第一范文网 - 专业文章范例文档资料分享平台

SK - BUFF学习笔记

来源:用户分享 时间:2025/5/26 6:23:15 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

在这几天的工作中总是或多或少的接触到了sk_buff结构体。后来我觉得这样时不时地学点sk_buff结构还不如干脆花段时间来研究下这个重要的结构体。所以我就学习了《深入理解linux网络技术内幕》有关sk_buff结构的介绍,这系列博文本来是我根据《深入理解linux网络技术内幕》学习整理而来的,可以算作是笔记吧。后来在看sk_buff克隆和拷贝时,又看了下《linux内核源码剖析:TCP/IP实现》。现在这博文是经过修改的,所以也加进了在《llinux内核源码剖析:TCP/IP实现》学习到的内容。大家也可以看看原文对sk_buff结构体的一些讲解,原文分别在第二章关键数据结构:套接字缓冲区:sk_buff结构和第三章:套接字缓存。如果没有电子书的,可以私信我留下邮箱地址。

我要先感谢下这两本书的作者以及译者,《深入理解linux网络技术内幕》是linux网络中的一本经典之作,对于学习linux网络来说是非常有用的,这是本全面宏观的介绍linux网络的书;《linux内核源码剖析:TCP/IP实现》我开始看的是电子书,这本书吸引我的地方是讲解的非常详细,而且是非常简洁,尤其是对各个知识点的讲解非常透彻。

下面开始正式的讲解sk_buff结构内容,至于sk_buff结构体的重要性以及历史背景之类的我就不过多废话了。

sk_buff结构体:

第一、内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体,而是通过增加协议头和移动指针来操作的。如果是从L4传输到L2,则是通过往sk_buff结构体中增加该层协议头来操作;如果是从L4到L2,则是通过移动sk_buff结构体中的data指针来实现,不会删除各层协议头。这样做是为了提高CPU的工作效率。

第二、sk_buff结构体中有很多条件编译,比如:

#ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info*nf_bridge; #endif

因为sk_buff结构体是linux网络代码中最重要的数据结构,是整个网络传输载体。所以sk_buff结构体

里面有很多关于其他功能的成员字段,比如:防火墙,子路由系统,多播等。这些字段并不是一定有的,只有在满足特点条件才有的。所以可以在需要的时候再去关心这些成员字段,现在我们只来讲解下一般的成员字段。

第三、下面就直接来看sk_buff结构体了。为了好理解结构中的一些成员字段,先把后面要讲的内容提前说下。sk_buff结构体关联多个其他结构体,第一是数据区:由sk_buff中head和end指向的数据块,用来存储sk_buff结构的数据也即是存储数据包的内容和各层协议头。第二是分片结构:用来表示IP分片的一个结构体,实则上是和sk_buff结构的数据区相连的,即是end指针的下一个字节开始就是分片结构。也正是此原因,所以分片结构和sk_buff数据区内存分配及销毁时都是一起的。第三个是分片结构指向的数据区,即是IP分片内容。下面开始看sk_buff结构体:

struct sk_buff {

/* These two members must be first. */ struct sk_buff struct sk_buff

*next; // 因为sk_buff结构体是双链*prev; // 这是指向前一个sk_buff结

表,所以有前驱后继。这是个指向后面的sk_buff结构体指针 构体指针

//老版本(2.6以前)应该还有个字段: sk_buff_head *list //struct sock ktime_t

*sk; // 指向拥有此缓冲的套接字tstamp; // 时间戳,表示这个skb的接*dev; // 表示一个网络设备,当skb为

即每个sk_buff结构都有个指针指向头节点 sock结构体,即:宿主传输控制模块

收到的时间,一般是在包从驱动中往二层发送的接口函数中设置

struct net_device

输出/输入时,dev表示要输出/输入到的设备

unsigned long _skb_dst; // 主要用于路由子系统,保存路由有关的东西

度,

char

cb[48]; // 保存每层的控制信息,每一len, // 表示数据区的长度(tail - data)

层的私有信息

unsigned int

与分片结构体数据区的长度之和。其实这个len中数据区长度是个有效长 // 因为不删除协议头,所以只计算有效协议头和包内容。如:当在L3时,不会计算L2的协议头长度。 志

cloned:1, // 为1表示该结构被克隆,

或者自己是个克隆的结构体;同理被克隆时,自身skb和克隆skb的cloned都要置1

ip_summed:2,

nohdr:1, // nohdr标识payload是否被

data_len; // 只表示分片结构体数据区mac_len, // mac报头的长度

hdr_len; // 用于clone时,表示clone

的长度,所以len = (tail - data) + data_len;

__u16

的skb的头长度

// 接下来是校验相关域,这里就不详细讲了。 __u32 __u8

priority; // 优先级,主要用于QOS local_df:1, // 是否可以本地切片的标

kmemcheck_bitfield_begin(flags1);

单独引用,不存在协议首部。 // 如果被引用,则决不能再修改协议首部,也不能通过skb->data来访问协议首部。

__u8

nfctinfo:3;

pkt_type:3, // 标记帧的类型 fclone:2, // 这个成员字段是克隆时ipvs_property:1, peeked:1, nf_trace:1;

protocol:16; // 这是包的协议类型,标

使用,表示克隆状态

__be16

识是IP包还是ARP包或者其他数据包。

kmemcheck_bitfield_end(flags1);

void (*destructor)(struct sk_buff *skb); // 这是析构函

数,后期在skb内存销毁时会用到 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)

struct nf_conntrack struct sk_buff

*nfct; *nfct_reasm;

#endif

#ifdef CONFIG_BRIDGE_NETFILTER

struct nf_bridge_info *nf_bridge; int

iif; // 接受设备的index tc_index;

/* traffic control

#endif

#ifdef CONFIG_NET_SCHED

__u16 index */

#ifdef CONFIG_NET_CLS_ACT

__u16

tc_verd;

/* traffic control

verdict */ #endif #endif

kmemcheck_bitfield_begin(flags2); __u16 __u8

queue_mapping:16; ndisc_nodetype:2;

#ifdef CONFIG_IPV6_NDISC_NODETYPE #endif

kmemcheck_bitfield_end(flags2); /* 0/14 bit hole */ dma_cookie_t

dma_cookie;

#ifdef CONFIG_NET_DMA #endif

#ifdef CONFIG_NETWORK_SECMARK

__u32 __u32 __u16

secmark; mark; vlan_tci;

transport_header; // 指向四层帧

#endif

sk_buff_data_t

搜索更多关于: SK - BUFF学习笔记 的文档
SK - BUFF学习笔记.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c1c0b03o6cu2p7v440mf6_1.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top