ninfo->tso_size = skb_shinfo(skb)->tso_size; ninfo->tso_segs = skb_shinfo(skb)->tso_segs; //fraglist为NULL ninfo->nr_frags = 0; ninfo->frag_list = NULL; offset = data - skb->head; //释放之前skb的data skb_release_data(skb); //将skb指向新的data skb->head = data; skb->...
skb的内存空间划分为线性区(head-end)和非线性区(frags和frag_list),非线性区是通过skb_shinfo管理的。 理解skb_shinfo至关重要,它位于skb尾部,其中frags用于Scatter Gather(SG)功能,这是一种在TX时通过硬件加速数据发送的方式。SG通过软件生成分散的数据块,硬件进行DMA读取和合并,例如IXGBE驱动通过dma_map_single...
skb_shared_info结构: 1/*include/linux/skbuff.h*/2structskb_shared_info {3unsignedcharnr_frags;/*表示有多少分片结构*/4__u8 tx_flags;5unsignedshortgso_size;6/*Warning: this field is not always filled in (UFO)!*/7unsignedshortgso_segs;8unsignedshortgso_type;9structsk_buff *frag_list;/...
atomic_set(&(skb_shinfo(skb)->dataref), 1); skb_shinfo(skb)->nr_frags = 0; skb_shinfo(skb)->tso_size = 0; skb_shinfo(skb)->tso_segs = 0; skb_shinfo(skb)->frag_list = NULL; skb_shinfo(skb)->ufo_size = 0; skb_shinfo(skb)->ip6_frag_id = 0; 最后,返回 SKB 的指针....
下面这幅图是《深入理解Linux网络技术内幕》里面的图,一个skb用于存储一个报文,如果一个报文特别大的话,线性存储区放不下就需要多个skb来存储,这就是下面frag_list的作用,保存连续的skb,但是如果内核支持分散聚集技术的话,并且报文长度刚好又不大于mt...
if(!skb_has_frag_list(skb)) gotopull_pages; // eat被赋值为传入的delta,而不是上面算出来的需要多少字节 eat= delta; // nr_frags是frags有效的字段数 for(i =0; i < skb_shinfo(skb)->nr_frags; i++) { // 拿到page中数据的长度 ...
struct sk_buff *frag_list; skb_frag_t frags[MAX_SKB_FRAGS]; }; 我们只要把 end 从 char* 转换成skb_shared_info* ,就能访问到这个结构 Linux 提供一个宏来做这种转换: #define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) ...
if(!skb_has_frag_list(skb)) gotopull_pages; // eat被赋值为传入的delta,而不是上面算出来的需要多少字节 eat= delta; // nr_frags是frags有效的字段数 for(i =0; i < skb_shinfo(skb)->nr_frags; i++) { // 拿到page中数据的长度 ...
skb的核心数据结构中,skb_shinfo(skb共享信息)隐藏在skb的end之后,包含frag_list和frags数组,用于处理TCP分段、UDP分包等操作。skb的内存空间划分为线性区(head-end)和非线性区(frags和frag_list),非线性区是通过skb_shinfo管理的。理解skb_shinfo至关重要,它位于skb尾部,其中frags用于Scatter ...
*/ if (clone) { clone->next = list; skb_shinfo(skb)->frag_list = clone; } } /* Success! Now we may commit changes to skb data. */ pull_pages: eat = delta; k = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int size = skb_frag_size(&skb_shinfo(skb)-...