arp_process() はどのようにして適切なデバイスに応答するのでしょうか?

arp_process() はどのようにして適切なデバイスに応答するのでしょうか?

カーネルのソースコードを見ると、ARP要求を処理するときにnet_deviceが から直接取得されskb、その後、応答がそのデバイスに送信されるようです(arp.c#L679):

static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
{
     struct net_device *dev = skb->dev;
     ...
     arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
           sip, dev, tip, sha,
           dev->dev_addr, sha,
           reply_dst);
}

しかし、パケットがブリッジを通過してskbデバイスに到達した場合ブリッジデバイスで上書きされました:

static int br_pass_frame_up(struct sk_buff *skb)
{
    ...
    skb->dev = brdev;
    ...
}

何らかの方法で元のデバイスを取得し、そこに応答を送信するべきではないでしょうか?

答え1

フレームがブリッジポートから到着した場合、それはフレッシュブリッジFDBエントリこの MAC アドレスにフレームを送信するときに、同じブリッジ ポートを使用するように指示します。応答は、クエリが到着した同じブリッジ ポートに送信されます。

したがって、ARP 層の観点からは、パケットはブリッジ インターフェイスで受信され、応答もブリッジ インターフェイスで送り返されます。

応答が下位層であるブリッジに到達すると、ブリッジコードは転送データベース(別名フィボナッチ) を実行し、すべてのポートに応答をフラッディングするのではなく、以前の着信ブリッジ ポートを送信ブリッジ ポートとして選択します (最近のエントリが見つかるため)。

br_device.c:

netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
...
  } else if ((dst = br_fdb_find_rcu(br, dest, vid)) != NULL) {
      br_forward(dst->dst, skb, false, true);
  } else {
      br_flood(br, skb, BR_PKT_UNICAST, false, true);

前と逆のことを行うと、skb のデバイス ブリッジ インターフェイスがブリッジ ポートで上書きされます。

br_forward.c:

static void __br_forward(const struct net_bridge_port *to,
           struct sk_buff *skb, bool local_orig)
{
...
      skb->dev = to->dev;
...

関連情報