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 層的角度來看,封包在橋接介面上被接收,並且應答也在橋接介面上發回。

當回復到達下層:橋接器時,橋接器代碼會在其轉送資料庫(又稱FIB)並選擇前一個傳入橋接端口作為傳出橋接端口,而不是將答案泛洪到其所有端口(因為可以找到這樣一個最近的條目):

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;
...

相關內容