Как arp_process() отвечает нужному устройству?

Как arp_process() отвечает нужному устройству?

Глядя на исходный код ядра, я вижу, что при обработке ARP-запроса он net_deviceизвлекается прямо из skb, а затем, похоже, ответ отправляется на это устройство (арп.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;
...

Связанный контент