1 / 23
文档名称:

报文缓存.pdf

格式:pdf   页数:23页
下载后只包含 1 个 PDF 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

报文缓存.pdf

上传人:bjy0415 2015/9/18 文件大小:0 KB

下载得到文件列表

报文缓存.pdf

文档介绍

文档介绍:Linux 内核网络实现分析文档密级

第二章报文缓存
1 概述
Linux内核网络设计实现里面有一个很重要的数据结构,就是sk_buff结构。读过《 TCP/IP
详解(第二卷)》的读者对BSD系统的mbuf数据结构一定不陌生。sk_buff的作用类似于mbuf,
但是远比mbuf的作用大。像其它很多系统和网络理论一样,Linux内核实现也是采用分层的
思想进行设计,分为链路层、网络层、传输层、应用层等,sk_buff就像一根纽带,将各个
网络层串连起来。所以要掌握Linux内核网络实现原理,sk_buff数据结构是入门的第一课。
网上也经常看到有关于论sk_buff机制和mbuf机制优劣的讨论。其实二者都在它们各自
的设计思想里面担当着相同的角色。笔者认为,sk_buff至少在以下方面比mbuf强:速度、
效率、伸缩性、内存转换,sk_buff的安全也好做一点,但是空间利用率可能不比mbuf强。
sk_buff结构就是这样一个平衡速度、效率的产物。下面我们就这个问题进一步讨论一下,
不熟悉mbuf的朋友可以跳过下面一段。
首先,Linux的sk_buff结构将整个报文放到一个单独的结构中,而mbuf结构则不然,它
采用128、1024、2048这样2的幂次递增链表的形式。所以,Linux没有报文链,不需要mbuf
的m_pullup这样的函数用来保证指定数目的字节在链表的第一个mbuf中紧挨着存放。
m_pullup有一个内存整理的过程,所以在速度上比不上sk_buff。
另外一方面,在接受和发送报文时,Linux总是申请一整块内存空间放到一个独立的结
构中,所以不需要像mbuf一样将报文划分成128、104、2048大小的块,所以,它应该更快。
另外,sk_buff有更多的指针,使得协议回溯、向前查找都可以直接进行。
但式,Linux的缺点也是明显的,首先,代码过于复杂,将简单的事情复杂化,尤其是
它的共享缓存部分。另外,sk_buff结构过于庞大,发送一个小报文申请的头结构大小可能
是数据体的几倍,但是下面会讲道,内核开发者会规避这个问题。 Linux还会需要牺牲一部
分空间,而不管真实的需求,尤其是在发送报文TCP报文时,不管应用层的数据大小是多少,
它的起点就是272个字节。
下面我们看看sk_buff结构的生命线。
当一个数据包被网卡接收到后,网卡驱动就会申请一个sk_buff结构,然后将数据部分
2004-01-02 保留所有权利陈国强 第 1 页, 共 23 页


PDF created with pdfFactory Pro trial version
Linux 内核网络实现分析文档密级

拷贝到sk_buff结构里,并且将与链路层相关的一下信息设置好,交给网络层处理。网络层、
传输层根据sk_buff的信息实现相应层次协议。一般地,当数据包被传输层的协议接收到后,
Socket接口将sk_buff中的数据拷贝到应用层的数据缓存区,这时候sk_buff的生命就结束了,
被释放掉。
对应地,当应用层发送数据时,也是在网络协议族提供的接口函数里,申请一个sk_buff
结构,将数据拷贝到这个结构里,然后sk_buff通过传输层、应用层最后达到链路层,里面
内容被一部分一部分地设置。当sk_buff结构达到网卡驱动程序时,里面包含足够二层路由
信息,数据部分也是一个完整的数据包。
从上所述,sk_buff结构最常见的起点和终点在网卡驱动接收函数和Socket的应用层接口
(sock->prot->sendmsg)这两个点上。当然Linux真正的实现远比这个复杂,包括各种各样
复制的技巧,比如克隆、共享数据、共享SKB等等。但是掌握基本的sk_buff生命线有利于理
解这个结构,尤其对于初学者。
为了解释sk_buff结构的意义,牵涉代码的面积很广泛。在理解sk_buff结构时不要过多
的纠缠于代码,笔者整理的代码都是为了解释sk_buff含义而引用的例子,如果不理解可以
慢慢琢磨。sk_buff中还定义了流量控制等高级技术,这里不做讨论。
另外,在内核里面还有一个与报文缓存相关的结构就是msghdr,内核通过插口I/O机制
将数据提交给用户层空间时、同时用户层空间将数据发送给内核时,都是通过msghdr来完成
的,所以sk_buff只是在内核空间使用的一个结构。至于为什么要使用量套数据,主要是为
了兼容,因为msghdr是POSIX 标准里面定义的一个结构,Linux有些代码