sk_buff 里的head、data、len, data_len, tail,end

使用内核是4.4

架构是powerpc64,64位,这个跟32位计算是有差别的,需要注意。

下面以64位为例子,先看几个接口,最后是实际运行时的代码输出,可以结合了解是怎么计算的。

struct sk_buff {
    ......
    unsigned int            len,
                         data_len;
    ......

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

#if BITS_PER_LONG > 32
#define NET_SKBUFF_DATA_USES_OFFSET 1
#endif

#ifdef NET_SKBUFF_DATA_USES_OFFSET
typedef unsigned int sk_buff_data_t;    64位是偏移长度
#else
typedef unsigned char *sk_buff_data_t;   32位是地址
#endif

static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
        return skb->len - skb->data_len;
}

static inline unsigned int skb_headroom(const struct sk_buff *skb)
{
        return skb->data - skb->head;
}

#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
        return skb->head + skb->end;   //end是uint,以head地址开始
}

static inline unsigned int skb_end_offset(const struct sk_buff *skb)
{
        return skb->end;
}
#else
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
        return skb->end;
}

static inline unsigned int skb_end_offset(const struct sk_buff *skb)
{
        return skb->end - skb->head;
}
#endif
 

#ifdef NET_SKBUFF_DATA_USES_OFFSET
static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
{
        return skb->head + skb->tail;  // tail是uint,也以head开始
}

static inline void skb_reset_tail_pointer(struct sk_buff *skb)
{
        skb->tail = skb->data - skb->head;  //reset时,初始值是data与head的偏移
}

static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
{
        skb_reset_tail_pointer(skb);
        skb->tail += offset;
}

#else /* NET_SKBUFF_DATA_USES_OFFSET */
static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
{
        return skb->tail;
}

static inline void skb_reset_tail_pointer(struct sk_buff *skb)
{
        skb->tail = skb->data;
}

static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
{
        skb->tail = skb->data + offset;
}

#endif /* NET_SKBUFF_DATA_USES_OFFSET */
 


下面是单板上的输出,64位的。
skb地址:ffff80006f6cea00
skb->len=2058
skb->data_len=2016
skb_headlen(skb)=42
skb_headroom(skb):2,
skb->tail:44,
skb->end:192,
head地址:ffff80006eb92a00,
data地址:ffff80006eb92a02

总长度:2058,分片数据长度:2016 线性数据:42

从skb_tail_pointer看出64位下,tail的地址是从head地址开始算起。

tail是数据结束,如果从data开始计算,tail-skb_headroom(skb)才是线性数据的长度=42.

猜你喜欢

转载自blog.csdn.net/megan_free/article/details/85322521
今日推荐