sk_buff有关的几个重要的数据结构

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;  
};  

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

union{  
    struct ethhdr *ethernet;  
    unsigned char *raw;  
}mac;  

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

#ifdef NET_SKBUFF_DATA_USES_OFFSET   
typedef unsigned int sk_buff_data_t;  
#else   
typedef unsigned char *sk_buff_data_t;  
#endif  

这里主要说明下后面几个后面的四个属性的含义head、data、tail、end

head是缓冲区的头指针,data是数据的起始地址,tail是数据的结束地址,end是缓冲区的结束地址
这里写图片描述

char cb[48] __aligned(8);中的48个字节是控制字段,配合各层协议工作,为每层存储必要的控制信息。

2。sk_buff_head结构体

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

    __u32       qlen;  
    spinlock_t  lock;  
};  

这个结构体比较简单,前面两个指针是用于和sk_buff结构串成双向链表,用于管理sk_buff双链表,qlen属性表示该链表中sk_buff的数目,lock是自旋锁。

3。skb_shared_info结构体

struct skb_shared_info {  
    unsigned short  nr_frags;  
    unsigned short  gso_size;//尺寸   
    /* Warning: this field is not always filled in (UFO)! */  
    unsigned short  gso_segs;//顺序   
    unsigned short  gso_type;  
    __be32          ip6_frag_id;  
    __u8        tx_flags;  
    struct sk_buff  *frag_list;//分片的sk_buff列表   
    struct skb_shared_hwtstamps hwtstamps;//硬件时间戳   

    /* 
     * Warning : all fields before dataref are cleared in __alloc_skb() 
     */  
    atomic_t    dataref;//使用计数   

    /* Intermediate layers must ensure that destructor_arg 
     * remains valid until skb destructor */  
    void *      destructor_arg;  

    /* must be last field, see pskb_expand_head() */  
    skb_frag_t  frags[MAX_SKB_FRAGS];  
}; 

该类型用来管理数据包分片信息,通过宏可以表示与skb的关系

#define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB)))  


#ifdef NET_SKBUFF_DATA_USES_OFFSET   
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)  
{  
    return skb->head + skb->end;  
}  
#else   
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)  
{  
    return skb->end;  
}  
#endif  

可以看到如果用户没有自己使用偏移量,就是skb的end属性指针,也就是该信息存储在缓冲区之后。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值