skbuff

发布时间:2016-12-6 7:49:47编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"skbuff ",主要涉及到skbuff 方面的内容,对于skbuff 感兴趣的同学可以参考一下。

  1. struct sk_buff {  
  2.          /* These two members must be first. */  
  3.          struct sk_buff          *next;  
  4.          struct sk_buff          *prev;  
  5.    
  6.          struct sock             *sk;  
  7.          struct skb_timeval      tstamp;  
  8.          struct net_device       *dev;  
  9.          struct net_device       *input_dev;  
  10.    
  11.          union {  
  12.                  struct tcphdr   *th;  
  13.                  struct udphdr   *uh;  
  14.                  struct icmphdr  *icmph;  
  15.                  struct igmphdr  *igmph;  
  16.                  struct iphdr    *ipiph;  
  17.                  struct ipv6hdr  *ipv6h;  
  18.                  unsigned char   *raw;  
  19.          } h;  
  20.    
  21.          union {  
  22.                  struct iphdr    *iph;  
  23.                  struct ipv6hdr  *ipv6h;  
  24.                  struct arphdr   *arph;  
  25.                  unsigned char   *raw;  
  26.          } nh;  
  27.    
  28.          union {  
  29.                  unsigned char   *raw;  
  30.          } mac;  
  31.    
  32.          struct  dst_entry       *dst;  
  33.          struct  sec_path        *sp;  
  34.    
  35.          /* 
  36.           * This is the control buffer. It is free to use for every 
  37.           * layer. Please put your private variables there. If you 
  38.           * want to keep them across layers you have to do a skb_clone() 
  39.           * first. This is owned by whoever has the skb queued ATM. 
  40.           */  
  41.          char                    cb[48];  
  42.    
  43.          unsigned int            len,  
  44.                                  data_len,  
  45.                                  mac_len,  
  46.                                  csum;  
  47.          __u32                   priority;  
  48.          __u8                    local_df:1,  
  49.                                  cloned:1,  
  50.                                  ip_summed:2,  
  51.                                  nohdr:1,  
  52.                                  nfctinfo:3;  
  53.          __u8                    pkt_type:3,  
  54.                                  fclone:2,  
  55.                                  ipvs_property:1;  
  56.          __be16                  protocol;  
  57.    
  58.          void                    (*destructor)(struct sk_buff *skb);  
  59. #ifdef CONFIG_NETFILTER  
  60.          __u32                   nfmark;  
  61.          struct nf_conntrack     *nfct;  
  62. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)  
  63.          struct sk_buff          *nfct_reasm;  
  64. #endif  
  65. #ifdef CONFIG_BRIDGE_NETFILTER  
  66.          struct nf_bridge_info   *nf_bridge;  
  67. #endif  
  68. #endif /* CONFIG_NETFILTER */  
  69. #ifdef CONFIG_NET_SCHED  
  70.          __u16                   tc_index;       /* traffic control index */  
  71. #ifdef CONFIG_NET_CLS_ACT  
  72.          __u16                   tc_verd;        /* traffic control verdict */  
  73. #endif  
  74. #endif  
  75.    
  76.    
  77.          /* These elements must be at the end, see alloc_skb() for details.  */  
  78.          unsigned int            truesize;  
  79.          atomic_t                users;  
  80.          unsigned char           *head,  
  81.                                  *data,  
  82.                                  *tail,  
  83.                                  *end;  
  84. };  

> : next和prev,这两个域是用来连接相关的skb的(例如如果有分片,将这些分片连接在一起可以)

> : sk,指向报文所属的套接字指针

> : tstamp,记录接收或者传输报文的时间戳

> : dev和input_dev,记录接收或者发送的设备

>: union u,对于一个层次,例如tcp层,可能有很多不同的协议,他们的协议头不一样,那么这个联合体就是记录这些协议头的。

     此处u就是代表传输层

> : union nh,代表网络层头

> : union mac,代表链路层头

> : dst,指向des_entry结构,记录了到达目的地的路由信息,以及其他的一些网络特征信息。

> : sp:安全路径,用于xfrm

> : cb[],保存与协议相关的控制信息,每个协议可能独立使用这些信息。

> : 重要的字段 len 和 data_len:

      len代: 表整个数据区域的长度!这里要提前解释几个定义,skb的组成是有sk_buff控制 + 线性数据 + 非线性数据 

      (skb_shared_info) 组成!

     后面会具体解释是什么意思!在sk_buff这个里面没有实际的数据,这里仅仅是控制信息,数据是通过后面的data指针指向其他内

     存块的!那个内存块中是线性数据和

     非线性数据!那么len就是length(线性数据) + length(非线性数据)!!!

     data_len: 指的是length(非线性数据)!!!那么可以知道:length(线性数据) =  skb->len - skb->data_len

> : mac_len,指的是mac头长度

> : csum,某时刻协议的校验和

> : priority,报文排队优先级,取决于ip中的tos域

> : local_df,允许在本地分配

> : cloned,保存当前的skb_buff是克隆的还是原始数据

> : ip_summed,是否计算ip校验和

> : nohdr,仅仅引用数据区域

> : pkt_type,报文类型,例如广播,多播,回环,本机,传出...

> : fclone,skb_buff克隆状态

> : ipvs_property,skb_buff是否属于ipvs

> : protocal,协议信息

> : nfmark,用于钩子之间通信

> : nfct_reasm,netfilter的跟踪连接重新组装指针

> : nf_bridge,保存桥接信息

> : tc_index: Traffic control index,tc_verd: traffic control verdict

> : truesize,该缓冲区分配的所有总的内存,包括:skb_buff + 所有数据大小

> : users,保存引用skb_buff的数量

> : 重要数据字段:head,data,tail,end!!!

    head:指向分配给的线性数据内存首地址( 建立起一个观念:并不是分配这么多内存,就都能被使用作为数据存储,可能没这么多

    数据也有可能!但是也不要认为分配这么多 就足够了,也不一定(非线性数据就是例子) )

    data:指向保存数据内容的首地址!我们由head可以知道,head和data不一定就是指在同一个位置!!!

    tail:指向数据的结尾!

    end:指向分配的内存块的结尾! ( 由上面我们知道数据结尾 != 分配的内存块的结尾 )

    下面还会具体分析!!!!!!!!!!!

二、

我觉得需要先了解一些对于一个数据skb到底有什么,或者说由哪些元素组成!这就需要知道所谓的 “线性数据” 和 “非线性数据”。

基本的组成如下:

> : sk_buff : 这是一个sk_buff的控制结构

> : 线性数据区域

> : 非线性数据区域( 由skb_shared_info结构体管理 )

那么下面通过一个图来看看这个skb结构到底是怎么样的!看(图一)

                                                                                    (图一)

借助图一,我们先来分析两个重要字段:len和data_len

之前说过len代表的是整个数据的长度,data_len代表的是非线性数据长度。我们由图一可以看到线性数据长度为l1,再看看非线性数据,其实就是看frags[]和frag_list

ok...那么我们可以知道非线性数据长度为( l2 + ... + ln ) + ( l(n+1) + ... + lm )

即:len = l1 + ( l2 + ... + ln ) + ( l(n+1) + ... + lm )

        data_len = ( l2 + ... + ln ) + ( l(n+1) + ... + lm )

ok...

现在从分配内存开始解释这个图的由来:

我们使用skb_alloc给skb分配空间,那么刚刚分配结束返回时候,是什么样的情况呢?看下图(图二):

                                                

                                                                                     (图二)

刚刚开始初始化的时候,预分配一个一块线性数据区域,这个区域一般放入的是各个协议层次的不同的头,还有一些实际数据,下面的非线性区域是为了弥补当数据真的很多的时候,作为数据区域的扩展!关于skb_shared_info具体意思下面会继续说!注意在初始化的时候,head,data和tail都指向内存的开始位置,head在这个位置始终不变,它表示的是分配的内存的开始位置。end的位置也是不变的,表示的是分配的内存的结束位置。data和tail会随着数据的加入和减少变化,总之表示的是放入数据的内存区域(由图一)可知。

现在需要解释一下skb_shared_info这个结构体,这个结构体真的是很很有特色!主要是其中的两个字段frags和frag_list,下面继续解释:


上一篇:iOS 多线程
下一篇:Ubuntu 16.04 64位 搭建 node.js NodeJS 环境

相关文章

关键词: skbuff

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款