设为首页 加入收藏

TOP

Linux网络协议栈之套接字缓冲区(一)
2014-11-24 12:29:28 来源: 作者: 【 】 浏览:3
Tags:Linux 网络 协议 套接字 缓冲区

Linux网络协议栈是内核中最大的组件之一,由于网络部分应用的范围很广,也相对较热,该部分现有的资料很多,学起来也比较容易。首先,我们看看贯穿网络协议栈各层的一个最关键数据结构——套接字缓冲区(sk_buff结构)。


一个封包就存储在这个数据结构中。所有网络分层都会使用这个结构来存储其报头、有关数据的信息,以及用来协调工作的其他内部信息。在内核的进化历程中,这个结构经历多次变动,本文及后面的文章都是基于2.6.20版本,在2.6.32中该结构又变化了很多。该结构字段可粗略划分为集中类型:布局、通用、专用、可选(可用宏开关)。


SKB在不同网络层之间传递,可用于不同的网络协议。协议栈中的每一层往下一层传递SKB之前,首先就是调用skb_reserve函数在数据缓存区头部预留出的一定空间以保证每一层都能把本层的协议首部添加到数据缓冲区中。如果是向上层协议传递skb,则下层协议层的首部信息就没有用了,内核实现上用指针改变指向来实现。


下面看看该结构体中的字段,大部分都给了注释,后面的方法与实现中我们将看到他的各个字段的应用与实际意义。


struct sk_buff {


/* These two members must be first. */


/*链表,放在结构头,用于强制转化得到,链表头为skb_buff_head*/


struct sk_buff *next;


struct sk_buff *prev;



/*指向拥有此缓冲区的sock数据结构,当数据在本地


产生或者正由本地进程接收时,就需要这个指针


因为该数据以及套接字相关的信息会由L4


以及用户应用程序使用。当缓冲去只是被


转发时,该指针为NULL*/


struct sock *sk;



/*通常只对一个以及接收的封包才有意义


这是一个时间戳记,用于表示封包何时被


接收,或者有时用于表示封包预定传输时间


*/


struct skb_timeva l tstamp;



/*此字段描述一个网络设备,该字段的作用与该SKB是发送包还是


接受包有关*/


struct net_device *dev;



/*接收报文的原始网络设备,主要用于流量控制*/


struct net_device *input_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;



/*IPSec协议用来跟踪传输的信息*/


struct sec_path *sp;



/*


* 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.


*/


/*SKB信息控制块,是每层协议的私有信息存储空间,由每层协议


自己使用并维护,并只有在本层有效*/


char cb[48];



/*数据总长度,包括线性缓冲区数据长度(data指向),SG类型的聚合分散I/O的数据


以及FRAGLIST类型的聚合分散I/O的数据长度,也包括协议首部的长度*/


unsigned int len,



/*SG类型和FRAGLIST类型聚合分散I/O存储区中的数据长度*/


data_len,



/*二层首部长度。实际长度与网络介质有关,在以太网中为以太网桢首部的长度*/


mac_len;


union {


__wsum csum;


__u32 csum_offset;


};



/*发送或转发QOS类别。*/


__u32 priority;



/*表示此skb在本地允许分片*/


__u8 local_df:1,



/*标记所属SKB是否已经克隆*/


cloned:1,



/*标记传输层校验和的状态*/


ip_summed:2,


首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Boost库简介以及在cygwin下的安装.. 下一篇在Ubuntu 12.04 下编译GCC 4.7

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·HyperText Transfer (2025-12-26 07:20:48)
·半小时搞懂 HTTP、HT (2025-12-26 07:20:42)
·CPython是什么?PyPy (2025-12-26 06:50:09)
·Python|如何安装seab (2025-12-26 06:50:06)
·python要学习数据分 (2025-12-26 06:50:03)