网络层次
linux网络设备驱动与字符设备和块设备有很大的不同。
1. 字符设备和块设备对应/dev下的一个设备文件。而网络设备不存在这样的设备文件。网络设备使用套接字socket访问,虽然也使用read,write系统调用,但这些调用只作用于软件对象。
2. 块设备只响应来自内核的请求,而网络驱动程序异步接收来自外部世界的数据包,并向内核请求发送到内核。
linux内核中网络子系统的设计基于设备无关及协议无关思想。即无论什么网卡驱动、网络协议,都对应统一的驱动程序。
inux网络协议栈层次有四层:
网络协议接口层
网络设备接口层
设备驱动功能层
网络设备媒介层
下面只分析下linux是如何实现网络设备的设备无关性及协议无关性。
网络协议接口层: 给上层协议提供透明的数据包发送和接收接口。与协议无关
当要发送数据包时,ARP协议或者IP协议,都将调用这一层中的dev_queue_xmit()函数发送该数据包。
上层对数据包的接收时,通过netif_rx()接收。具体协议处理在上级网络协议处理。
这其中需要一个很重要的结构体struct sk_buff.
网络设备接口层:为千变万化的网络设备定义统一、抽象的数据结构net_device结构体,实现多种硬件在软件层次上的统一。与设备无关。
net_device结构体在内核中指代一个网络设备,网络设备驱动程序只需通过填充net_device中的具体成员并注册net_device即可实现硬件操作函数与内核的挂接。使用统一的注册、注销及初始化等一系列函数。
设备驱动功能层:填充net_device中的成员。管理物理网络设备。
包括设备打开、停止、传输等操作。由于网络包得接收可以由中断产生,所以设备驱动功能层中另一个主题部分是中断处理函数,负责读取硬件上接收的数据包并传送给上层协议。
网络设备与媒介层:对应于实际的物理设备
包括设备寄存器的描述,寄存器读写函数等。
网络协议
这里主要进行数据包的收发,使用函数原型为:
dev_queue_xmit(struct sk_buff *skb);int netif_rx(struct sk_buff *skb);
这里使用了一个skb_buff结构体,定义于include/linux/skbuff.h中,它的含义为“套接字缓冲区”,用于在Linux网络子系统各层间传输数据
sk_buff中重要的数据成员
struct device *dev;正在处理该包的设备
__u32 sadd;r//IP元地址
__u32 daddr;//IP目的地址