MABC
MABC

Reputation: 595

How sk_buff points to sk_buff_head

sk_buff data structure in linux kernel is organised into a doubly linked list, but the last member and first member of this list are pointing to a sk_buff_head struct . However next and prev members are declared as pointers to sk_buff not sk_buff_head. How is this possible?

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

Upvotes: 1

Views: 1694

Answers (3)

ChrisPhoenix
ChrisPhoenix

Reputation: 1090

It's ugly, but it works because "next" and "prev" are in the same place (first fields) of both sk_buff and sk_buff_head. The list handling code knows that it might actually be either structure, and casts (coerces) it when necessary to maintain the ring of pointers with one sk_buff_head in the ring.

Upvotes: 0

krase
krase

Reputation: 1044

As David Miller discribes it in his website, the sk_buff_head structure is used to place an sk_buff in several lists and make them easy accessible:

struct sk_buff {
    /* These two members must be first. */
    struct sk_buff      *next;
    struct sk_buff      *prev;

    struct sk_buff_head *list;
 ...

The first two members implement list handling. Packets can exist on several kinds of lists and queues. For example, a TCP socket send queue. The third member says which list the packet is on.

Upvotes: 1

macfij
macfij

Reputation: 3209

every sk_buff structure in that doubly linked list must be able to find the head of whole list quickly. that's the purpose of sk_buff_head structure, which is inserted at the beginning of the list. so, sk_buff_head is a special sk_buff. it wouldn't make any sense to point to another sk_buff_head inside. i think that you would point to the head of whole different doubly linked list, if next and prev members where sk_buff_head...
see the image below for understanding this concept.

sk_buff_head image

Upvotes: 2

Related Questions