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.