分享

Linux内核--网络内核实现分析(一)--与sk_buff有关的几个重要的结构

 zhouADNjj 2014-03-10

本文分析基于Linux Kernel 3.2.1

几个月之前做了关于Linux内核版本1.2.13网络栈的结构框架分析并实现了基于Netfilter的包过滤防火墙,这里以内核3.2.1内核为例来进一步分析,更全面的分析网络栈的结构。

更多请查看 Linux内核--网络内核实现分析

1、先说一下sk_buff结构体

这个结构体是套接字的缓冲区,详细记录了一个数据包的组成,时间、网络设备、各层的首部及首部长度和数据的首尾指针。

下面是他的定义,挺长

  1. struct sk_buff {  
  2.     /* These two members must be first. */  
  3.     struct sk_buff      *next;  
  4.     struct sk_buff      *prev;  
  5.   
  6.     ktime_t         tstamp;  
  7.   
  8.     struct sock     *sk;  
  9.     struct net_device   *dev;  
  10.   
  11.     /* 
  12.      * This is the control buffer. It is free to use for every 
  13.      * layer. Please put your private variables there. If you 
  14.      * want to keep them across layers you have to do a skb_clone() 
  15.      * first. This is owned by whoever has the skb queued ATM. 
  16.      */  
  17.     char            cb[48] __aligned(8);  
  18.   
  19.     unsigned long       _skb_refdst;  
  20. #ifdef CONFIG_XFRM   
  21.     struct  sec_path    *sp;  
  22. #endif   
  23.     unsigned int        len,  
  24.                 data_len;  
  25.     __u16           mac_len,  
  26.                 hdr_len;  
  27.     union {  
  28.         __wsum      csum;  
  29.         struct {  
  30.             __u16   csum_start;  
  31.             __u16   csum_offset;  
  32.         };  
  33.     };  
  34.     __u32           priority;  
  35.     kmemcheck_bitfield_begin(flags1);  
  36.     __u8            local_df:1,  
  37.                 cloned:1,  
  38.                 ip_summed:2,  
  39.                 nohdr:1,  
  40.                 nfctinfo:3;  
  41.     __u8            pkt_type:3,  
  42.                 fclone:2,  
  43.                 ipvs_property:1,  
  44.                 peeked:1,  
  45.                 nf_trace:1;  
  46.     kmemcheck_bitfield_end(flags1);  
  47.     __be16          protocol;  
  48.   
  49.     void            (*destructor)(struct sk_buff *skb);  
  50. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)   
  51.     struct nf_conntrack *nfct;  
  52. #endif   
  53. #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED   
  54.     struct sk_buff      *nfct_reasm;  
  55. #endif   
  56. #ifdef CONFIG_BRIDGE_NETFILTER   
  57.     struct nf_bridge_info   *nf_bridge;  
  58. #endif   
  59.   
  60.     int         skb_iif;  
  61. #ifdef CONFIG_NET_SCHED   
  62.     __u16           tc_index;   /* traffic control index */  
  63. #ifdef CONFIG_NET_CLS_ACT   
  64.     __u16           tc_verd;    /* traffic control verdict */  
  65. #endif   
  66. #endif   
  67.   
  68.     __u32           rxhash;  
  69.   
  70.     __u16           queue_mapping;  
  71.     kmemcheck_bitfield_begin(flags2);  
  72. #ifdef CONFIG_IPV6_NDISC_NODETYPE   
  73.     __u8            ndisc_nodetype:2;  
  74. #endif   
  75.     __u8            ooo_okay:1;  
  76.     __u8            l4_rxhash:1;  
  77.     kmemcheck_bitfield_end(flags2);  
  78.   
  79.     /* 0/13 bit hole */  
  80.   
  81. #ifdef CONFIG_NET_DMA   
  82.     dma_cookie_t        dma_cookie;  
  83. #endif   
  84. #ifdef CONFIG_NETWORK_SECMARK   
  85.     __u32           secmark;  
  86. #endif   
  87.     union {  
  88.         __u32       mark;  
  89.         __u32       dropcount;  
  90.     };  
  91.   
  92.     __u16           vlan_tci;  
  93.   
  94.     sk_buff_data_t      transport_header;  
  95.     sk_buff_data_t      network_header;  
  96.     sk_buff_data_t      mac_header;  
  97.     /* These elements must be at the end, see alloc_skb() for details.  */  
  98.     sk_buff_data_t      tail;  
  99.     sk_buff_data_t      end;  
  100.     unsigned char       *head,  
  101.                 *data;  
  102.     unsigned int        truesize;  
  103.     atomic_t        users;  
  104. };  

可以看到新版本内核中发生了很多变化,其中数据包的首部在早期版本是以union的形式定义的,例如mac_header的定义方式如下:

  1. union{  
  2.     struct ethhdr *ethernet;  
  3.     unsigned char *raw;  
  4. }mac;  

这里是以指针的形式给出的

  1. #ifdef NET_SKBUFF_DATA_USES_OFFSET   
  2. typedef unsigned int sk_buff_data_t;  
  3. #else   
  4. typedef unsigned char *sk_buff_data_t;  
  5. #endif  
linux

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多