sk_buff如何指向sk_buff_head

时间:2014-06-17 23:10:01

标签: c networking linux-kernel

linux内核中的

sk_buff数据结构被组织成一个双向链表,但该列表的最后一个成员和第一个成员指向sk_buff_head struct。但是,nextprev成员被声明为指向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;  
}; 

3 个答案:

答案 0 :(得分:2)

该双向链表中的每个sk_buff结构必须能够快速找到整个列表的头部。这是sk_buff_head结构的目的,它插在列表的开头。所以,sk_buff_head是一个特殊的sk_buff。在内部指向另一个sk_buff_head是没有任何意义的。我认为你会指向整个不同的双向链表的头部,如果下一个和prev成员在哪里sk_buff_head ...
请参阅下图以了解此概念。

sk_buff_head image

答案 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的指针环。