操作tailroom中用户数据块区域:skb_put用于修改指向数据区末尾的指针tail: 可以看到tail指针的移动是扩大数据区域,即数据区向下扩大len字节,并更新数据区长度len。 增加headroom区域的协议头:skb_push函数用于移动data指针,增加头部协议,与skb_reserve()类似,也并没有真正向数据缓存区中添加数据,而只是移动数据缓存区的...
**sk_buff->len ** 表示当前协议数据包的长度 。它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。 sk_buff->data_len和len不同,data_len只计算分片中数据的长度 sk_buff->mac_len这是mac头的长度 sk_buff->users这是一个引用计数,用于计算有多少实体引用了这个sk_buff缓冲区。它的主要用...
static inline void skb_reserve(struct sk_buff *skb, int len) { skb->data += len; skb->tail += len; } 如下图所示:
**sk_buff->len ** 表示当前协议数据包的长度 。它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。 sk_buff->data_len和len不同,data_len只计算分片中数据的长度 sk_buff->mac_len这是mac头的长度 sk_buff->users这是一个引用计数,用于计算有多少实体引用了这个sk_buff缓冲区。它的主要用...
len:当前有效数据的长度。 protocol:数据包所使用的协议类型(如 IPv4、IPv6、ARP 等)。 dev:指向与此数据包相关联的网络设备(network device)的指针。 2. 功能 存储数据包:sk_buff提供了一个灵活且高效的方法来存储接收到或要发送的数据包。 链式管理:由于支持链表结构,多个sk_buff可以链接在一起,以便处理分段...
skb- >data_len; } 在没有开启分片的报文中,数据包长度在struct sk_buff中为len字段的大小,即data到tail的长度,nf_frags为0,frag_list为NULL。 普通聚合分散I/O的报文: 采用聚合分散I/O的报文, frag_list为 NULL,nf_frags不等于0 ,说明这不是一个普通的分片,而是聚合分散I/O的报文。
有些sk_buff成员变量的作用是方便查找或者是连接数据结构本身。内核可以把sk_buff组织成一个双向链表。当然,这个链表的结构要比常见的双向链表的结构复杂一点。就像任何一个双向链表一样,sk_buff 中有两个指针next和prev,其中,next指向下一个节点,而prev指向上一个节点。在第一个节点前面会插入另一个结构sk_...
data_len只计算片段中的数据大小 unsigned int mac_len MAC报头的大小 atomic_t users 引用计数,或者使用这个sk_buff缓冲区的实例的数目。 这个参数的主要用途是避免在某人依然使用此sk_buff结构时,把这个结构给释放掉。因此,此缓冲区的每个用户在必要时都要递增和递减此字段。
unsigned int len, //缓冲区中数据区块的大小。包括由head所指以及一些片段数据。当从一个分层移动到另一个分层时候回发生变化。协议报头也算在里面。 data_len;//只计算片段中的数据大小 __u16 mac_len,//mac报头的大小 hdr_len;//克隆的skb可写的头长度 /* Following fields are _not_ copied in __cop...
mac_len,//mac头的长度 csum;//校验和 __u32 priority; __u8 local_df:1, cloned:1,//表示该结构是另一个sk_buff克隆的 ip_summed:2, nohdr:1, nfctinfo:3; __u8 pkt_type:3, fclone:2, ipvs_property:1; __be16 protocol; __u32 flag; /*packet flags*/ ...