内核协议栈-2

先贴出关于linux内核数据结构之链表部分。list.h完全注释。

先复习下:
上次说了net_device这一个结构
相当于是说了物理设备层,这里有必要说明一下net_device和驱动程序的关系。
net_device中包含了各种用于发送接收设备的函数指针,这些函数指针指向驱动
程序中那些你自己设计编写的发送和接收的函数,驱动程序就是直接来对物理设备
寄存器进行操作的,所以这里理清这个思路,上层的N个协议将数据包好之后,通过
网络设备来调用驱动程序的发送函数,将数据包发送出去,那应该是你现在脑海中
对协议栈的理解了。至于以后的工作就是慢慢深入协议内部进行了。

下面我们说说接口层,按照的是从底向上的方式来说的,先说说数据包的接收过程。
当数据包到达网络设备的时候可以通过两种方式来接收数据

一种方法是轮询。驱动程序定期检查是否有数据报到达网络设备,当然这个查询时间
周期不太好确定,需要折中,
还一种方法是中断,驱动程序为数据包的到达设置好中断处理程序,数据包到达后会
出发中断,由中断程序来接收数据包,这种方式比轮询要好一些诶,

一种折中的方式叫做NAPI方式,它是中断机制和轮询机制的混合体,能有效的提高
网络处理速度,在网络负荷比较中的时候,NAPI技术能显著减少由于接收数据报而
产生的硬中断数量,对高速率,短长度的数据报十分有效

其实现的方法: 当第一笔数据包中的第一个到达网络设备时,会以硬中断的方式通知
系统,在硬中断响应函数中,系统将该设备添加到CPU的设备轮询队列之中,并关闭
中断,同时激活数据报软中断,由软中断处理程序遍历轮询队列之中的网络设备,从
中读取数据报。当程序在从网络设备接收报文的时候,若有新的报文到来,NAPI无需
再执行硬中断程序,只需维护网络设备轮询队列,就能读取新到来的报文。当设备全部
读取完成后,再打开中断。

于是,通过上面的这种方式就完成了数据包到内核的一个过程,当然这只是漫长旅途的
一个开始,下面开始第一个数据结构。

1. softnet_data , 它描述了与网络软中断处理相关的报文输入和输出队列,每个
CPU有一个单独的softnet_data实力,因此在操作该成员的时候不必加锁,这个结构
是一个承上启下的作用。它主要包含:
-----------------1. 非NAPI接口层缓存队列(input_pkt_queue),
对于不是NAPI的驱动,通常在硬中断中或通过轮询读取报文后,调用netif_rx将接收
到的报文传递到上层,所以先将报文缓存到这个队列中,然后产生一个数据包输入软中
断,由软中断处理程序将报文传递到上层。

-----------------2. 网络设备轮询队列: NAPI的驱动,处于报文接收状态的设备链接到该队列上,在数
据包输入软中断中,会遍历该队列,以轮询的方式接收报文。


2. 上面的结构就是数据SKB缓存的地方,softnet_data,每个CPU有一个,数据进
入内核存下了,下面就该往上传递了,往上应该是网络层,在往上层传递中,又需要有
一个关键的结构packet_type。中文名称叫报文接收例程,每个协议族都会实现一个
报文例程。当数据到达时,会根据报文类型调用相应的网络层接收处理函数。对应的
函数指针就存在这个结构之中,该结构还有一个type类型,由这个来确定调用哪个
packet_type的处理函数,那么内核之中应该是会有很多的这中packet_type了,它们
如何进行组织呢,答案就是前面注释过的散列表了。嘿嘿。总算用上了。这样就通过
这两个结构将数据交到了网络层。

posted @ 2012-07-04 13:48  熊猫基地  阅读(180)  评论(0编辑  收藏  举报