public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Volker Diels-Grabsch <v@njh.eu>
To: passt-dev@passt.top
Subject: Re: [PATCH] Send an initial ARP request to resolve the guest IP address
Date: Sun, 7 Sep 2025 12:57:02 +0200	[thread overview]
Message-ID: <aL1k_ryYR-wCj3md@6153f789-1cf1-4ca3-8cea-6fa7ae195a8b.njh.eu> (raw)
In-Reply-To: <20250907104912.17917-1-v@njh.eu>

Hi all,

please ignore this one, it was sent by accident.  I'll send the actual
patch soon.  Sorry for the noise.


Best regards,
Volker


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.
> 
> 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.
> 
> 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.
> 
> 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 receive the guest's DHCP request - just as before.  In other
> words, in the worst case an ARP request would be harmless.
> 
> Signed-off-by: Volker Diels-Grabsch <v@njh.eu>
> ---
>  arp.c | 34 ++++++++++++++++++++++++++++++++++
>  arp.h |  1 +
>  tap.c | 15 +++++++++++++--
>  3 files changed, 48 insertions(+), 2 deletions(-)
> 
> diff --git a/arp.c b/arp.c
> index 44677ad..561581a 100644
> --- a/arp.c
> +++ b/arp.c
> @@ -112,3 +112,37 @@ int arp(const struct ctx *c, struct iov_tail *data)
>  
>  	return 1;
>  }
> +
> +/**
> + * send_initial_arp_req() - Send initial ARP request to retrieve guest MAC address
> + * @c:		Execution context
> + */
> +void send_initial_arp_req(const struct ctx *c)
> +{
> +	struct {
> +		struct ethhdr eh;
> +		struct arphdr ah;
> +		struct arpmsg am;
> +	} __attribute__((__packed__)) req;
> +
> +	/* Ethernet header */
> +	req.eh.h_proto = htons(ETH_P_ARP);
> +	memcpy(req.eh.h_dest, c->guest_mac, 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 = htons(ARPOP_REQUEST);
> +	req.ah.ar_hrd = htons(ARPHRD_ETHER);
> +	req.ah.ar_pro = htons(ETH_P_IP);
> +	req.ah.ar_hln = ETH_ALEN;
> +	req.ah.ar_pln = 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,	c->guest_mac,		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 reconnect");
> +	tap_send_single(c, &req, sizeof(req));
> +}
> diff --git a/arp.h b/arp.h
> index 86bcbf8..5490144 100644
> --- a/arp.h
> +++ b/arp.h
> @@ -21,5 +21,6 @@ struct arpmsg {
>  } __attribute__((__packed__));
>  
>  int arp(const struct ctx *c, struct iov_tail *data);
> +void send_initial_arp_req(const struct ctx *c);
>  
>  #endif /* ARP_H */
> diff --git a/tap.c b/tap.c
> index 7ba6399..47dedd5 100644
> --- a/tap.c
> +++ b/tap.c
> @@ -1355,6 +1355,16 @@ static void tap_start_connection(const struct ctx *c)
>  	ev.events = EPOLLIN | EPOLLRDHUP;
>  	ev.data.u64 = ref.u64;
>  	epoll_ctl(c->epollfd, EPOLL_CTL_ADD, c->fd_tap, &ev);
> +
> +	switch (c->mode) {
> +	case MODE_PASST:
> +		send_initial_arp_req(c);
> +		break;
> +	case MODE_PASTA:
> +		break;
> +	case MODE_VU:
> +		break;
> +	}
>  }
>  
>  /**
> @@ -1504,8 +1514,9 @@ void tap_backend_init(struct ctx *c)
>  		tap_sock_unix_init(c);
>  
>  		/* 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));
>  		break;
> -- 
> 2.47.2
> 

-- 
.---<<<((()))>>>---.
|      [[||]]      |
'---<<<((()))>>>---'

  reply	other threads:[~2025-09-07 10:57 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-07 10:49 [PATCH] Send an initial ARP request to resolve the guest IP address Volker Diels-Grabsch
2025-09-07 10:57 ` Volker Diels-Grabsch [this message]
  -- strict thread matches above, loose matches on Subject: below --
2025-09-07 11:01 Volker Diels-Grabsch
2025-09-08  4:00 ` David Gibson
2025-09-06  0:22 Volker Diels-Grabsch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aL1k_ryYR-wCj3md@6153f789-1cf1-4ca3-8cea-6fa7ae195a8b.njh.eu \
    --to=v@njh.eu \
    --cc=passt-dev@passt.top \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).