非常详细的详谈struct sk_buff

struct sk_buff是Linux内核中处理网络数据包的关键数据结构,它用于存储网络包并实现自底向上的层间传递。sk_buff包含多个指针,用于标识数据包的不同部分,如数据、协议头和链路层头。结构体内部的双向链表管理着多个sk_buff,便于数据包处理和传递。通过skb_reserve、skb_push等函数,协议栈可以在数据包中添加或移除头部,而sk_buff的引用计数机制保证了资源的有效管理。
摘要由CSDN通过智能技术生成

非常详细的详谈struct sk_buff

排版太慢

难看的话可以下载WOR文档

专门详解struct_sk_buff

链接: http://pan.baidu.com/s/1gf8VNKR 密码: pquc

注:本文大部分内容来源于网络收集加上自己理解,如有不托之处,请指出,本人无任何版权

全称socket buffers,简称skb,中文名字叫套接字缓存。它作为网络数据包的存放地点,使得协议栈中每个层都可以对数据进行操作,从而实现了数据包自底向上的传递。该结构维护一个收到的或者要发送的网络包。但其本身并不包含存放网络包的数据的存储区。存储区是另外单独分配的内存空间,但该结构说明了如何访问存储区空间,如何维护多个存储区空间以及存储网络包解析的成果。

所有的sk_buff是通过一个双向链表进行维护的。需要说明的是该双向链表中的一个元素是struct sk_buff_head类型。它相当于该双向链表的表头,其中有锁,链表元素个数等维护链表的相关信息。链表中其它的元素都是sk_buff类型。

这个结构被网络的不同层(MAC或者其他二层链路协议,三层的IP,四层的TCP或UDP等)使用,并且其中的成员变量在结构从一层向另一层传递时改变。 L4向L3传递前会添加一个L4的头部,同样,L3向L2传递前,会添加一个L3的头部。添加头部比在不同层之间拷贝数据的效率更高。由于在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数skb_reserve来完成这个功能。协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间。

    skb_reserve同样被设备驱动使用来对齐接收到包的包头。如果缓冲区向上层协议传递,旧的协议层的头部信息就没什么用了。例如,L2的头部只有在网络驱动处理L2的协议时有用,L3是不会关心它的信息的。但是,内核并没有把L2的头部从缓冲区中删除,而是把有效荷载的指针指向L3的头部,这样做,可以节省CPU时间。

有些sk_buff成员变量的作用是方便查找或者是连接数据结构本身。内核可以把sk_buff组织成一个双向链表。当然,这个链表的结构要比常见的双向链表的结构复杂一点。就像任何一个双向链表一样,sk_buff中有两个指针next和prev,其中,next指向下一个节点,而prev指向上一个节点。在第一个节点前面会插入另一个结构sk_buff_head,这是一个辅助节点(作为sk_buff双向链表的头),它的定义如下:

struct sk_buff_head {

    struct sk_buff -*next;

    struct sk_buff -*prev;

    __u32           qlen;

    spinlock_t      lock;

};

qlen代表链表元素的个数

lock用于防止对链表的并发访问

sk_buff和sk_buff_head的前两个元素是一样的:next和prev指针。这使得它们可以放到同一个链表中,尽管sk_buff_head要比sk_buff小得多。另外,相同的函数可以同样应用于sk_buff和sk_buff_head。

以下是truct sk_buff 数据结构(源代码)

truct sk_buff - socket buffer

struct sk_buff {

 /* These two members must be first. */

         struct sk_buff          *next;//@next: Next buffer in list 链表中下一个缓存

         struct sk_buff          *prev;@prev: Previous buffer in list链表中前一个缓存

         struct sk_buff_head     *list;@list: List we are on//当前链表

        struct sock             *sk;@sk: Socket we are owned by//所属socket

         struct timeval          stamp;@stamp: Time we arrived(分组)到达的时间

         struct net_device       *dev;@dev: Device we arrived on/are leaving by分组离开的设备

         struct net_device       *input_dev;@input_dev: Device we arrived on

         struct net_device       *real_dev;@real_dev: The real device we areusing

 

         union {

              struct tcphdr   *th;@nh: Network layer header

                 struct udphdr   *uh;

                 struct icmphdr  *icmph;

                 struct igmphdr  *igmph;

                 struct iphdr    *ipiph;

                 struct ipv6hdr  *ipv6h;

                 unsigned char   *raw;

         } h;@h: Transport layer header传输层头标(tcp,udp,icmp,igmp,spx,raw)

               union {

                    struct iphdr    *iph;

                   struct ipv6hdr  *ipv6h;

                   struct arphdr   *arph;

                    unsigned char   *raw;

           } nh;@nh:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值