From e456c02a0e84bedba8011a6c0b6659a7409ad14b Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Thu, 23 Oct 2025 21:29:27 -0400 Subject: arp/ndp: respond with true MAC address of LAN local remote hosts When we receive an ARP request or NDP neigbour solicitation over the tap interface for a host on the local network segment attached to the template interface, we respond with that host's real MAC address, if available. Signed-off-by: Jon Maloy Reviewed-by: David Gibson Signed-off-by: Stefano Brivio --- arp.c | 8 ++++++-- inany.c | 1 + ndp.c | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arp.c b/arp.c index ad088b1..b4a686f 100644 --- a/arp.c +++ b/arp.c @@ -69,6 +69,7 @@ static bool ignore_arp(const struct ctx *c, */ int arp(const struct ctx *c, struct iov_tail *data) { + union inany_addr tgt; struct { struct ethhdr eh; struct arphdr ah; @@ -102,8 +103,11 @@ int arp(const struct ctx *c, struct iov_tail *data) resp.ah.ar_hln = ah->ar_hln; resp.ah.ar_pln = ah->ar_pln; - /* ARP message */ - memcpy(resp.am.sha, c->our_tap_mac, sizeof(resp.am.sha)); + /* MAC address to return in ARP message */ + inany_from_af(&tgt, AF_INET, am->tip); + fwd_neigh_mac_get(c, &tgt, resp.am.sha); + + /* Rest of ARP message */ memcpy(resp.am.sip, am->tip, sizeof(resp.am.sip)); memcpy(resp.am.tha, am->sha, sizeof(resp.am.tha)); memcpy(resp.am.tip, am->sip, sizeof(resp.am.tip)); diff --git a/inany.c b/inany.c index 65a39f9..7680439 100644 --- a/inany.c +++ b/inany.c @@ -16,6 +16,7 @@ #include "ip.h" #include "siphash.h" #include "inany.h" +#include "fwd.h" const union inany_addr inany_loopback4 = INANY_INIT4(IN4ADDR_LOOPBACK_INIT); const union inany_addr inany_any4 = INANY_INIT4(IN4ADDR_ANY_INIT); diff --git a/ndp.c b/ndp.c index 588b48f..7e2ae2a 100644 --- a/ndp.c +++ b/ndp.c @@ -196,6 +196,7 @@ static void ndp_send(const struct ctx *c, const struct in6_addr *dst, static void ndp_na(const struct ctx *c, const struct in6_addr *dst, const struct in6_addr *addr) { + union inany_addr tgt; struct ndp_na na = { .ih = { .icmp6_type = NA, @@ -213,7 +214,8 @@ static void ndp_na(const struct ctx *c, const struct in6_addr *dst, } }; - memcpy(na.target_l2_addr.mac, c->our_tap_mac, ETH_ALEN); + inany_from_af(&tgt, AF_INET6, addr); + fwd_neigh_mac_get(c, &tgt, na.target_l2_addr.mac); ndp_send(c, dst, &na, sizeof(na)); } -- cgit v1.2.3