skb_push() will decrement the 'skb->data' pointer by the specified number ofbytes. It will also increment 'skb->len' by that number of bytes as well.The caller must make sure there is enough head room for the push beingperformed. This condition is checked for by skb_push() and an ...
while((list = skb_shinfo(skb)->frag_list)!= insp) { skb_shinfo(skb)->frag_list =list->next; kfree_skb(list); } /* And insert newcloneat head. */ if(clone) { clone->next =list; skb_shinfo(skb)->frag_list =clone; } } /* Success! Now we may commit changes to skb data...
skb_release_all(skb);/*释放skb附带的所有数据*/kfree_skbmem(skb);/*释放skb*/} staticvoidskb_free_head(structsk_buff *skb) { unsignedchar*head = skb->head;if(skb->head_frag)//表示线性区 数据在page 区 len=size&&&date_len=sieze 通过alloc_page_frag拿到skb->head=data=pageskb_free_fr...
skb的核心数据结构中, skb_shinfo(skb共享信息)隐藏在skb的end之后,包含frag_list和frags数组,用于处理TCP分段、UDP分包等操作。skb的内存空间划分为线性区(head-end)和非线性区(frags和frag_list),非线性区是通过skb_shinfo管理的。 理解skb_shinfo至关重要,它位于skb尾部,其中frags用于Scatter Gather(SG)功能,这...
headroom=skb_headroom(head_skb); pos=skb_headlen(head_skb); do{ structsk_buff*nskb; skb_frag_t*nskb_frag; inthsize; intsize; len=skb->len-offset; len=head_skb->len-offset; if(len>mss) len=mss; hsize=skb_headlen(skb)-offset; ...
23 /* must be last field, see pskb_expand_head() */ 24 skb_frag_t frags[MAX_SKB_FRAGS]; /*保存分页数据,skb->data_len = 所有数组数据长度之和*/ 25 }; 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
skb->head = data; skb->data = data; skb->end = skb->tail + size; ... } 第二就是什么时候会使用no-linear,frag_list在处理IP分片时被使用,可以查看内核中的ip_fragment->ip_do_fragment函数,[1][2][3]中对这个部分的描述并不够详细,或者说对frags对描述还不够详细。
* @head_frag: skb was allocated from page fragments, 668669 * not allocated by kmalloc() or vmalloc(). 669670 * @pfmemalloc: skbuff was allocated from PFMEMALLOC reserves 671+ * @pp_recycle: mark the packet for recycling instead of freeing (implies ...
skb */...skb_success:skb_reserve(skb,NET_SKB_PAD);/* 在数据头部保留部分空间 */skb->dev=dev;/* 设定 skb 的 所属的 网卡设备对象 */skb_fail:returnskb;}structsk_buff*__build_skb(void*data,unsignedintfrag_size){structskb_shared_info*shinfo;structsk_buff*skb;unsignedintsize=frag_size?
ninfo->frag_list = NULL; offset = data - skb->head; //释放之前skb的data skb_release_data(skb); //将skb指向新的data skb->head = data; skb->end = data + size; //重新初始化新skb的各个报头指针 skb->h.raw += offset; skb->nh.raw += offset; ...