netpoll只是一种框架和一些接口,只有依赖这个框架和接口实现的netpoll实例,netpoll才能发挥它的功能。类似于kernel中的vfs,vfs本身并不会去做具体的文件操作,只是为不同的文件系统提供了一个框架。netpoll不依赖于网络协议栈,因此在内核网络及I/O子系统尚未可用时,也可以发送或接收数据包。当然netpoll能够处理的数据包类型也很有限,只有UDP和ARP数据包,并且只能是以太网报文。注意这里对UDP数据包的处理并不像四层的UDP协议那样复杂,并且netpoll可以发挥作用要依赖网络设备的支持。
1、netpoll结构和netpoll_info结构
netpoll结构用来描述接收和发送数据包的必要信息,每一个依赖netpoll的模块在使用这个框架前都必须实现并注册netpoll实例。
netpoll结构定义如下:
struct netpoll {
struct net_device *dev;
char dev_name[IFNAMSIZ];
const char *name;
void (*rx_hook)(struct netpoll *, int, char *, int);
__be32 local_ip, remote_ip;
u16 local_port, remote_port;
u8 remote_mac[ETH_ALEN];
};
dev成员存储的是绑定的网络设备实例,netpoll实例只能通过特定的网络设备接收和发送数据包。该设备在注册netpoll实例时设置。
dev_name存储的是网络设备名,通过它调用dev_get_by_name()获取指定的网络设备实例,并保存在dev中。
name是netpoll实例的名称。
netpoll实例有两种:能接收数据包和不能接收数据包。如果要接收数据包的话,必须实现rx_hook接口。如果不接收数据包的话,则不用。
local_ip和remote_ip分别存储的是远端和本地的IP,由netpoll实例指定。
local_port和remote_port分别存储的是远端和本地的port。
remote_mac存储的MAC地址。netpoll只支持以太网数据包,所以这里的MAC地址是以太网MAC地址。
当支持netpoll时,网络设备的net_device实例必须实现npinfo成员,即网络设备的netpoll_info信息块,描述结构为netpoll_info,定义如下:
struct netpoll_info {
atomic_t refcnt;
int rx_flags;
spinlock_t rx_lock;
struct netpoll *rx_np; /* netpoll that registered an rx_hook */
struct sk_buff_head arp_tx; /* list of arp requests to reply to */
struct sk_buff_head txq;
struct delayed_work tx_work;
};
refcnt是引