sk_buff结构体成员变量说明
一. 前言
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结构的一些字段的含义和用途,为后续的网络协议栈的学习打好基础。
相关文章:
sk_buff结构体成员变量说明
一. 前言 Socket Buffer的数据包在穿越内核空间的TCP/IP协议栈过程中,数据内容不会被修改,只是数据包缓冲区中的协议头信息发生变化。大量操作都是围绕sk_buff结构体来进行的。 sk_buff结构的成员大致分为3类:结构管理域,常规数据…...
springbatch设置throttle-limit参数不生效
背景描述 当springbatch任务处理缓慢时,就需要使用多线程并行处理任务。 参数throttle-limit用于控制当前任务能够使用的线程数的最大值。 调整throttle-limit为10时,处理线程只有8,再次增大throttle-limit值为20,处理线程依旧为…...
用 tensorflow.js 做了一个动漫分类的功能(一)
前言:浏览某乎网站时发现了一个分享各种图片的博主,于是我顺手就保存了一些。但是一张一张的保存实在太麻烦了,于是我就想要某虫的手段来处理。这样保存的确是很快,但是他不识图片内容,最近又看了 mobileNet 的预训练模…...
看完这篇Vue-element-admin,跟面试官聊骚没问题
Vue-element-admin vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。它使用了最新的前端技术栈,内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富…...
2022年全国职业院校技能大赛(中职组)网络安全竞赛试题A(5)
目录 模块A 基础设施设置与安全加固 一、项目和任务描述: 二、服务器环境说明 三、具体任务(每个任务得分以电子答题卡为准) A-1任务一 登录安全加固(Windows) 1.密码策略 a.密码策略必须同时满足大小写字母、数…...
基于Java+SpringBoot+Vue+Uniapp前后端分离商城系统设计与实现
博主介绍:✌全网粉丝3W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战✌ 博主作品:《微服务实战》专栏是本人的实战经验总结,《Spring家族及…...
新建ES别名 添加别名 切换别名
# 查询别名指向到哪个索引 GET bebd_factory_search/_alias # 查询这个索引使用了什么别名 GET bebd_factory_search_1588250935622/_alias # 删除索引 DELETE bebd_factory_search_1588250935622 # 新建别名 POST /_aliases { "actions": [ { "ad…...
MySQL —— 内外连接
目录 表的内外连接 一、内连接 二、外连接 1. 左外连接 2. 右外连接 表的内外连接 表的连接分为内连和外连 一、内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面博客中的查询都是内连接,也是在开发过程中使用的最多…...
EXCEL中文本和数字的相互转换方法
将EXCEL中存为文本的数字转换成数字 如果在 Excel 中,将数字存储为文本格式,可以通过以下步骤将其转换为数字: 选中需要转换格式的单元格或者整列;右键单击,选择“格式单元格”;在弹出的对话框中选择“常…...
React源码分析6-hooks源码
本文将讲解 hooks 的执行过程以及常用的 hooks 的源码。 hooks 相关数据结构 要理解 hooks 的执行过程,首先想要大家对 hooks 相关的数据结构有所了解,便于后面大家顺畅地阅读代码。 Hook 每一个 hooks 方法都会生成一个类型为 Hook 的对象ÿ…...
Windows10神州网信政府版麦克风、摄像头的使用
Windows10神州网信政府版默认麦克风摄像头是禁用状态,此禁用状态符合版本规定。 在录课和直播过程中,如果需要使用麦克风和摄像头的功能,可以这样更改: 1、鼠标右键点击屏幕左下角的开始菜单图标,选择windows中的“运…...
微机原理学习总结0:前言
近期结束了微机课程的学习,(指刚考完试),正常情况下,后面应该不会再接触这门课程了,故在此记录自己这段时间的收获。 首先,十分推荐b站的一门课程,老师讲的很细致,很适合…...
LeetCode 1828. 统计一个圆中点的数目
给你一个数组 points ,其中 points[i] [xi, yi] ,表示第 i 个点在二维平面上的坐标。多个点可能会有 相同 的坐标。 同时给你一个数组 queries ,其中 queries[j] [xj, yj, rj] ,表示一个圆心在 (xj, yj) 且半径为 rj 的圆。 对…...
Spring Boot + Vue3 前后端分离 实战 wiki 知识库系统<一>---Spring Boot项目搭建
前言: 接下来又得被迫开启新的一门课程的学习了,上半年末尾淘汰又即将拉开序幕【已经记不清经历过多少次考试了】,需要去学习其它领域的技术作为考试内容,我选了spring boot相关技术,所以。。总之作为男人,…...
leetcode 11~20 学习经历
LeetCode 习题 11 - 2011. 盛最多水的容器12. 整数转罗马数字13. 罗马数字转整数14. 最长公共前缀15. 三数之和16. 最接近的三数之和17. 电话号码的字母组合18. 四数之和19. 删除链表的倒数第 N 个结点20. 有效的括号小结11. 盛最多水的容器 给定一个长度为 n 的整数数组 heigh…...
LeetCode 双周赛 98,脑筋急转弯转不过来!
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 昨晚是 LeetCode 第 98 场双周赛,你参加了吗?这场周赛需要脑筋急转弯,转不过来 Medium 就会变成 Hard&#…...
函数的栈帧的创建和销毁
文章目录本章主题:一.什么是函数栈帧1.什么是栈2.什么是函数栈帧二.理解函数栈帧能解决什么问题呢?三.函数栈帧的创建和销毁解析1.预备知识(1) 认识相关寄存器和汇编指令(2)栈帧空间的维护2.解析函数栈帧的…...
python filtermapreducezip
一、filter 过滤 filter 过滤, 从可迭代对象中,筛选出满足条件的元素,再将这些满足条件的元素,组成一个新的可迭代对象。 方式一:filter(过滤方法,可迭代对象) 举例:将一个list中…...
Centos7搭建hadoop3.3.4分布式集群
文章目录1、背景2、集群规划2.1 hdfs集群规划2.2 yarn集群规划3、集群搭建步骤3.1 安装JDK3.2 修改主机名和host映射3.3 配置时间同步3.4 关闭防火墙3.5 配置ssh免密登录3.5.1 新建hadoop部署用户3.5.2 配置hadoopdeploy用户到任意一台机器都免密登录3.7 配置hadoop3.7.1 创建目…...
骨传导耳机工作原理,骨传导耳机优缺点
骨传导耳机虽说最近是十分火爆的一款单品,但还是有很多人对骨传导耳机不是很了解,骨传导耳机更多使用场景还是在户外运动使用,骨传导耳机对于长时间使用耳机的人来说十分友好,这主要还是得益于骨传导耳机传输声音的特殊性。 下面我…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
webpack面试题
面试题:webpack介绍和简单使用 一、webpack(模块化打包工具)1. webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖文件,使用loaders来处理它们&#x…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
