购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.2 Socket Buffer的构成

Linux内核网络子系统的设计目标是使网络子系统的实现独立于特定的网络协议,这一设计目的不仅适用于网络层和传输层的协议(TCP/IP、IPX/SPX等),也适用于网络适配器所采用的协议(Ethernet、token ring 等)。其他的网络协议不需做大的改动就能直接加入到TCP/IP协议栈的任何层次中。本章要讨论的内容的源代码都在以下目录中。

文件路径

Socket Buffer的完整定义在Linux源文件的目录树: include/linux/草纲目skbuff.h 文件中。

Socket Buffer 的构成如图2-2 所示。

图2-2 Socket Buffer 的构成示意图

2.2.1 Socket Buffer的基本组成

一个完整的Socket Buffer 主要由两个实体组成。

● 数据包:存放实际要在网络中传送的数据缓冲区。

● 管理数据结构(struct sk_buff):当在内核中处理数据包时,内核还需要一些其他的数据来管理数据包和操作数据包,例如数据接收/发送的时间、状态等。这些信息是不需要向外发送的,所以不存放在数据包中。

数据包与sk_buff 的关系就好比信件与信封的关系一样,信件是你要传递给他人的信息内容,信封告诉邮局如何将信件传到目的地。

在本书中,如果我们提到的是数据包和管理数据结构的整体,会用Socket Buffer来描述;如果只是管理数据结构,会以sk_buff来说明。

2.2.2 Socket Buffer穿越TCP/IP协议栈

网络数据包在TCP/IP协议栈各层传送时,以上两个实体——数据包与管理数据结构的内容会不断发生变化。

1.发送网络数据包

例如,当网络应用数据从用户地址空间复制到内核地址空间时,在内核的套接字层会创建相应的Socket Buffer实例来将负载数据存放在数据包缓冲区中。数据包的地址、长度、状态等信息存放在sk_buff结构中。在Socket Buffer 由上向下穿越TCP/IP协议栈的各层期间会发生如下事件。

● 各层协议的头信息会不断插入到数据包中。

● 相应的,在sk_buff结构中描述协议头信息的地址指针会被赋值。

所以,创建Socket Buffer时需要在数据包缓冲区前留出足够的空间来存放各层协议的头信息。

2. 接收网络数据包

网络适配器接收到发给本机的网络数据后,首先产生中断通知内核收到了网络数据帧。接着在网络适配器的中断处理程序中调用dev_alloc_skb函数向系统申请一个SocketBuffer,将接收到的网络数据帧从设备硬件的缓冲区复制到Socket Buffer 的数据包缓冲区;填写sk_buff结构中的地址、接收时间和协议等信息。

这时:Socket Buffer到达了内核地址空间。当Socket Buffer由下向上穿越TCP/IP协议栈的各层时将发生如下事件。

● 各层协议的头信息会不断从数据包中去掉。

● 相应的在sk_buff结构中描述头信息的地址指针会被复位,并调整sk_buff结构中

指向有效数据的sk_buff->data指针。

图2-3给出了Socket Buffer 在传送过程中的变化示意图。

图2-3 网络数据包在TCP/IP协议栈的传送示意图

3. 设计优点

Socket Buffer 这样组织的优点是避免了重复复制数据,要传送的数据只需复制两次:一次是从应用程序的用户地址空间复制到内核地址空间;一次是从内核地址空间复制到网络适配器的硬件缓冲区中。 7MCwR0vt7iEj3Vx0DzJLS7X5C78RGcmPgILgH0fDZ0gzvCXaWBI0YzFvg8uFUeFA

点击中间区域
呼出菜单
上一章
目录
下一章
×