Linux3.10内核RX收包路径TAP及AF_PACKET套接字捕获逻辑问询
问题解答
1 ptype_all列表与AF_PACKET套接字的关系
你的猜测完全正确:ptype_all列表仅包含以ETH_P_ALL作为协议号注册的协议处理实例,不是所有AF_PACKET原始套接字都会进入这个列表。
- 当你创建AF_PACKET套接字时指定具体协议(比如
ETH_P_ARP),内核会将对应的packet_type结构体注册到ptype_base哈希表(按协议号索引),不会加入ptype_all - 只有创建套接字时指定协议为
ETH_P_ALL,对应的注册项才会进入ptype_all列表
2 原代码tp_vlan_tci始终为0的原因
Linux 3.10内核的报文接收路径执行顺序如下:
- 网卡收包后,若支持VLAN硬件卸载,会直接将VLAN TCI信息存入
skb->vlan_tci字段,VLAN头从报文载荷中剥离 - 进入
__netif_receive_skb_core后首先遍历ptype_all列表,将报文副本分发给所有ETH_P_ALL类型的处理逻辑,此时skb->vlan_tci还保留完整值,会被填充到tpacket_auxdata的tp_vlan_tci字段 - 之后才会执行VLAN子系统的处理逻辑,处理完成后会清空
skb->vlan_tci字段 - 最后内核才会遍历
ptype_base哈希表,将报文分发给指定具体协议的处理逻辑(包括你最初创建的ETH_P_ARP类型AF_PACKET套接字),此时skb->vlan_tci已经被清空,所以你读到的tp_vlan_tci始终为0
3 替代优化方案
如果你不需要捕获所有报文、只想捕获ARP报文同时拿到VLAN TCI,可以在ETH_P_ALL类型的AF_PACKET套接字上挂载BPF过滤规则,只允许ARP报文通过,这样不需要用户态做过滤,性能损耗极低。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

