当前位置:文档之家› 网络协议栈

网络协议栈

《嵌入式操作系统VxWorks中网络协议存储池原理及实现》

周卫东蔺妍刘利强

(哈尔滨工程大学自动化学院,黑龙江哈尔滨,150001)

摘要本文讨论了网络协议存储池的基本原理和在嵌入式操作系统中的实现方法。为在嵌入式系统中实现TCP/IP协议栈,提供了一种有效、简洁、可靠的缓冲区管理。

关键词 VxWorks; mBlk; clBlk; 网络协议存储池

VxWorks操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS)。它以良好的持续发展能力、高性能的内核以及卓越的实时性被广泛的应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中。VxWorks操作系统有着优越的网络性能,而缓冲区的数据拷贝是影响网络性能的主要因素。

众所周知,缓冲区在网络协议栈中有两个作用:第一,提供载体,使分组或报文可以在各协议层中流动;第二,为各级缓冲区提供空间。缓冲区的设立使得 TCP/IP协议栈支持异步I/O操作,异步操作对于协议栈的I/0性能是非常重要的。在网络输出的过程中每一层需要在数据的首部或者尾部添加数据头和数据尾来对数据进行封装使得接收端对应的层能够进行正确的接收,在输入的过程中每层都需要将本层的数据头和数据尾去掉而最终还原成发送端发送的

数据。上述的封装/去封装和拷贝操作使得网络协议对内核的存储器管理能力提出了很多要求。这些要求包括能方便地操作可变长缓存,能在缓存头部和尾部添加数据(如低层封装来自高层的数据),能从缓存中移去数据(如当数据包向上经过协议栈时要去掉首部),并能尽量减少这些操作所作的数据复制。

1 使用netBufLib管理存储池的基本原理

网络协议存储池使用mBlk结构、clBlk结构、簇缓冲区和netBufLib提供的函数进行组织和管理。mBlk和clBlk结构为簇缓冲区(cluster)中数据的缓冲共享和缓冲链接提供必要的信息。netBufLib例程使用mBlk和clBlk来管理cluster和引用 cluster中的数据,这些结构体中的信息用于管理cluster 中的数据并且允许他们通过引用的形式来实现数据共享,从而达到数据“零拷贝”的目的。

1.1 结构体mBlk和clBlk及其数据结构

mBlk是访问存储在内存池中数据的最基本对象,由于mBlk仅仅只是通过clBlk来引用数据,这使得网络层在交换数据时就可以避免数据复制。只需把一个mBlk连到相应mBlk链上就可以存储和交换任意多的数据。一个mBlk结构

体包括两个成员变量mNext和mNextPkt,由它们来组成纵横两个链表:mNext 来组成横的链表,这个链表中的所有结点构成一个包(packet);mNextPkt来组成纵的链表,这个链表中的每个结点就是一个包 (packet),所有的结点链在一起构成一个包队列,如图1所示。

图1 包含两个数据包的mBlk链

结构体mBlk和clBlk的数据结构如下所示:

struct mBlk

{

M_BLK_HDR mBlkHdr; /* header */

M_PKT_HDR mBlkPktHdr; /* pkthdr */

CL_BLK * pClBlk; /* pointer to cluster blk */

} M_BLK;

struct clBlk

{

CL_BLK_LIST clNode;/* union of next clBlk */

UINT clSize;/* cluster size */

int clRefCnt;/*countof the cluster */

struct netPool * pNetPool; /* pointer to the netPool */

} CL_BLK;

/* header at beginning of each mBlk */

struct mHdr

{

struct mBlk * mNext;/* next buffer in chain */

struct mBlk * mNextPkt;/* next chain in queue/record */

char *mData; /* location of data */

int mLen;/* amount of data in this mBlk */

UCHAR mType;/* type of data in this mBlk */

UCHAR mFlags; /* flags; see below */ } M_BLK_HDR;

/* record/packet header in first mBlk of chain; valid if M_PKTHDR set */ struct pktHdr

{

struct ifnet * rcvif;/* rcv interface */

int len; /* total packet length */ } M_PKT_HDR;

1.2 网络协议存储池的初始化

VxWorks在网络初始化时给网络协议分配存储池并调用netPoolInit()函数对其初始化,由于一个网络协议通常需要不同大小的簇,因此它的存储池也必须包含很多簇池(每一个簇池对应一个大小的簇)。如图2所示。另外,每个簇的大小必须为2的方幂,最大可为64KB(65536),存储池的常用簇的大小为64,128,256,512,1024比特,簇的大小是否有效取决于CL_DESC表中的相关内容,CL_DESC表是由 netPoolInit()函数调用设定的。

图2 网络协议存储池初始化后的结构

1.3 存储池的链接及释放

存储池在初始化后,由netPool结构组织几个下一级子池:一个mBlk 池、一个clBlk池和一个cluster池。mBlk池就是由很多mBlk组成的一条mBlk 链;clBlk池就是由很多clBlk组成的一条clBlk链。cluster池由很多的更下一级cluster子池构成,每一个 cluster子池就是一个cluster链。每一个cluster链中的所有cluster的大小相同,不同链中的cluster大小不同。但要实现不同进程访问同一簇而不需要作数据的拷贝,还需要把mBlk结构,clBlk 结构和簇结构链接在一起。创建这三级结构一般要遵循这样五步:

a.调用系统函数netClusterGet()预定一块簇缓冲区;

b.调用系统函数netClBlkGet()预定一个clBlk结构;

c.调用系统函数netMblkGet()预定一个mBlk结构;

d.调用系统函数netClBlkJoin()把簇添加到clBlk结构中;

相关主题