skbuff frags和frag_list之间的区别

Die*_*yen 5 linux fragmentation linux-device-driver linux-kernel

sk_buff有两个地方可以存储下一个碎片数据:

skb_shinfo(head)->frag_list 
skb_shinfo(head)->frags[]
Run Code Online (Sandbox Code Playgroud)

请有人解释这两种处理碎片的方法之间的差异.

谢谢,最诚挚的问候!

小智 7

两者都用于不同的情况.

断支[]

当您的设备支持分散 - 聚集I/O,并且您希望它进行数据组合等时,您可以frags[]从第二个片段开始填充结构直到第n个片段.第一个片段总是由datatail指针指定.其余的碎片填充在frags[]结构中.如果不使用分散集合,则此变量为空.

frag_list

这是IP片段列表.这将在期间填补ip_push_pending_frames.说你sk_buffs在这个安排

sk_buff0->next = sk_buff1
sk_buff1->next = sk_buff2
...
sk_buffn-1->next = sk_buffn
Run Code Online (Sandbox Code Playgroud)

之后ip_push_pending_frames被召唤

sk_buff0->frag_list = sk_buff1
sk_buff1->next = sk_buff2
...
sk_buffn-1->next = sk_buffn
Run Code Online (Sandbox Code Playgroud)

简单的说

  • frags[] 用于分散 - 聚集I/O缓冲区
  • frag_list 用于ip片段


fir*_*iro 5

skb_shinfo(head)->frags[]

如果网卡支持SG I/O,__ip_append_data会将用户空间数据复制到skb_shinfo(head)->frags。NIC驱动程序(例如ixgbe_add_rx_frag)也可以使用这些frags[]来承载接收到的网络流量;请注意,frags[] 中的每个内容都是完整数据包的一部分。一个完整的数据包由所有frags[] + (skb->data ~ skb->tail)组成。

skb_shinfo(head)->frag_list

IP分片不直接使用该成员。在__ip_make_skb()中,frag_list用于收集sk->sk_write_queue中的所有skb;一些 NIC 驱动程序还使用此 frag_list 将数据包传送到上层网络堆栈。frag_list中的每个content/skb也不是一个完整的数据包;tcp_v4_send_ack -> ip_send_unicast_reply -> ip_push_pending_frames -> ip_finish_skb -> __ip_make_skb;