カーネルソースコードを見ると、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層の観点から見ると、パケットはブリッジインタフェースで受信され、応答はブリッジインタフェースに送り返される。
応答が下位層のブリッジに達すると、ブリッジコードは転送データベース(別名)で次のことを行います。悪のない嘘)すべてのポートへの応答をフラッディングする代わりに、前の受信ブリッジポートを発信するブリッジポートとして選択します(これらの最近のエントリが見つかるため)。
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のデバイスブリッジインターフェイスはブリッジポートで保護されています。
static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb, bool local_orig) { ... skb->dev = to->dev; ...