//分配新的skb->data,将旧的skb->data、skb_shinfo(skb)->frags、skb_shinfo(skb)->frag_list中的内容拷贝到新skb->data的连续内存空间中,释放frags或frag_list //其中frags用于支持分散聚集IO,frags_list用于支持数据分片 1.1 int __skb_linearize(struct sk_buff *skb, int gfp_mask) { unsigned int ...
*/if(skb_has_frag_list(skb)) {structsk_buff*frag, *frag2;intfirst_len = skb_pagelen(skb);if(first_len - hlen > mtu || ((first_len - hlen) &7) || ip_is_fragment(iph) || skb_cloned(skb))gotoslow_path; skb_walk_frags(skb, frag) {/* Correct geometry. */if(frag->len ...
因此需要释放frags,frag_list中被拷贝过的数据//计算从frags数组中拷贝的数据量eat =delta;for(i =0; i < skb_shinfo(skb)->nr_frags; i++) {//寻找到满足eat这么多数据量的最后一个pageif(skb_shinfo(skb)->frags[i].size >=eat)//在frags数组中的数据量可以满足delta时,则只...
frag = skb_shinfo(skb)->frag_list; skb_frag_list_init(skb);/* BUILD HEADER */*prevhdr = NEXTHDR_FRAGMENT; tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);if(!tmp_hdr) { IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS);return-ENOMEM; }...
我对bpf_skb_pull_data把非线性区的数据如何pull到线性区非常感兴趣,因为非线性区有两种类型,但是文档中没有说明: 1. 偏移如何对应到两种非线性区frags和frag_list 2. frags和frag_list在pull时的顺序问题 3. 如何扩展线性区的数据 bpf_skb_pull_data的作用在注释中写到非常清楚: ...
frags和frag_list在pull时的顺序问题 如何扩展线性区的数据 bpf_skb_pull_data的作用在注释中写到非常清楚: Idea is the following: should the needed direct read/write test fail during runtime, we can pull in more data and redo again, since implicitly, we invalidate previous checks here. ...
Ian reported several skb corruptions triggered by rx-gro-list, collecting different oops alike: [ 62.624003] BUG: kernel NULL pointer dereference, address: 00000000000000c0 [ 62.631083] #PF: supervisor read access in kernel mode [ 62.636312] #PF: error_code(0x0000) - not-present page [ 62.6415...
· void skb_drop_fraglist(struct sk_buff *skb) · void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) · pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, gfp_t gfp_mask) · int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, in...
第二就是什么时候会使用no-linear,frag_list在处理IP分片时被使用,可以查看内核中的ip_fragment->ip_do_fragment函数,[1][2][3]中对这个部分的描述并不够详细,或者说对frags对描述还不够详细。
if (!skb_shinfo(skb)->frag_list) goto pull_pages; // 后面的操作都是在要腾出delta大小的线性缓冲区,腾出空间后就可以拉长skb包页面 /* Estimate size of pulled pages. */ eat = delta; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ...