skb_shinfo(skb1)->frags[0].page_offset += len - pos; skb_shinfo(skb1)->frags[0].size -= len - pos; skb_shinfo(skb)->frags[i].size = len - pos; skb_shinfo(skb)->nr_frags++; } k++; } else skb_shinfo(skb)->nr_frags++; pos += size; } skb_shinfo(skb1)->nr_frags ...
{inti, k =0;//开始设置sk_buff结构数据区内容constintnfrags = skb_shinfo(skb)->nr_frags; skb_shinfo(skb)->nr_frags =0; skb1->len = skb1->data_len = skb->len -len; skb->len =len; skb->data_len = len -pos;//这是循环拆分分片结构数据区数据for(i =0; i < nfrags; i++)...
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的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...
// 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); returnskb_tail_pointer(skb);
*/ pull_pages: eat = delta; k = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int size = skb_frag_size(&skb_shinfo(skb)->frags[i]); if (size <= eat) { // 释放对frag(skb->frags[i])的引用。 skb_frag_unref(skb, i); eat -= size; } else { skb_...
skb_frag_t frags[MAX_SKB_FRAGS]; }; 我们只要把 end 从 char* 转换成skb_shared_info* ,就能访问到这个结构 Linux 提供一个宏来做这种转换: #define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) 那么,这个隐藏的结构用意何在?
1 #define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) 1. skb_shared_info结构: 1 /* include/linux/skbuff.h */ 2 struct skb_shared_info { 3 unsigned char nr_frags; /*表示有多少分片结构*/ 4 __u8 tx_flags; ...
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; BUG_TRAP(start <= offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { u8 *vaddr; if (copy > len)
skb_shinfo(skb)->nr_frags = k; // skb数据尾指针拉长delta,同时非页面内的数据长度减少delta skb->tail += delta; skb->data_len -= delta; return skb->tail; } 3. 应用位置 skb_make_writable()函数用在各个IP上层协议的的manip_pkt()函数、用于修改数据包内容的ip_nat_mangle_tcp_packet()、...