1.前言
在互联网技术里,有两件事最为重要,一个是 TCP/IP 协议,它是万物互联的事实标准;另一个是 Linux 操作系统,它是推动互联网技术走向繁荣的基石。在 Linux内核的协议栈中的实现中,数据结构skb_buff是最关键和最核心的数据,它表示接收或发送数据包的包头信息,并包含很多成员变量供网络代码中的各子系统使用。本文以及后续关于skb_buff的介绍,均来源于经典著作《深入理解linux网络技术内幕》和《linux内核源码剖析:TCP/IP实现》。

2.skb_buff基本原理
内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体,而是通过增加协议头和移动指针来操作的。如果是从L4传输到L2,则是通过往sk_buff结构体中增加该层协议头来操作;如果是从L4到L2,则是通过移动sk_buff结构体中的data指针来实现,不会删除各层协议头,这样方式极大的提高CPU工作效率。

sk_buff结构体是linux网络代码中最重要的数据结构,是整个网络传输载体。所以sk_buff结构体里面有很多关于其他功能的成员字段,比如:防火墙,子路由系统,多播等。这些字段并不是一定有的,只有在满足特点条件才有的。所以可以在需要时候再去关心这些成员字段,现在我们只来讲解主要的成员字段。
3.skb_buff主要字段
为了好理解结构中的一些成员字段,先把后面要讲的内容提前说下。sk_buff结构体关联多个其他结构体,主要可以分为:
第一是数据区:由sk_buff中head和end指向的数据块,用来存储sk_buff结构的数据也即是存储数据包的内容和各层协议头。
第二是分片结构:用来表示IP分片的一个结构体,实则上是和sk_buff结构的数据区相连的,即是end指针的下一个字节开始就是分片结构。正因此,分片结构和sk_buff数据区内存分配及销毁时都是一起的。
第三个是分片结构指向的数据区,即是IP分片内容。
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next; // 因为sk_buff结构体是双链表,所以有前驱后继。这是个指向后面的sk_buff结构体指针
struct sk_buff *prev; // 这是指向前一个sk_buff结构体指针
//老版本(2.6以前)应该还有个字段: sk_buff_head *list //即每个sk_buff结构都有个指针指向头节点
struct sock *sk; // 指向拥有此缓冲的套接字sock结构体,即:宿主传输控制模块
ktime_t tstamp; // 时间戳,表示这个skb的接收到的时间,一般是在包从驱动中往二层发送的接口函数中设置
struct net_device *dev; // 表示一个网络设备,当skb为输出/输入时,dev表示要输出/输入到的设备
unsigned long _skb_ds

本文深入解析Linux内核中skb_buff结构体,它是网络传输的核心数据结构。文章详细介绍了skb_buff的基本原理,包括其如何在各层协议间高效传输,以及其主要字段的作用,如数据区、分片结构、协议头和尾、控制信息等。
最低0.47元/天 解锁文章
681





