Wie antwortet arp_process() dem richtigen Gerät?

Wie antwortet arp_process() dem richtigen Gerät?

Wenn ich mir den Kernel-Quellcode anschaue, sehe ich, dass bei der Verarbeitung der ARP-Anforderung das net_devicedirekt vom abgerufen wird skbund 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 skbbekam 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):

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

Wenn Sie es umgekehrt wie zuvor machen, wird die Gerätebrückenschnittstelle des SKB mit dem Brückenport überschrieben:

br_forward.c:

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

verwandte Informationen