public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 2/3] fwd: Clarify semantics of --host-lo-to-ns-lo
Date: Wed,  1 Jul 2026 17:08:10 +1000	[thread overview]
Message-ID: <20260701070811.1944139-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260701070811.1944139-1-david@gibson.dropbear.id.au>

The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoreically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with upcoming remapping of target address by forwarding rules.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 conf.c  |  2 ++
 fwd.c   | 22 ++++++++++------------
 passt.1 |  9 +++++----
 3 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/conf.c b/conf.c
index c4a36dee..912543fa 100644
--- a/conf.c
+++ b/conf.c
@@ -1792,6 +1792,8 @@ void conf(struct ctx *c, int argc, char **argv)
 		if (c->splice_only)
 			die("--splice-only is for pasta mode only");
 	}
+	if (c->no_splice && c->host_lo_to_ns_lo)
+		die("--host-lo-to-ns-lo is incompatible with --no-splice");
 
 	if (c->mode == MODE_PASTA && !c->pasta_conf_ns) {
 		if (copy_routes_opt)
diff --git a/fwd.c b/fwd.c
index 042158cf..659f8d9f 100644
--- a/fwd.c
+++ b/fwd.c
@@ -1036,21 +1036,19 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
 		 * In either case, let the kernel pick the source address to
 		 * match.
 		 */
-		if (inany_v4(&ini->eaddr)) {
-			if (c->host_lo_to_ns_lo)
-				tgt->eaddr = inany_loopback4;
-			else
-				tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
+		if (c->host_lo_to_ns_lo && inany_is_loopback(&ini->oaddr))
+			tgt->eaddr = ini->oaddr;
+		else if (inany_v4(&ini->eaddr))
+			tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
+		else
+			tgt->eaddr.a6 = c->ip6.addr_seen;
+
+		/* Let the kernel pick source address and port */
+		if (inany_v4(&tgt->eaddr))
 			tgt->oaddr = inany_any4;
-		} else {
-			if (c->host_lo_to_ns_lo)
-				tgt->eaddr = inany_loopback6;
-			else
-				tgt->eaddr.a6 = c->ip6.addr_seen;
+		else
 			tgt->oaddr = inany_any6;
-		}
 
-		/* Let the kernel pick source port */
 		tgt->oport = 0;
 		if (proto == IPPROTO_UDP)
 			/* But for UDP preserve the source port */
diff --git a/passt.1 b/passt.1
index 908fd4a4..d057aebc 100644
--- a/passt.1
+++ b/passt.1
@@ -650,10 +650,11 @@ Default is \fBauto\fR.
 
 .TP
 .BR \-\-host-lo-to-ns-lo
-If specified, connections forwarded with \fB\-t\fR and \fB\-u\fR from
-the host's loopback address will appear on the loopback address in the
-guest as well.  Without this option such forwarded packets will appear
-to come from the guest's public address.
+If specified, connections to a host loopback address forwarded with
+\fB\-t\fR or \fB\-u\fR will be delivered to the same loopback address
+on the guest.  Without this option such connections are forwarded to
+the guest's public address.  This option is incompatible with
+\fB--no-splice\fR.
 
 .TP
 .BR \-\-userns " " \fIspec
-- 
2.54.0


  parent reply	other threads:[~2026-07-01  7:08 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01  7:08 [PATCH 0/3] RFC: Target address mapping David Gibson
2026-07-01  7:08 ` [PATCH 1/3] fwd_rule: Parse target adddresses for forwarding rules David Gibson
2026-07-01  7:08 ` David Gibson [this message]
2026-07-01  7:08 ` [PATCH 3/3] fwd, fwd_rule: Implement configurable target address mapping David Gibson

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=20260701070811.1944139-3-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /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).