最近看了挺多linux源码,想着写一些总结,一来可以给别人参考,二来自己还能加深下印象。
这些天看的最多的是网络相关的源码,先从skb_buff这个结构体写起吧。
union {
struct {
struct sk_buff *next;
struct sk_buff *prev;
union {
struct net_device *dev;//标识网络设备
unsigned long dev_scratch;//用数字标识设备?
};
};
struct rb_node rbnode;
struct list_head list;
};
//采用这样的形式,表明skb_buff是一个双链表结构,之前的版本,用prev、next指向前后节点,现在的版本又增加了rbnode和list,效果是一样的。
union {
struct sock *sk;
int ip_defrag_offset;
};
//这里是一个sock结构体,用于指明sock,sock结构体是socket在网络层的表示,内容太多,先不展开说明了,该结构体定义在\include\net\sock.h文件中
//ip_defrag_offset变量是之后的版本才有的,还没看明白这里的作用。
union {
ktime_t tstamp;
u64 skb_mstamp_ns; /* earliest departure time */
};
//表示报文到达或离开的时间戳。
char cb[48] __aligned(8);
//中的48个字节是控制字段,配合各层协议工作,为每层存储必要的控制信息。相当于每一层都可以使用它来存储私有数据。
union {
struct {
unsigned long _skb_refdst;
void (*destructor)(struct sk_buff *skb);
};
struct list_head tcp_tsorted_anchor;
};
//引用计数,怎么使用的没看明白。
unsigned int len,data_len;//只表示切片数据的长度,也就是skb_shared_info中的长度
__u16 mac_len,hdr_len;//用于clone的时候,它表示clone的skb的头的长度
//len是缓冲区以及一些片段的总长度,data_len只是一些片段的长度,mac_len是MAC报头的长度,hdr_len是克隆skb时可写报头的长度。
__u16 queue_mapping;//多队列设备的映射,也就是说映射到那个队列。
__be16 protocol;//通知上层采用哪种协议来处理数据
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
#endif
#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
//这些成员由netfilter相关代码所使用。
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
//这些成员代表缓冲区的边界以及其中的数据,head和end指向已分配缓冲区空间的开端和尾端,而data和tail则指向实际数据的开端和尾端
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head,
*data;
//这些成员代表缓冲区的边界以及其中的数据,head和end指向已分配缓冲区空间的开端和尾端,而data和tail则指向实际数据的开端和尾端
unsigned int truesize;
//此成员代表缓冲区总的大小,包括sk_buff结构本身。
refcount_t users;
//引用计数,避免正在使用时被其它用户所释放掉。