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

  1、先说一下sk_buff结构体

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

  下面是他的定义,挺长


struct sk_buff {
 /* These two members must be first. */
 struct sk_buff  *next;
 struct sk_buff  *prev;

 ktime_t   tstamp;

 struct sock  *sk;
 struct net_device *dev;

 /*
  * This is the control buffer. It is free to use for every
  * layer. Please put your private variables there. If you
  * want to keep them across layers you have to do a skb_clone()
  * first. This is owned by whoever has the skb queued ATM.
  */
 char   cb[48] __aligned(8);

 unsigned long  _skb_refdst;
#ifdef CONFIG_XFRM
 struct sec_path *sp;
#endif
 unsigned int  len,
    data_len;
 __u16   mac_len,
    hdr_len;
 union {
  __wsum  csum;
  struct {
   __u16 csum_start;
   __u16 csum_offset;
  };
 };
 __u32   priority;
 kmemcheck_bitfield_begin(flags1);
 __u8   local_df:1,
    cloned:1,
    ip_summed:2,
    nohdr:1,
    nfctinfo:3;
 __u8   pkt_type:3,
    fclone:2,
    ipvs_property:1,
    peeked:1,
    nf_trace:1;
 kmemcheck_bitfield_end(flags1);
 __be16   protocol;

 void   (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 struct nf_conntrack *nfct;
#endif
#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
 struct sk_buff  *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
 struct nf_bridge_info *nf_bridge;
#endif

 int   skb_iif;
#ifdef CONFIG_NET_SCHED
 __u16   tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
 __u16   tc_verd; /* traffic control verdict */
#endif
#endif

 __u32   rxhash;

 __u16   queue_mapping;
 kmemcheck_bitfield_begin(flags2);
#ifdef CONFIG_IPV6_NDISC_NODETYPE
 __u8   ndisc_nodetype:2;
#endif
 __u8   ooo_okay:1;
 __u8   l4_rxhash:1;
 kmemcheck_bitfield_end(flags2);

 /* 0/13 bit hole */

#ifdef CONFIG_NET_DMA
 dma_cookie_t  dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
 __u32   secmark;
#endif
 union {
  __u32  mark;
  __u32  dropcount;
 };

 __u16   vlan_tci;

 sk_buff_data_t  transport_header;
 sk_buff_data_t  network_header;
 sk_buff_data_t  mac_header;
 /* These elements must be at the end, see alloc_skb() for details.  */
 sk_buff_data_t  tail;
 sk_buff_data_t  end;
 unsigned char  *head,
    *data;
 unsigned int  truesize;
 atomic_t  users;
};