Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between skbuff frags and frag_list

The sk_buff has two places where it can store the next fragmentation data:

skb_shinfo(head)->frag_list 
skb_shinfo(head)->frags[]

What are the differences between these two ways to handle fragmentation?

like image 942
Dien Nguyen Avatar asked Apr 06 '12 06:04

Dien Nguyen


People also ask

What is Skbuff?

The sk_buff elements are organized as a doubly linked list, in such a way that it is very efficient to move an sk_buff element from the beginning/end of a list to the beginning/end of another list. A queue is defined by struct sk_buff_head, which includes a head and a tail pointer to sk_buff elements.

How SKBs work?

The total number of bytes in the packet is 'len'. SKBs are composed of a linear data buffer, and optionally a set of 1 or more page buffers. If there are page buffers, the total number of bytes in the page buffer area is 'data_len'. Therefore the number of bytes in the linear buffer is 'skb->len - skb->data_len'.


2 Answers

Both are used for different cases.

frags[]

When your device supports scatter-gather I/O, and you want it to do the combining of data, etc., you can populate the frags[] structure starting with the second fragment till the nth fragment. The first fragment is always specified by the data and tail pointers. The rest of the fragments are filled in the frags[] structure. If you don't use scatter gather, this variable is empty.

frag_list

This is the list of IP fragments. This will be filled during ip_push_pending_frames.

Say your sk_buffs are in this arrangement,

sk_buff0->next = sk_buff1
sk_buff1->next = sk_buff2
...
sk_buffn-1->next = sk_buffn

After ip_push_pending_frames is called

sk_buff0->frag_list = sk_buff1
sk_buff1->next = sk_buff2
...
sk_buffn-1->next = sk_buffn

Simply put

  • frags[] are for scatter-gather I/O buffers
  • frag_list is for IP fragments
like image 142
bjxt Avatar answered Oct 23 '22 02:10

bjxt


skb_shinfo(head)->frags[]

If the NIC supports SG I/O, __ip_append_data will copy user space data to skb_shinfo(head)->frags. The NIC driver (e.g., ixgbe_add_rx_frag) can also use these frags[] to carry the received network traffic; please note that every content in frags[] is a part of a complete packet. A complete packet consists of all frags[] + (skb->data ~ skb->tail).

skb_shinfo(head)->frag_list

This member is not used by IP fragmentation directly. In __ip_make_skb(), the frag_list is used to collect all skbs from sk->sk_write_queue; some NIC drivers also use this frag_list for carrying a packet to the upper network stack. Every content/skb in frag_list is also not a complete packet; tcp_v4_send_ack -> ip_send_unicast_reply -> ip_push_pending_frames -> ip_finish_skb -> __ip_make_skb;

like image 4
firo Avatar answered Oct 23 '22 01:10

firo