分类: LINUX
2010-07-29 11:00:38
24.8 接收过程的实现
接收函数一般由中断控制程序调用,负责把网络设备接收到的数据以一定格式提交给内核中的网络层模块。在具体介绍接收函数前先简单介绍一下sk_buff结构。
24.8.1 sk_buff结构
sk_buff是Linux网络协议栈中一个重要数据结构,网络协议栈中的各层协议都可以通过对它的操作实现本层协议数据的添加或者数据提取,这种机制避免了协议数据单元在不同的协议层间被来回复制情况的发生,提高了执行效率。内核在各协议层都提供一系列函数对此结构进行操作。如图24-4所示为sk_buff结构的示意图。
sk_buff的数据分成两大部分,一部分是实际在网络中要传输的部分,图中表示为Packet date storage部分,这就是常说的数据区。另一部分是用于内核进行管理的部分。在此着重介绍要用到的几个域段。其中有四个数据指针指向数据区相应的位置。
unsigned char *head:指向被分配的内存空间的首地址;
unsigned char *data:指向当前数据包的首地址;
unsigned char *tail:指向当前数据包的末地址;
unsigned char *end:指向被分配的内存空间的末地址;
(点击查看大图)图24-4 sk_buff结构 |
unsigned long len:当前数据包的大小。len=skb->tail - skb->data;
unsigned long truesize:分配到的内存空间大小。len=skb->end - skb->head;
struct net_device *dev:接收或者发送该数据包的网络设备;
unsigned short:protocol给数据包使用的网络层协议。
由于数据包的大小会随着自己在不同协议层间的传送而不断地变化,故data和tail指针也将会不断地改变,即依赖于sk_buff当前所在的协议层;head和end指针则在内存空间分配后就固定不变。
对sk_buff缓冲区的操作,核心提供了一个比较完整的函数界面,下面将列出用得最多的几个函数并作分析说明。
struct sk_buff*alloc_skb (unsigned int len, int priority); |
void kfree_skb (struct sk_buff*skb, int rw); |
unsigned char *skb_put (struct sk_buff*skb, int len); |
unsigned char *skb_push (struct sk_buff*skb, int len); |
int skb_tailroom (struct sk_buff*skb); |
int skb_headroom (struct sk_buff*skb); |
void skb_reserve (struct sk_buff*skb, int len); |
unsigned char *skb_pull (struct sk_buff*skb, int len); |
void skb_trim(struct sk_buff*skb, int len) |