struct sk_buff

作者: SnC_ | 来源:发表于2021-09-28 15:44 被阅读0次

在Linux网络代码中,struct sk_buff 代表已接收或正要传输的数据的报头。
Defined in <include/linux/skbuff.h>, <net/core/skbuff.c>

  • used by every network layer (except physical layer)
  • field of the structure change as it is passed from one layer to another, i.e., fields are layer dependent.

当sk_buff从协议栈的一层传到下一层时,会附加一个该层协议的报头:附加报头比把数据从一层copy到另一层更有效率。
后续可以看到,内核中使用skb_reserve函数来保证sk_buff在传到下层时有足够的预留空间以保存后续的报头。

sk_buffer结构中的字段很多,但大致可分为几种类型:

  • 布局(Layout)
  • 通用(General)
  • 功能专用(Feature-specific)
  • 管理函数(Management functions)

Layout of sk buffer :

The kernel maintains all sk_buff structures in a doubly linked list.

struct sk_buff_head {
  struct sk_buff *next;
  struct sk_buff *prev;

  __u32 qlen; //表中元素的数目
  spinlock_t lock; //防止对表的并发访问
}

sk_buff_head结构之所以存在,是因为sk_buff双向链表的一项要求:sk_buff结构必需能够迅速找出整个表的头。
sk_buff_head本身也是双向链表中的一个node。
每个sk_buff结构都包含一个指针,指向sk_buff_head结构,此指针名为list

struct sk_buff {
  struct sk_buff *next;
  struct sk_buff *prev;

  /* represents the Rx/Tx device interface corresponding
  to the packet. */
  struct net_device *dev;

  /* structure of the socket that owns this buffer. */
  struct sock *sk;

  /* This is the control buffer, or storage for private
  information, maintained by each layer for internal use. */
  char cb[48] __aligned(8);

  /* include both the data in the main buffer(i.e. the one
  pointed to by head) and the data in the fragments. */
  unsigned int len;

  /* unlike len, data_len accounts only for the size of the
  data in the fragments. */
  unsigned int data_len;

  /* size of mac header. */
  unsigned int mac_len;

  /* pointers to protocol headers. */
  __u16 transport_header;
  __u16 network_header;
  __u16 mac_header;

  sk_buff_data_t tail;
  sk_buff_data_t end;
  unsigned char  *head, *data;
  /* total size of this buffer (including sk_buff itself) */
  unsigned int truesize;
  /* the number of entities using this sk_buff buffer. */
  refcount_t users;
}
position pointers pointer modifications

Control block example:

struct tcp_skb_cb {
  ...
  __u32 seq; /* starting sequence number */
  __u32 end_seq; /* SEQ + FIN + SYN + datalen */
  __u32 when; /* used to compute rtt's */
  __u8 flags; /* TCP header flags */
  ...
}

Management functions :

skb_put(struct sk_buff *, unsigned int len) skb_push(struct sk_buff *, unsigned int len) skb_pull(struct sk_buff *, unsigned int len) skb_reserve(struct sk_buff *, unsigned int len)

Each of the above 4 memory management functions return the data pointer.

Memory allocation :

Initializing buffer :

reception transmission

Clone && Copy of buffer
当同一个buffer需要由不同消费者个别处理时,那些消费者可能需要修改sk_buff descriptor的内容,但内核不需要完全copy sk_buff结构和其关联的数据缓冲区。
相反,为了效率,内核可以clone原始值,即值copy sk_buff结构,然后使用引用计数,以避免过早释放共享的数据块。
缓冲区的clone由skb_clone函数实现。

skb_clone

Walkthrough Reception :

原文链接

相关文章

网友评论

    本文标题:struct sk_buff

    本文链接:https://www.haomeiwen.com/subject/exblnltx.html