sk_buff结构详解

linux内核版本3.19

struct sk_buff {
    union {
        struct {
            /* These two members must be first. */
            struct sk_buff      *next;
            struct sk_buff      *prev;
//next和prev指针:协议栈中经常用到sk_buff的队列,队列通过sk_buff中的指针相连接。这两个指针用来连接相关的skb的(例如有分片,则将这些分片连在一起。)
            union {
                ktime_t     tstamp;
                struct skb_mstamp skb_mstamp;
            };//报文到达或者离开的时间戳;
        };
        struct rb_node  rbnode; /* used in netem & tcp stack */
    };
    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;
    void            (*destructor)(struct sk_buff *skb); 这是析构函数,后期在skb内存销毁时会用到

#ifdef CONFIG_XFRM
    struct  sec_path    *sp;//安全路径,用于xfrm
#endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
    struct nf_conntrack *nfct;//netfilter跟踪的连接信息;
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
    struct nf_bridge_info   *nf_bridge;//桥接相关信息;
#endif
    unsigned int        len,//当前协议数据包的长度,包括主缓冲区中数据长度和分片中数据长度(个人理解为当前协议层包头和数据区域长度)。skb的组成是sk_buff控制+线性数据+非线性数据(skb_shared_info)组成!

                    data_len;//分片中数据长度
    __u16           mac_len,//mac报头的长度
                    hdr_len;//用于clone时,表示clone的skb的头长度;

    /* Following fields are _not_ copied in __copy_skb_header()
     * Note that queue_mapping is here mostly to fill a hole.
     */
    kmemcheck_bitfield_begin(flags1);
    __u16           queue_mapping;//队列映射
    __u8            cloned:1,//是否允许被克隆
                nohdr:1,//运载时不能修改头部
                fclone:2,//数据包克隆状态
                peeked:1,//数据包是否处于操作状态
                head_frag:1,
                xmit_more:1;
    /* one bit hole */
    kmemcheck_bitfield_end(flags1);

    /* fields enclosed in headers_start/headers_end are copied
     * using a single memcpy() in __copy_skb_header()
     */
    /* private: */
    __u32           headers_start[0];
    /* public: */

/* if you move pkt_type around you also must adapt those constants */
#ifdef __BIG_ENDIAN_BITFIELD
#define PKT_TYPE_MAX    (7 << 5)
#else
#define PKT_TYPE_MAX    7
#endif
#define PKT_TYPE_OFFSET()   offsetof(struct sk_buff, __pkt_type_offset)

    __u8            __pkt_type_offset[0];
    __u8            pkt_type:3;//报文类型
    __u8            pfmemalloc:1;
    __u8            ignore_df:1;//是否允许分片相关标志位
    __u8            nfctinfo:3;//数据包连接关系

    __u8            nf_trace:1;//netfilter对数据包的跟踪标志
    __u8            ip_summed:2;//ip校验和标志
    __u8            ooo_okay:1;
    __u8            l4_hash:1;
    __u8            sw_hash:1;
    __u8            wifi_acked_valid:1;
    __u8            wifi_acked:1;

    __u8            no_fcs:1;
    /* Indicates the inner headers are valid in the skbuff. */
    __u8            encapsulation:1;
    __u8            encap_hdr_csum:1;
    __u8            csum_valid:1;
    __u8            csum_complete_sw:1;
    __u8            csum_level:2;
    __u8            csum_bad:1;

#ifdef CONFIG_IPV6_NDISC_NODETYPE
    __u8            ndisc_nodetype:2;
#endif
    __u8            ipvs_property:1;
    __u8            inner_protocol_type:1;
    __u8            remcsum_offload:1;
    /* 3 or 5 bit hole */

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

    union {
        __wsum      csum;//校验和
        struct {
            __u16   csum_start;//skb->head即校验和计算起始点;
            __u16   csum_offset;//校验和存储位置偏移(以csum_start处起始偏移csum_offset大小)
        };
    };
    __u32           priority;//报文排队优先级,取决于ip中的tos域
    int         skb_iif;//报文到达接口的索引号;
    __u32           hash;//数据包的hash值;
    __be16          vlan_proto;//vlan封装协议;
    __u16           vlan_tci;//vlan标签控制信息;
#ifdef CONFIG_NET_RX_BUSY_POLL
    unsigned int    napi_id;
#endif
#ifdef CONFIG_NETWORK_SECMARK
    __u32           secmark;
#endif
    union {
        __u32       mark;
        __u32       dropcount;
        __u32       reserved_tailroom;
    };

    union {
        __be16      inner_protocol;
        __u8        inner_ipproto;
    };

    __u16           inner_transport_header;//内部封装的传输层头;
    __u16           inner_network_header;//内部封装的网络层头;
    __u16           inner_mac_header;

    __be16          protocol;//协议
    __u16           transport_header;//传输层头
    __u16           network_header;//网络层头
    __u16           mac_header;//链路层头

    /* private: */
    __u32           headers_end[0];
    /* public: */

    /* 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;//该缓冲区分配的所有总的内存,包括:skb_buff + 所有数据大小;
    atomic_t        users;//保存引用skb_buff的数量
};

skb队列

skb头部指针

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值