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 v2 2/2] fwd, fwd_rule: Implement configurable target address mapping
Date: Thu,  2 Jul 2026 17:32:15 +1000	[thread overview]
Message-ID: <20260702073215.751291-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260702073215.751291-1-david@gibson.dropbear.id.au>

From: Stefano Brivio <sbrivio@redhat.com>

Add a 'taddr' field to forwarding rules, which controls the destination
address on the target side.  Since changing the structure alters the pesto
update protocol, bump the protocol version number

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
[dwg: Split from option parsing code, added protocol version bump,
 explicitly exclude splicing with target address for now]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 fwd.c      |  8 ++++++--
 fwd_rule.c | 19 +++++++++++--------
 fwd_rule.h |  7 +++++--
 pesto.h    |  6 +++++-
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/fwd.c b/fwd.c
index 042158cf..3ae25fde 100644
--- a/fwd.c
+++ b/fwd.c
@@ -1023,7 +1023,9 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
 	/* Common for spliced and non-spliced cases */
 	tgt->eport = rule->to + (ini->oport - rule->first);
 
-	if (!c->no_splice && inany_is_loopback(&ini->eaddr) &&
+	/* TODO: Allow splicing with specified target address */
+	if (!c->no_splice && inany_is_unspecified(&rule->taddr) &&
+	    inany_is_loopback(&ini->eaddr) &&
 	    (proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
 		/* spliceable */
 
@@ -1074,7 +1076,9 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
 	}
 	tgt->oport = ini->eport;
 
-	if (inany_v4(&tgt->oaddr)) {
+	if (!inany_is_unspecified(&rule->taddr)) {
+		tgt->eaddr = rule->taddr;
+	} else if (inany_v4(&tgt->oaddr)) {
 		tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
 	} else {
 		if (inany_is_linklocal6(&tgt->oaddr))
diff --git a/fwd_rule.c b/fwd_rule.c
index bed29ed9..d1ecd39e 100644
--- a/fwd_rule.c
+++ b/fwd_rule.c
@@ -115,10 +115,15 @@ __attribute__((noinline))
 const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size)
 {
 	const char *percent = *rule->ifname ? "%" : "";
+	char taddr[INANY_ADDRSTRLEN] = { 0 };
 	const char *weak = "", *scan = "";
 	char addr[INANY_ADDRSTRLEN];
 	int len;
 
+	if (!inany_is_unspecified(&rule->taddr)) {
+		(void)snprintf(taddr, sizeof(taddr), "%s:",
+			       inany_ntop(&rule->taddr, addr, sizeof(addr)));
+	}
 	inany_ntop(fwd_rule_addr(rule), addr, sizeof(addr));
 	if (rule->flags & FWD_WEAK)
 		weak = " (best effort)";
@@ -127,16 +132,17 @@ const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size)
 
 	if (rule->first == rule->last) {
 		len = snprintf(dst, size,
-			       "%s [%s]%s%s:%hu  =>  %hu %s%s",
+			       "%s [%s]%s%s:%hu  =>  %s%hu %s%s",
 			       ipproto_name(rule->proto), addr, percent,
-			       rule->ifname, rule->first, rule->to, weak, scan);
+			       rule->ifname, rule->first,
+			       taddr, rule->to, weak, scan);
 	} else {
 		in_port_t tolast = rule->last - rule->first + rule->to;
 		len = snprintf(dst, size,
-			       "%s [%s]%s%s:%hu-%hu  =>  %hu-%hu %s%s",
+			       "%s [%s]%s%s:%hu-%hu  =>  %s%hu-%hu %s%s",
 			       ipproto_name(rule->proto), addr, percent,
 			       rule->ifname, rule->first, rule->last,
-			       rule->to, tolast, weak, scan);
+			       taddr, rule->to, tolast, weak, scan);
 	}
 
 	if (len < 0 || (size_t)len >= size)
@@ -393,6 +399,7 @@ static void fwd_rule_range_except(struct fwd_table *fwd, bool del,
 {
 	struct fwd_rule rule = {
 		.addr = addr ? *addr : inany_any6,
+		.taddr = tgt_addr ? *tgt_addr : inany_any6,
 		.ifname = { 0 },
 		.proto = proto,
 		.flags = flags,
@@ -416,10 +423,6 @@ static void fwd_rule_range_except(struct fwd_table *fwd, bool del,
 			    inany_ntop(addr, bstr, sizeof(bstr)),
 			    inany_ntop(tgt_addr, astr, sizeof(astr)));
 		}
-
-		info("Target address: %s",
-		     inany_ntop(tgt_addr, astr, sizeof(astr)));
-		die("Target address remapping not yet implemented");
 	}
 
 	if (!addr)
diff --git a/fwd_rule.h b/fwd_rule.h
index 435be5bd..a8788318 100644
--- a/fwd_rule.h
+++ b/fwd_rule.h
@@ -33,6 +33,7 @@
 /**
  * struct fwd_rule - Forwarding rule governing a range of ports
  * @addr:	Address to forward from
+ * @taddr:	Target side destination address
  * @ifname:	Interface to forward from
  * @first:	First port number to forward
  * @last:	Last port number to forward
@@ -45,6 +46,7 @@
  */
 struct fwd_rule {
 	union inany_addr addr;
+	union inany_addr taddr;
 	char ifname[IFNAMSIZ];
 	in_port_t first;
 	in_port_t last;
@@ -91,10 +93,11 @@ void fwd_probe_ephemeral(void);
 
 #define FWD_RULE_STRLEN					    \
 	(IPPROTO_STRLEN - 1				    \
-	 + INANY_ADDRSTRLEN - 1				    \
+	 + INANY_ADDRSTRLEN - 1 /* listen addr */	    \
+	 + INANY_ADDRSTRLEN - 1	/* target addr */	    \
 	 + IFNAMSIZ - 1					    \
 	 + 4 * (UINT16_STRLEN - 1)			    \
-	 + sizeof(" []%:-  =>  - (best effort) (auto-scan)"))
+	 + sizeof(" []%:-  =>  :- (best effort) (auto-scan)"))
 
 const union inany_addr *fwd_rule_addr(const struct fwd_rule *rule);
 const char *fwd_rule_fmt(const struct fwd_rule *rule, char *dst, size_t size);
diff --git a/pesto.h b/pesto.h
index 980cc17d..8db701b4 100644
--- a/pesto.h
+++ b/pesto.h
@@ -15,7 +15,11 @@
 #define PESTO_SERVER_MAGIC	"basil:s"
 
 /* Version 0 is reserved for unreleased / unsupported experimental versions */
-#define PESTO_PROTOCOL_VERSION	1
+/* Version 1 had no target address field in struct fwd_rule.  It was released,
+ * but was little enough used that we decided not to implement backwards
+ * compatiblity code (i.e. a v2 pesto will not work with a v1 pasta)
+ */
+#define PESTO_PROTOCOL_VERSION	2
 
 /* Maximum size of a pif name, including \0 */
 #define	PIF_NAME_SIZE	(128)
-- 
2.55.0


      parent reply	other threads:[~2026-07-02  7:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-02  7:32 [PATCH v2 0/2] Target " David Gibson
2026-07-02  7:32 ` [PATCH v2 1/2] fwd_rule: Parse target addresses for forwarding rules David Gibson
2026-07-02  7:32 ` David Gibson [this message]

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=20260702073215.751291-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).