struct sk_buff { /* These two members must be first. */ struct sk_buff *next; //这两个变量让sk_buff struct sk_buff *prev; //构成双向的链表
struct sk_buff_head *list; //指向链表的头 struct sock *sk; //指向创建这个sk_buff的socket struct timeval stamp; //该packet到达的时间(以jiffies为单位) struct net_device *dev; //incoming/outcoming 的设备 struct net_device *input_dev; //到达的设备 struct net_device *real_dev; //真实使用的设备
union { //指向传输层 struct tcphdr *th; struct udphdr *uh; struct icmphdr *icmph; struct igmphdr *igmph; struct iphdr *ipiph; struct ipv6hdr *ipv6h; unsigned char *raw; } h;
union { //指向网络层 struct iphdr *iph; struct ipv6hdr *ipv6h; struct arphdr *arph; unsigned char *raw; } nh;
union { //指向链路层 unsigned char *raw; } mac;
struct dst_entry *dst; //目的表项(指向一个路由cache,在后面文章详解) struct sec_path *sp; //只被xfrm使用(这个讨论基本上没用到)
/* * This is the control buffer. It is free to use for every * layer. Please put your private variables there. If you * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. */ char cb[40];
unsigned int len, //真实数据区的长度 data_len, //数据区的长度 mac_len, //mac长度 csum; //checknum __u32 priority;
//以下都是作为flag用,只用了一个byte的5个bit __u8 local_df:1, //允许local分片标志 cloned:1, //允许clone操作标志 ip_summed:2, nohdr:1; /* 3 bits spare */
__u8 pkt_type; //packet的类型,在if_packet.h中定义取值 __be16 protocol;
void (*destructor)(struct sk_buff *skb); ............
............ /* These elements must be at the end, see alloc_skb() for details. */ unsigned int truesize; //buffer的大小(后面详解) atomic_t users; //user计数,atomic_t指明该变量只能"原子"操作
//在后面详细介绍 unsigned char *head, *data, *tail, *end; }; |
评论暂时关闭