%20dem%20richtigen%20Ger%C3%A4t%3F.png)
Wenn ich mir den Kernel-Quellcode anschaue, sehe ich, dass bei der Verarbeitung der ARP-Anforderung das net_device
direkt vom abgerufen wird skb
und dann die Antwort anscheinend an dieses Gerät gesendet wird (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);
}
Aber wenn das Paket durch die Brücke ging, dann skb
bekam sein Gerätmit Bridge-Gerät überschrieben:
static int br_pass_frame_up(struct sk_buff *skb)
{
...
skb->dev = brdev;
...
}
Sollte es nicht irgendwie das ursprüngliche Gerät abrufen und die Antwort dorthin senden?
Antwort1
Wenn der Frame von einem Bridge-Port kam, bedeutet das, dass es jetzt einenFresh Bridge FDB-Eintragweist darauf hin, beim Senden eines Frames an diese MAC-Adresse denselben Bridge-Port zu verwenden: Eine Antwort wird an denselben Bridge-Port gesendet, von dem die Abfrage kam.
Aus Sicht der ARP-Schicht wurde das Paket also über die Bridge-Schnittstelle empfangen und die Antwort auch über die Bridge-Schnittstelle zurückgesendet.
Wenn die Antwort die untere Schicht erreicht: Bridge, das ist der Bridge-Code, der eine Suche in seiner Weiterleitungsdatenbank durchführt (auch bekannt alsFLUNKEREI) und wählt als ausgehenden Bridge-Port den vorherigen eingehenden Bridge-Port, anstatt die Antwort an alle seine Ports zu fluten (da ein so neuer Eintrag vorhanden ist):
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);
Wenn Sie es umgekehrt wie zuvor machen, wird die Gerätebrückenschnittstelle des SKB mit dem Brückenport überschrieben:
static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb, bool local_orig) { ... skb->dev = to->dev; ...