struct sk_buff¶
sk_buff is the main networking structure representing
a packet.
Basic sk_buff geometry¶
struct sk_buffitself is a metadata structure and does not hold any packet data. All the data is held in associated buffers.
sk_buff.headpoints to the main “head” buffer. The head buffer is divided into two parts:
data buffer, containing headers and sometimes payload; this is the part of the skb operated on by the common helpers such as
skb_put()orskb_pull();shared info (
struct skb_shared_info) which holds an array of pointers to read-only data in the (page, offset, length) format.Optionally
skb_shared_info.frag_listmay point to another skb.Basic diagram may look like this:
--------------- | sk_buff | --------------- ,--------------------------- + head / ,----------------- + data / / ,----------- + tail | | | , + end | | | | v v v v ----------------------------------------------- | headroom | data | tailroom | skb_shared_info | ----------------------------------------------- + [page frag] + [page frag] + [page frag] + [page frag] --------- + frag_list --> | sk_buff | ---------
dataref and headerless skbs¶
Transport layers send out clones of payload skbs they hold for retransmissions. To allow lower layers of the stack to prepend their headers we split
skb_shared_info.datarefinto two halves. The lower 16 bits count the overall number of references. The higher 16 bits indicate how many of the references are payload-only.skb_header_cloned()checks if skb is allowed to add / write the headers.The creator of the skb (e.g. TCP) marks its skb as
sk_buff.nohdr(via__skb_header_release()). Any clone created from marked skb will getsk_buff.hdr_lenpopulated with the available headroom. If there’s the only clone in existence it’s able to modify the headroom at will. The sequence of calls inside the transport layer is:<alloc skb> skb_reserve() __skb_header_release() skb_clone() // send the clone down the stackThis is not a very generic construct and it depends on the transport layers doing the right thing. In practice there’s usually only one payload-only skb. Having multiple payload-only skbs with different lengths of hdr_len is not possible. The payload-only skbs should never leave their owner.