sk_buff
数据结构被组织成一个双向链表,但该列表的最后一个成员和第一个成员指向sk_buff_head struct
。但是,next
和prev
成员被声明为指向sk_buff
而不是sk_buff_head
的指针。这怎么可能?
struct sk_buff {
struct sk_buff * next;
struct sk_buff * prev;
struct sk_buff_head * list;
struct sock * sk;
struct timeval stamp;
struct net_device * dev;
struct net_device * real_dev;
union private;
#endif#ifdef CONFIG_NET_SCHED__u32 tc_index;
#endif
unsigned int truesize;
atomic_t users;
};
struct sk_buff_head {
/* These two members must be first. */
struct sk_buff * next;
struct sk_buff * prev;
__ U32 qlen;
spinlock_t lock;
};
答案 0 :(得分:2)
该双向链表中的每个sk_buff结构必须能够快速找到整个列表的头部。这是sk_buff_head结构的目的,它插在列表的开头。所以,sk_buff_head是一个特殊的sk_buff。在内部指向另一个sk_buff_head是没有任何意义的。我认为你会指向整个不同的双向链表的头部,如果下一个和prev成员在哪里sk_buff_head ...
请参阅下图以了解此概念。
答案 1 :(得分:1)
正如David Miller在他的website中描述的那样,sk_buff_head结构用于将sk_buff放在几个列表中并使它们易于访问:
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
struct sk_buff_head *list;
...
前两个成员实现列表处理。数据包可以存在于多种列表和队列中。例如,TCP套接字发送队列。第三个成员说明数据包所在的列表。
答案 2 :(得分:0)
这很丑陋,但是可以使用,因为“ next”和“ prev”与sk_buff和sk_buff_head都位于同一位置(第一字段)。列表处理代码知道它实际上可能是任何一种结构,并在必要时强制转换(强制)它,以维护在指针环中带有一个sk_buff_head的指针环。