From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202508 header.b=Eb2wqzbn; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 163735A0278 for ; Tue, 09 Sep 2025 04:52:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202508; t=1757386332; bh=x01GM7yh71W3Kp17qijcn6KF2wNtDbqyyI62eEaOoL8=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=Eb2wqzbnwGDDI7VOP1t1ueiwKGz6SpHkv30LqATdJlADdXQyeMUYNFSQwc2YybuGe 7EylO73fboWy9XyklOV+sdWsXX9wBfCqv7oxoD+oDoCfBQ+PlU2MZR6mwZeO868tSs xiSwKfuGcBZC/sCZWb+J6QHbNTybFWnE/7S+aW+or8krzUz2ESCbDWkOalkbN6SOSe jR0tsOY7mI31l14CZF/DDUaJzUfgTYU+cq2FUfAvkQZuoK5iqy+RGcQgV+2PujSBjh c23JcKm2i+5w4mhv2QUfTc2Rq1bkXLTbPpZkyH2IOq4cZA/Vm1DkahyBzCPoQLzhEf FHtJUP4r6nKlA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4cLSz05940z4w8w; Tue, 9 Sep 2025 12:52:12 +1000 (AEST) Date: Tue, 9 Sep 2025 12:52:03 +1000 From: David Gibson To: Volker Diels-Grabsch Subject: Re: [PATCH v2] Send an initial ARP request to resolve the guest IP address Message-ID: References: <20250908092038.405194-1-v@njh.eu> <20250908092429.406248-2-v@njh.eu> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="R9h1NrT+CS6iUkRv" Content-Disposition: inline In-Reply-To: <20250908092429.406248-2-v@njh.eu> Message-ID-Hash: IKVSLCBT2JRCD25ZLR7VOTHQ2VKELJ5Q X-Message-ID-Hash: IKVSLCBT2JRCD25ZLR7VOTHQ2VKELJ5Q X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --R9h1NrT+CS6iUkRv Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Sep 08, 2025 at 11:22:44AM +0200, Volker Diels-Grabsch wrote: > When restarting passt while QEMU keeps running with a configured > "reconnect-ms" setting, the port forwardings will stop working until > the guest sends some outgoing network traffic. >=20 > Reason: Although QEMU reconnects successfully to the unix domain > socket of the new passt process, that one no longer knows the guest's > MAC address and uses instead a broadcast MAC address. However, this > is ignored by the guest, at least if the guest runs Linux. Only after > the guest sends some network package on its own initiative, passt will > know the MAC address and will be able to establish forwarded > connections. >=20 > This change fixes this issue by sending an ARP request to resolve the > guest's MAC address via its IP address, which we do know, right after > the unix domain socket (re)connection. >=20 > The only case where the IP is "wrong" would be if the configuration > changed, and/or on the very first start right after qemu started. But > in those cases, we just wouldn't get an ARP response, and can't do > anything until we receive the guest's DHCP request - just as before. > In other words, in the worst case an ARP request would be harmless. >=20 > Signed-off-by: Volker Diels-Grabsch Reviewed-by: David Gibson Looks good to me. It would be nice to also send an Neighbour Discovery request to accomplish the same thing for IPv6 only guests, but that could be a separate patch. Note that even with this patch, active TCP connections (and in some cases UDP flows) will be broken by a passt restart. > --- > arp.c | 34 ++++++++++++++++++++++++++++++++++ > arp.h | 1 + > tap.c | 9 ++++++--- > util.h | 1 + > 4 files changed, 42 insertions(+), 3 deletions(-) >=20 > diff --git a/arp.c b/arp.c > index 44677ad..c217356 100644 > --- a/arp.c > +++ b/arp.c > @@ -112,3 +112,37 @@ int arp(const struct ctx *c, struct iov_tail *data) > =20 > return 1; > } > + > +/** > + * arp_send_init_req() - Send initial ARP request to retrieve guest MAC = address > + * @c: Execution context > + */ > +void arp_send_init_req(const struct ctx *c) > +{ > + struct { > + struct ethhdr eh; > + struct arphdr ah; > + struct arpmsg am; > + } __attribute__((__packed__)) req; > + > + /* Ethernet header */ > + req.eh.h_proto =3D htons(ETH_P_ARP); > + memcpy(req.eh.h_dest, MAC_BROADCAST, sizeof(req.eh.h_dest)); > + memcpy(req.eh.h_source, c->our_tap_mac, sizeof(req.eh.h_source)); > + > + /* ARP header */ > + req.ah.ar_op =3D htons(ARPOP_REQUEST); > + req.ah.ar_hrd =3D htons(ARPHRD_ETHER); > + req.ah.ar_pro =3D htons(ETH_P_IP); > + req.ah.ar_hln =3D ETH_ALEN; > + req.ah.ar_pln =3D 4; > + > + /* ARP message */ > + memcpy(req.am.sha, c->our_tap_mac, sizeof(req.am.sha)); > + memcpy(req.am.sip, &c->ip4.our_tap_addr, sizeof(req.am.sip)); > + memcpy(req.am.tha, MAC_BROADCAST, sizeof(req.am.tha)); > + memcpy(req.am.tip, &c->ip4.addr, sizeof(req.am.tip)); > + > + info("sending initial ARP request to retrieve guest MAC address after r= econnect"); > + tap_send_single(c, &req, sizeof(req)); > +} > diff --git a/arp.h b/arp.h > index 86bcbf8..d5ad0e1 100644 > --- a/arp.h > +++ b/arp.h > @@ -21,5 +21,6 @@ struct arpmsg { > } __attribute__((__packed__)); > =20 > int arp(const struct ctx *c, struct iov_tail *data); > +void arp_send_init_req(const struct ctx *c); > =20 > #endif /* ARP_H */ > diff --git a/tap.c b/tap.c > index 7ba6399..4249353 100644 > --- a/tap.c > +++ b/tap.c > @@ -1355,6 +1355,8 @@ static void tap_start_connection(const struct ctx *= c) > ev.events =3D EPOLLIN | EPOLLRDHUP; > ev.data.u64 =3D ref.u64; > epoll_ctl(c->epollfd, EPOLL_CTL_ADD, c->fd_tap, &ev); > + > + arp_send_init_req(c); > } > =20 > /** > @@ -1504,10 +1506,11 @@ void tap_backend_init(struct ctx *c) > tap_sock_unix_init(c); > =20 > /* In passt mode, we don't know the guest's MAC address until it > - * sends us packets. Use the broadcast address so that our > - * first packets will reach it. > + * sends us packets (e.g. responds to our initial ARP request). > + * Until then, use the broadcast address so that our first > + * packets will reach it. > */ > - memset(&c->guest_mac, 0xff, sizeof(c->guest_mac)); > + memcpy(&c->guest_mac, MAC_BROADCAST, sizeof(c->guest_mac)); > break; > } > =20 > diff --git a/util.h b/util.h > index 2a8c38f..3719f0c 100644 > --- a/util.h > +++ b/util.h > @@ -97,6 +97,7 @@ void abort_with_msg(const char *fmt, ...) > #define FD_PROTO(x, proto) \ > (IN_INTERVAL(c->proto.fd_min, c->proto.fd_max, (x))) > =20 > +#define MAC_BROADCAST ((uint8_t [ETH_ALEN]){ 0xff, 0xff, 0xff, 0xff, 0x= ff, 0xff }) > #define MAC_ZERO ((uint8_t [ETH_ALEN]){ 0 }) > #define MAC_IS_ZERO(addr) (!memcmp((addr), MAC_ZERO, ETH_ALEN)) > =20 > --=20 > 2.47.3 >=20 --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --R9h1NrT+CS6iUkRv Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmi/llIACgkQzQJF27ox 2GeJShAApsblucb8NTdMirk9zxgojoLBmJ69ktvvQw47Zs5uRdIctznh094SY8Nw +p58QK8zPbUOYYDJPOzakQ8h8F1Z03VMNOj+Mp2zI4D0yAIcLasWaszu3uVvynLZ btf722fA5oiZUMIMlRkXtaF7NSa5Gcu4swXwM37yDlMtIjt3Ad1MM5+nptaGoBN2 RA1ePCSVKBWf5UnDOtV23QORtPNlKUzMPEnvcC033InzU1pbsZCdewSRgefBMtnk j6PQXFupybBKcFF6QcMyGQe3/uXJSdXxn9dWs2KIET6dQsoiZiMRBCxk4fywqi7N zn5mfzge7LSUyzwoi9xegznqJzhr33ctKBonLYz2aW28rWEBtgh0F/lCEF2aaSYC QKH/uZxd6KfzqL8BXSU5CSSW6EaEdOloDcnYrsk1Jm56FrixIwPEqXFWyC7Grtpz 3aL0gqu4Gsl0++M3KpL5Jp5LEYSFTcp21aHtYjq5LrptV9x6ReWBdWUjZcqITWYm tkrZwClcAX9OwIg//EfL8gYpNwvjWyAz+OCCvZ5YcuF/odmM/YnB3Giew/4mckxq qWvw/fiaJfgYH0zoMmgqxvttR+5zb0wOZpY7qix/polx59tUcE5HNK5CIlKBy+27 WW3nTtXPwzwUdrXejSroz7geL9ox+tYR68uG5CP7HBKOkZA3S00= =W1gb -----END PGP SIGNATURE----- --R9h1NrT+CS6iUkRv--