我正在编写网络设备驱动程序。
内核 2.6.35.12
设备在连接到网桥端口时应该可以工作。
我试图拦截从网桥转发到接口的 ICMPv6 RA 和 NS 消息(路由器/邻居请求)。
eth <–> br0 <–> mydevice
在设备 start_xmit 函数中,我正在执行以下操作:
检查以太网头后的协议字段是否为 IPV6 (0x86dd)
检查 ipv6 下一个标头是否为 ICMPv6 并检查其类型:
__u8 nexthdr = ipv6_hdr(skb)->nexthdr;
if (nexthdr == htons (IPPROTO_ICMPV6))
{
struct icmp6hdr *hdr = icmp6_hdr(skb);
u8 type = hdr->icmp6_type;
if(type == htons (NDISC_NEIGHBOUR_SOLICITATION) || type == htons (NDISC_ROUTER_SOLICITATION))
{
….Do something here…
}
}
当从设备(例如 br0)内部发送 RS/NS 时,我看到代码工作正常。
问题是当流量从另一个端口通过网桥转发时。
我看到 icmp6_hdr(skb) 返回了不正确的标题。
再调试一些,似乎 skb->network_header 和 skb->transport_header 指向同一个地方。
icmp6_hdr 正在使用 transport_header 来解释它为什么不正确。
转储 skb 数据,它看起来所有的标头和有效负载都在正确的偏移量(也将它与 tcpdump 进行比较)
我怀疑它可能与桥代码有关,在深入研究之前,
我想也许有人遇到过类似的事情或有任何其他想法?