5

ドライバをボンディングする方法について、スレーブインターフェイスからRXパケットを取得する方法について質問があります。ボンディングを使用dev_add_pack()してLACPDUおよびARPパケットのハンドラーを設定していることがわかりましたが、他のハンドラー(他のパケットタイプの場合)は見つかりませんでした。

この問題を解決するのを手伝ってくれませんか。

4

2 に答える 2

2

ボンディング ドライバーは独自の Rx ハンドラーを登録します。スレーブ インターフェイスがボンド マスターにスレーブされると、bond_enslave() で次のことがわかります。

res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
                                 new_slave);

したがって、bond_handle_frame() では、スレーブ インターフェイスが受信したパケットをハイジャックし、代わりにボンド マスターがパケットを受信するようにします。

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;
}
于 2013-03-01T09:57:09.403 に答える
1

ボンディングのコードを確認したところ、ドライバーがこれらのモードで動作している場合、一部のタイプ (LACPDU、ARP) がないと、ドライバーが着信 RX パケットを検査しないことがわかりました。ドライバーは、dev_add_pack() 関数を使用して、このパケットのハンドラーを設定します。

実際にグローバル フックを設定するには、nf_register_hook() を使用できます。これは、パケットを傍受するための独自のネット フィルター手順をセットアップするためのインターフェイスを提供します。nf_register_hook() は dev_add_pack() よりも強力なようですが、nf_register_hook() を使用する場合は、フックの条件が間違っている場合に多くのパケットがドロップされる可能性があるため、より注意が必要だと思います。

于 2013-02-28T19:09:41.717 に答える