分配成功之后,因为还没有存放具体的网络报文,所以sk_buff的 data,tail指针都指向存储空间的起始地址,len的大小为0,而且 is_clone和cloned两个标记的值都是0。struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)从控制结构skb中 clone出一个新的控制结构,它们都指向同一个网络报文。clone成功之后...
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len); static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len) { skb->len -= len; BUG_ON(skb->len < skb->data_len); return skb->data += len; } 如下如所示: (4)skb_reserve函数:当skb还是空的时...
unsigned char *skb_put(struct sk_buff *skb, unsigned int len) 将tail指针下移,并增加skb的 len值。data和 tail之间的空间就是可以存放网络报文的空间。这个操作增加了可以存储网络报文的空间,但是增加不能使tail的值大于end的值,skb的 len值大于truesize的值。 unsigned char *skb_push(struct sk_buff *s...
skb->data -= len ; skb->len += len ; if ( unlikely(skb->data < skb->head ) ) skb_under_panic(skb , len , __builtin_return_address(0)) ; return skb->data ; } /** * skb_pull - remove data from the start of a buffer * @skb : buffer to use * @len : amount of da...
skb->len //大哥、小弟和兄弟的总和,即data的总长度,线性和非线性的总和。 skb->data_len //小弟和兄弟的总和,即大哥缺少的份额,非线性数据长度。 skb_headlen() //即大哥长度,线性长度。和skb_headroom()不一样,这个是只头部空间剩余长度。 skb_pagelen() //大哥和小弟的总和,即线性数据长度和页面碎片的...
allocate_skb skb = alloc_skb(len, GFP_KERNEL); 这是使用alloc_skb()分配新的skb后各指针的初始位置,head、data和tail指针都指向数据缓冲区的开头,end指针指向它的结尾。需要特别注意的是:tail指针指向的是用户数据区的末尾。 这个skb的长度为零,因为它根本不包含任何数据。接下来,让我们使用skb_reserve()为...
sizeof(struct udphdr), skb->csum); uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, user_data_len, IPPROTO_UDP, skb->csum); if (uh->check == 0) uh->check = -1; 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ...
dev_kfree_skb()完成dev_alloc_skb()的相反功能,释放缓冲区。接下来调用的skb_reserve()在数据包缓冲的起始和载荷的开始之间增加一个2B的填充位。这使IP头能在16B边界处开始(因为对齐的原因,这通常意味着性能更佳),因为前面的以太网头部是14B。剩下的代码用收到的数据包填充载荷缓冲区,并移动skb->data,skb-...
skb->len =2有效负载 (线性区域 + 非线性区域(datalen),这里暂时不考虑协议头部) Case2:如果缓冲区积压(存在未被ACK的已经发送的网络包-即SEND-Q中存在sk_buff结构),Linux会尝试将当前包合并到SEND-Q的最后一个sk_buff结构中(粘包);考虑我们上述的768bytes的结构体为SEND-Q的最后一个sk_buff,当用户进程继...
操作tailroom中用户数据块区域:skb_put用于修改指向数据区末尾的指针tail: 可以看到tail指针的移动是扩大数据区域,即数据区向下扩大len字节,并更新数据区长度len。 增加headroom区域的协议头:skb_push函数用于移动data指针,增加头部协议,与skb_reserve()类似,也并没有真正向数据缓存区中添加数据,而只是移动数据缓存区的...