}//接下来的数据从skb_shinfo的frags数组中进行拷贝for(i =0; i < skb_shinfo(skb)->nr_frags; i++) {intend;//遍历fragsend = start + skb_shinfo(skb)->frags[i].size;if((copy = end - offset) >0) { u8*vaddr;if(copy >len) copy=len;//映射skb的frag到内核地址空间vaddr = kmap_s...
skb_shinfo(skb)->frag_list = clone; } } pull_pages: eat = delta; k = 0; //释放frags中的page for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { if (skb_shinfo(skb)->frags[i].size <= eat) { put_page(skb_shinfo(skb)->frags[i].page); eat -= skb_shinfo(skb)->...
理解skb_shinfo至关重要,它位于skb尾部,其中frags用于Scatter Gather(SG)功能,这是一种在TX时通过硬件加速数据发送的方式。SG通过软件生成分散的数据块,硬件进行DMA读取和合并,例如IXGBE驱动通过dma_map_single和skb_frag_dma_map为每个数据块分配DMA地址。 在发送大包时,内核可能使用TSO(TCP Segmentation Offload)进行...
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) skb_shinfo(skb1)->frags[i] = skb_shinfo(skb)->frags[i]; //下面做的都是些成员字段拷贝赋值操作,并且设置skb的字段 skb_shinfo(skb1)->nr_frags = skb_shinfo(skb)->nr_frags; skb_shinfo(skb)->nr_frags = 0; skb1->data_len ...
skb_frag_t frags[MAX_SKB_FRAGS]; }; 我们只要把 end 从 char* 转换成skb_shared_info* ,就能访问到这个结构 Linux 提供一个宏来做这种转换: #define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) 那么,这个隐藏的结构用意何在?
skb_frag_t frags[MAX_SKB_FRAGS]; }; 我们只要把 end 从 char* 转换成skb_shared_info* ,就能访问到这个结构 Linux 提供一个宏来做这种转换: #define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) 那么,这个隐藏的结构用意何在?
理解skb_shinfo至关重要,它位于skb尾部,其中frags用于Scatter Gather(SG)功能,这是一种在TX时通过硬件加速数据发送的方式。SG通过软件生成分散的数据块,硬件进行DMA读取和合并,例如IXGBE驱动通过dma_map_single和skb_frag_dma_map为每个数据块分配DMA地址。在发送大包时,内核可能使用TSO(TCP ...
i) goto end; eat = 0; } k++; } } // nr_frags设置为k skb_shinfo(skb)->nr_frags = k; end: // tail增加data skb->tail += delta; // 非线性数据减去delta skb->data_len -= delta; if (!skb->data_len) skb_zcopy_clear(skb, false); return skb_tail_pointer(skb); } 基本...
1 #define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) 1. skb_shared_info结构: AI检测代码解析 1 /* include/linux/skbuff.h */ 2 struct skb_shared_info { 3 unsigned char nr_frags; /*表示有多少分片结构*/ ...
第一是skb_shared_info在sk_buff是无法直接找到的,在访问的时候需要借助skb_shinfo宏来实现,关于NET_SKBUFF_DATA_USES_OFFSET可参考[8]: #defineskb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) #ifdefNET_SKBUFF_DATA_USES_OFFSET ...