我有一个关于如何绑定驱动程序从被奴役接口获取 RX 数据包的问题。我发现绑定dev_add_pack()
用于为 LACPDU 和 ARP 数据包设置处理程序,但我没有找到其他处理程序(用于其他数据包类型)。
你能帮我解决这个问题吗?
我有一个关于如何绑定驱动程序从被奴役接口获取 RX 数据包的问题。我发现绑定dev_add_pack()
用于为 LACPDU 和 ARP 数据包设置处理程序,但我没有找到其他处理程序(用于其他数据包类型)。
你能帮我解决这个问题吗?
绑定驱动程序注册自己的 Rx 处理程序,当从接口被绑定到绑定主机时,在 bond_enslave() 中您可以看到:
res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
new_slave);
所以在bond_handle_frame()中,它会劫持slave接口接收到的数据包,让bond master代替接收数据包:
static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
struct slave *slave;
struct bonding *bond;
int (*recv_probe)(const struct sk_buff *, struct bonding *,
struct slave *);
int ret = RX_HANDLER_ANOTHER;
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
return RX_HANDLER_CONSUMED;
*pskb = skb;
slave = bond_slave_get_rcu(skb->dev);
bond = slave->bond;
if (bond->params.arp_interval)
slave->dev->last_rx = jiffies;
recv_probe = ACCESS_ONCE(bond->recv_probe);
if (recv_probe) {
ret = recv_probe(skb, bond, slave);
if (ret == RX_HANDLER_CONSUMED) {
consume_skb(skb);
return ret;
}
}
if (bond_should_deliver_exact_match(skb, slave, bond)) {
return RX_HANDLER_EXACT;
}
skb->dev = bond->dev;
if (bond->params.mode == BOND_MODE_ALB &&
bond->dev->priv_flags & IFF_BRIDGE_PORT &&
skb->pkt_type == PACKET_HOST) {
if (unlikely(skb_cow_head(skb,
skb->data - skb_mac_header(skb)))) {
kfree_skb(skb);
return RX_HANDLER_CONSUMED;
}
memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN);
}
return ret;
}
我检查了绑定代码,发现当驱动程序在这些模式下工作时,驱动程序不会检查没有某些类型(LACPDU、ARP)的传入 RX 数据包。驱动程序使用 dev_add_pack() 函数为此数据包设置处理程序。
为了在实践中设置全局挂钩,您可以使用 nf_register_hook(),它为设置自己的网络过滤程序以拦截数据包提供接口。似乎 nf_register_hook() 比 dev_add_pack() 更强大,但我认为在工作 nf_register_hook() 时需要更加小心,因为如果钩子中的条件错误,它会丢弃很多数据包。