sk_buff结构体成员变量说明

news2024/11/24 7:55:03

一. 前言

        Socket Buffer的数据包在穿越内核空间的TCP/IP协议栈过程中,数据内容不会被修改,只是数据包缓冲区中的协议头信息发生变化。大量操作都是围绕sk_buff结构体来进行的。

        sk_buff结构的成员大致分为3类:结构管理域,常规数据域和网络功能配置相关域。

二. sk_buff数据结构体解析

1. 结构管理域

*next和prev:

        sk_buff会被链入到一个双链表中,next指向链表的下一个成员,prev指向链表的前一个成员。链表的头是一个sk_buff_head的结构体,如下所示:

struct sk_buff_head {
	/* These two members must be first. */
	struct sk_buff	*next;
	struct sk_buff	*prev;

	__u32		qlen;
	spinlock_t	lock;
};

        其中qlen表示链表中sk_buff结构实例成员的个数,lock用于对双链表操作的保护的锁,防止并发访问链表。示意图如下

         内核管理Socket Buffer的优点:某个Socket Buffer的状态变化了,需要将Socket Buffer在各队列之间移动时,无需复制整个缓冲区,只需要修改prev和next指针,就可以将Socket Buffer的缓冲区从一个队列放入到另一个队列管理。例如struct usbnet结构体如下:

struct usbnet {
    ......
    struct sk_buff_head     rxq;
    struct sk_buff_head     txq;
    struct sk_buff_head     done;
    struct sk_buff_head     rxq_pause;
    ......
}

struct sock *sk:

        指向拥有该Socket Buffer的套接字数据结构的指针。当数据是由本机的应用产生,将要对外发送时,或从网络来的数据包的目的地址是本机的应用程序时,这个数据域需要被设置。

        套接字本质是端口号加IP,用来唯一识别系统中的网络应用程序。sk_buff->sk数据域表示网络数据包最终应该送给到哪个应用程序。如果是需要从本机Forward的数据包,sk应该被设置为空。

unsigned int len:

        表示数据包的实际的长度,也就是sk_buff->data指向的数据的实际长度。sk_buff->len在数据包通过协议栈的各层时其值也会发生变化因为各层的协议头信息在不断加入或从Socket Buffer中去掉,因为sk_buff->len包含了协议头的长度。

        sk_buff->len包括两个部分:主缓冲区的数据长度和各个分片数据的长度

unsigned int data_len:

        data_len只是计算了被分了片的数据块长度。所以data_len应该要等于或小于len。

__u16 mac_len:

        数据链路层协议头的长度。

__u16 hdr_len:

        hdr_len是针对克隆数据包时使用的,它表示克隆的数据包的头长度。

static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
{
    ......
	n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
    ......
}

atomic_t users:

        引用计数,所有使用该sk_buff缓冲区的进程计数。这个参数的作用是防止sk_buff还在使用就被释放了。任何进程要使用sk_buff时,应该对sk_buff->users加1,使用完后应该对sk_buff->users减1。通常加和减操作分别使用skb_get和free_skb函数,这样做更安全。

unsigned int truesize:

        记录整个Socket buffer的大小,即sk_buff数据结构的长度和数据包的长度和。它是由alloc_skb函数将其初始化为len+sizeof(sk_buff)。

sk_buff_data_t tail;

sk_buff_data_t end;

unsigned char *head,*data:

        Socket Buffer的数据缓冲区的内容包括:TCP/IP协议栈各层的协议头信息;负载数据。这是最终在网络上传送的内容。以上的几个域代表数据包缓冲区中各个信息的边界。

        head和end指向整个数据包缓冲区的起始和结束地址,data和tail指向实际数据的起始和结束地址,各层的协议处理函数可以在data和head之间的空隙处填写头信息,在tail和end之间放新数据。

 void (*destructor)(...):

        destructor函数指针可以在sk_buff数据结构初始化时指向Socket Buffer的析构函数。在释放Socket Buffer时,完成具体的清除工作。当sk_buff不属于任何套接字时,析构函数不需要初始化。

2. 常规数据域

ktime_t tstamp:

        描述数据包到达内核的时间。由接收数据包处理函数netif_rx调用net_timestamp(skb)来对该数据域赋值。

struct net_device *dev:

        dev是指向代表网络设备数据结构的指针。它表示该数据包是通过哪个网络设备接收或传送的。当网络设备从网络上收到一个数据包时,设备驱动程序将该域更新为一个net_device类型的指针,指向接收该数据包的网络设备。

static int fe_poll_rx(struct napi_struct *napi, int budget,
		struct fe_priv *priv, u32 rx_intr)
{
    ......    
	skb->protocol = eth_type_trans(skb, netdev);
    ......
}

__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
    ......
	skb->dev = dev;
    ......
}

char cb[48]:

        控制缓冲区(Control Buffer),是各层协议在处理数据包时存放私有信息或变量的地方。各层协议可以自由使用该控制缓冲区。控制缓冲区大小是48字节,如果在传输层,UDP协议用控制缓冲区来存放它的udp_skb_cb数据结构。

struct udp_skb_cb {
	union {
		struct inet_skb_parm	h4;
#if IS_ENABLED(CONFIG_IPV6)
		struct inet6_skb_parm	h6;
#endif
	} header;
	__u16		cscov;
	__u8		partial_cov;
};

        内核定义了宏来访问控制缓冲区,一下代码是UDP访问其私有数据的宏。

#define UDP_SKB_CB(__skb)	((struct udp_skb_cb *)((__skb)->cb))

       以下是在初始化过程中对UDP数据包做校验和时,填写控制缓冲区代码:

static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
				 int proto)
{
    ......
	UDP_SKB_CB(skb)->partial_cov = 0;
	UDP_SKB_CB(skb)->cscov = skb->len;
    ......
}

        r如果需要让控制缓冲区的信息跨协议层传送,必须克隆sk_buff。

__wsum csum:

        csum用于存放发送数据的校验和。发送数据包时,我们将数据从用户地址空间复制到内核地址空间,同时以相应的算法计算数据包的校验和存放在该数据域。

csum_start/csum_end:

        存放接收数据的校验和。csum_start以skb->head为起始地址的偏移量,指出校验和从数据什么位置开始计算。csun_offset以csum_start为起始地址的偏移量,指出校验和存放的地址。

__u8 ip_summed:

          描述网络设备是否可用硬件对IP数据进行校验编码和解码。ip_summed是两位描述网络设备硬件对校验和的支持,它是设备驱动程序反馈的信息。ip_summed的值可以如下:

CHECKSUM_NONE:网络设备不具备计算校验和的功能。

CHECKSUM_UNNECESSARY:不需要对数据包计算校验和,这个值一般用于lookback设备

CHECKSUM_COMPLETE:网络硬件具有计算校验和的功能。

CHECKSUM_PARITAL:针对输出数据包,要求设备对有hard_start_xmit函数发送的数据包做校验和,教养和的范围从csum_start指明的地址起始到数据包结束处,校验和存放在csum_start+csum_offset的地址。

__u32 priority:

        priority数据域是用来实现质量服务(Quality of service)QoS功能特性的。QoS描述了数据包传送的优先级别。例如网络视频数据、语音数据需要QoS以保证视频、语音的流畅。

__be16 protocol:

        接收数据包的网络层协议(如IP协议)。它标志了网络数据包应传给TCP/IP协议栈网络层的哪个协议处理函数。protocol域协议的完整定义在include/linux/if_ether.h头文件中。该域是由网络适配器的驱动程序调用相关函数来填写的。

__u16 vlan_tci:

        虚拟局域网的标记控制信息(Vlan Tag Control Information)。

sk_buff_data_t transport_header,

sk_buff_data_t network_header,

sk_buff_data_t mac_header:

        以上3个域是sk_buff结构中描述Linux内核网络协议栈中各层协议头在网络数据包的位置信息。他们含义如下,transport_header表示传输层协议头在网络数据包中的地址;network_header编号网络协议头在网络数据包中的地址;mac_header表示数据链路层协议头在网络数据包中的地址。

        在64位系统中,这3个协议值表示相应的协议头在网络数据包中的地址是以skb->head为起始的偏移量,在32位系统中,sk_buff_data_t的类型就为指针,存放各层协议头在网络数据包中的起始地址。 如下:

// include/linux/skbuff.h
#if BITS_PER_LONG > 32
#define NET_SKBUFF_DATA_USES_OFFSET 1
#endif

#ifdef NET_SKBUFF_DATA_USES_OFFSET
typedef unsigned int sk_buff_data_t;
#else
typedef unsigned char *sk_buff_data_t;
#endif

三. 总结

        本文主要学习了struct sk_buff结构的一些字段的含义和用途,为后续的网络协议栈的学习打好基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cocos2d-x4.0 win10环境搭建

cocos2d-x默认只支持win32的版本,win64的我测试link不行 我搭建使用的环境 windows10vs2019py2.7cmake3 从GitHub上clone源码https://github.com/cocos2d/cocos2d-x coco2d-x默认带了submodule,有协同子模块,最好是一起下载,搞个…

国内知名插画培训机构有哪些

国内知名插画培训机构有哪些?给大家梳理了国内5家专业的插画师培训班,最新无大插画班排行榜,各有优势和特色! 一:国内知名插画培训机构排名 1、轻微课(五颗星) 主打课程有日系插画、游戏原画、古…

MYSQL 配置优化

max_connections 允许客户端并发连接的最大数量,默认值是151。 show status like %connections%; 设置参数值应大于Max_used_connections。如果使用连接池,可参考连接池的最大连接数和每个连接池的数量作为参考设置 innodb_buffe_pool_instances Inno…

【华为云-开发者专属集市】DevCloud+ECS、MySQL搭建WordPress

文章目录AppBazaar官网选择与购买项目项目概况操作过程购买DevCloud服务创建项目添加制品库应用部署购买ECS添加部署模板并执行任务故障排除安装及访问WordPress登录网站管理后台访问网站完善部署模板资源释放使用总结AppBazaar官网 首先,我们来到AppBazaar的官网&…

【Kubernetes】【十五】Service详解 Service介绍 类型 使用

第七章 Service详解 本章节主要介绍kubernetes的流量负载组件:Service和Ingress。 Service介绍 ​ 在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着…

数据库必知必会:TiDB(11)TiDB集群安装

数据库必知必会:TiDB(11)TiDB集群安装TiDB集群安装单机环境上安装集群下载并安装TiUP工具安装TiUP cluster组件创建拓扑文件配置SSH免密登录检查安装要求创建安装目录部署集群启动集群验证集群启动使用命令验证通过Dashboard查看通过Grafana查…

2023年1月冰箱品牌销量排行:销量环比增长26%,销售额36亿+

鲸参谋电商大数据2023年1月京东平台“冰箱”销售数据出炉! 根据鲸参谋平台电商数据显示,2023年1月份,在京东平台上,冰箱的销量将近130万件,环比增长26%,同比下滑8%;销售额达36亿,环比…

嵌入式开发:C++在深度嵌入式系统中的应用

深度嵌入式系统通常在C语言中实现。为什么会这样?这样的系统是否也能从C中获益?嵌入式开发人员在将广泛、高效的深度嵌入式代码库从C转换为C方面的实践经验的贡献。嵌入式和深度嵌入式系统通常用C而不是C实现。软件开发人员必须放弃C作为强类型系统、模板元编程(TMP)和面向对…

dubbo整合nacos进行远程调用

doubbo是什么? Apache Dubbo 最初在 2008 年由 Alibaba 捐献开源,很快成为了国内开源服务框架选型的事实标准框架 ,得到了各行各业的广泛应用。在 2017 年,Dubbo 正式捐献到 Apache 软件基金会并成为 Apache 顶级项目&#xff0c…

DJI 无人机 Onboard SDK ROS 功能包demo运行

DJI 无人机 Onboard SDK ROS 功能包demo运行demo功能准备测试环境运行 dji sdk 节点运行 demo 节点自动飞行任务航点自动飞行兴趣点环绕自动飞行飞行控制本地坐标位置控制搭建好 Onboard SDK ROS 的开发环境后,功能包自身具备一些写好的demo功能案例 dji sdk 的节点…

华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】

使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12201821.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 猴子爬山 | 华为OD机…

特征工程-定义+意义+安装scikit-learn+数据的特征抽取(字典、文本)

目录 数据中对特征的处理 特征工程定义 特征工程意义 安装scikit-learn 数据的特征抽取 字典特征抽取 DictVectorizer语法 文本特征抽取 CountVectorizer语法 TfidfVectorizer语法 数据中对特征的处理 pandas:一个数据读取非常方便以及基础的处理格式的工具 sklear…

Spring Boot + Vue3 前后端分离 实战 wiki 知识库系统<一>---Spring Boot项目搭建

前言: 接下来又得被迫开启新的一门课程的学习了,上半年末尾淘汰又即将拉开序幕【已经记不清经历过多少次考试了】,需要去学习其它领域的技术作为考试内容,我选了spring boot相关技术,所以。。总之作为男人&#xff0c…

Linux之网络流量监控工具ntopng YUM安装

一、ntopng简介 Ntop是一种监控网络流量工具,用ntop显示网络的使用情况比其他一些网络管理软件更加直观、详细。Ntop甚至可以列出每个节点计算机的网络带宽利用率。他是一个灵活的、功能齐全的,用来监控和解决局域网问题的工具;尤其当ntop与n…

【Spring Cloud Alibaba】003-Nacos 概述与单机搭建

【Spring Cloud Alibaba】003-Nacos 概述与单机搭建 文章目录【Spring Cloud Alibaba】003-Nacos 概述与单机搭建一、Nacos 概述0、新技术学习思路推荐1、什么是 Nacos2、架构图架构图架构图信息二、Nacos 单机搭建1、下载与启动下载地址编辑 startup.cmd 文件下面对两种模式的…

“王炸”产品+集资2000万美元,D-Wave在赌什么?

(图片来源:网络)D-Wave是量子计算系统、软件和服务的领导者,也是全球量子计算机商业供应商。近日,它发布了一系列的最新产品和业务,展示出其在推动量子计算商业化方面的强劲势头。随着全球越来越多的企业将…

C++入门:内联函数、auto关键字、基于范围for循环及指针空值nullptr

目录 一. 内联函数 1.1 内联函数的概念 1.2 内联函数的特性 1.3 内联函数和宏的优缺点对比 二. auto关键字(C11) 2.1 auto的功能 2.2 auto在使用时的注意事项 三. 基于范围的for循环(C11) 四. 指针空值nullptr&#xff08…

开发日记-lombok

开发日记-lombok环境问题解决方案:1 Data注解失效 无法正常生成 get和set方法2 RequiredArgsConstructor(onConstructor _(Lazy)) 符号_无法识别环境 idea2020.1lombok1.18.24jdk1.8 问题 Data注解失效 无法正常生成 get和set方法RequiredArgsConstructor(onCons…

机器学习:学习k-近邻(KNN)模型建立、使用和评价

机器学习:学习k-近邻(KNN)模型建立、使用和评价 文章目录机器学习:学习k-近邻(KNN)模型建立、使用和评价一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.数据读取2.数据理解3.数据准备4.算…

Talk预告 | 悉尼科技大学澳大利亚人工智能研究所讲师方震:广义分布外检测的学习理论

本期为TechBeat人工智能社区第476期线上Talk! 北京时间2月22日(周三)20:00,悉尼科技大学澳大利亚人工智能研究所讲师——方震的Talk将准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “广义分布外检测的学习理论”,届时将…