%20al%20dispositivo%20correcto%3F.png)
Al observar el código fuente del kernel, veo que al procesar la solicitud ARP, net_device
se recupera directamente desde el skb
y luego parece que la respuesta se envía a ese dispositivo (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);
}
Pero si el paquete pasó por el puente, entonces skb
obtuvo su dispositivo.sobrescrito con dispositivo puente:
static int br_pass_frame_up(struct sk_buff *skb)
{
...
skb->dev = brdev;
...
}
¿No debería de alguna manera recuperar el dispositivo original y enviar la respuesta allí?
Respuesta1
Si la trama llegó desde un puerto puente, eso significa que ahora hay unentrada fresca del puente fdbindicando que se utilice este mismo puerto puente al enviar una trama a esta dirección MAC: se enviará una respuesta al mismo puerto puente desde el que llegó la consulta.
Entonces, desde el punto de vista de la capa ARP, el paquete se recibió en la interfaz del puente y la respuesta también se envió de regreso a la interfaz del puente.
Cuando la respuesta llega a la capa inferior: puente, ese es el código del puente que realiza una búsqueda en su base de datos de reenvío (también conocido comoMENTIRA) y elige como puerto puente de salida el puerto puente entrante anterior en lugar de inundar la respuesta a todos sus puertos (ya que se puede encontrar una entrada tan reciente):
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);
Haciendo lo contrario que antes, la interfaz puente del dispositivo del skb se sobrescribe con el puerto puente:
static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb, bool local_orig) { ... skb->dev = to->dev; ...