当设备接收到一个包,会从类型字段得到协议类型,如:IP,802.3,ARP,IPv6等。然后根据类型,调用不同的处理函数,这类似面向对象的操作,通过下面的方式实现:
- 定义一个结构,用来将类型和函数对应起来
[ include/linux/netdevice.h ]
struct packet_type { __be16 type; /* This is really htons(ether_type).包的类型 */ struct net_device *dev; /* NULL is wildcarded here.对应的网络设备 */ int (*func) (struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); bool (*id_match)(struct packet_type *ptype, struct sock *sk); void *af_packet_priv; struct list_head list; };
- 定义一个全局列表,所有packet_type类型为ETH_P_ALL(接收所有类型的包)的都挂在此列表上
[ net/core/dev.c ]
struct list_head ptype_all __read_mostly; /* Taps */ - 定义一个哈希表,其中的key为包的类型
[ net/core/dev.c ]
struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
[ include/linux/netde