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=202512 header.b=Iveo6oN9; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 9A4B75A0773 for ; Fri, 19 Dec 2025 15:19:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202512; t=1766153948; bh=YAkdYCdREEw3BDjPL7MmWkfnlswsDmmTrscPQXVjElQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Iveo6oN9Xp0PX6Qz16NDGi0RioD8xqXCBy6HDKaUX9mluQD7dSgjVPSWVJOqrcLYC CiJxv/mqfQN0YL9BsR1uu6NZ1jioKcn1PR9v14TGBEtXb1am8pNAlGd2SI8dHny7j1 RVgg0dDbjTrd4fcAbawYV7Av7YcEMJUdKHIojvvM0DkQs/PlIF3p3T1qkTv4sUVcCO y5iaq8rQPKC5ccK7G/pb/4paZwFmqsJgOPn17UFvw4lRnbHTYwetSI7WNEcl5v7uwf Laf80ucYSF4wDZSLVCUgTlOa59NZ9/YJE3jpmNfCfOPl6u04wO3d7DMPBPmznVwt+i 9hclK043i2ixQ== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4dXqR02mCTz4wM8; Sat, 20 Dec 2025 01:19:08 +1100 (AEDT) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 05/12] conf, fwd: Record "auto" port forwards in forwarding table Date: Sat, 20 Dec 2025 01:18:57 +1100 Message-ID: <20251219141904.1758072-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251219141904.1758072-1-david@gibson.dropbear.id.au> References: <20251219141904.1758072-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: M55U7EYIOLETIIRMA4RVNEZBMSFP76JV X-Message-ID-Hash: M55U7EYIOLETIIRMA4RVNEZBMSFP76JV 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: David Gibson 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: Currently the forwarding table records details of explicit port forwards, but nothing for -[tTuU] auto. That looks a little odd on the debug output, and will be a problem for future changes. Extend the forward table to have entries for auto-scanned forwards, using a new FWD_SCAN flag. For now the mechanism of auto port forwarding isn't updated, and we can only create a single FWD_SCAN entry per protocol and direction. We'll better integrate auto scanning with other forward table mechanics in future. Signed-off-by: David Gibson --- conf.c | 34 ++++++++++++++++++++++++++++------ fwd.c | 12 +++++++----- fwd.h | 2 ++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/conf.c b/conf.c index af9e82f5..9d94e449 100644 --- a/conf.c +++ b/conf.c @@ -135,7 +135,7 @@ static int parse_port_range(const char *s, char **endptr, * @ifname: Listening interface * @first: First port to forward * @last: Last port to forward - * @exclude: Bitmap of ports to exclude + * @exclude: Bitmap of ports to exclude (may be NULL) * @to: Port to translate @first to when forwarding * @flags: Flags for forwarding entries */ @@ -158,11 +158,11 @@ static void conf_ports_range_except(const struct ctx *c, char optname, } for (base = first; base <= last; base++) { - if (bitmap_isset(exclude, base)) + if (exclude && bitmap_isset(exclude, base)) continue; for (i = base; i <= last; i++) { - if (bitmap_isset(exclude, i)) + if (exclude && bitmap_isset(exclude, i)) break; if (bitmap_isset(fwd->map, i)) { @@ -170,12 +170,13 @@ static void conf_ports_range_except(const struct ctx *c, char optname, "Altering mapping of already mapped port number: %s", optarg); } - bitmap_set(fwd->map, i); + if (!(flags & FWD_SCAN)) + bitmap_set(fwd->map, i); fwd->delta[i] = delta; - if (optname == 't') + if (!(flags & FWD_SCAN) && optname == 't') ret = tcp_listen(c, PIF_HOST, addr, ifname, i); - else if (optname == 'u') + else if (!(flags & FWD_SCAN) && optname == 'u') ret = udp_listen(c, PIF_HOST, addr, ifname, i); else /* No way to check in advance for -T and -U */ @@ -2189,6 +2190,27 @@ void conf(struct ctx *c, int argc, char **argv) if (!c->udp.fwd_out.mode) c->udp.fwd_out.mode = fwd_default; + if (c->tcp.fwd_in.mode == FWD_AUTO) { + conf_ports_range_except(c, 't', "auto", &c->tcp.fwd_in, + NULL, NULL, 1, NUM_PORTS - 1, + NULL, 1, FWD_SCAN); + } + if (c->tcp.fwd_out.mode == FWD_AUTO) { + conf_ports_range_except(c, 'T', "auto", &c->tcp.fwd_out, + NULL, "lo", 1, NUM_PORTS - 1, + NULL, 1, FWD_SCAN); + } + if (c->udp.fwd_in.mode == FWD_AUTO) { + conf_ports_range_except(c, 'u', "auto", &c->udp.fwd_in, + NULL, NULL, 1, NUM_PORTS - 1, + NULL, 1, FWD_SCAN); + } + if (c->udp.fwd_out.mode == FWD_AUTO) { + conf_ports_range_except(c, 'U', "auto", &c->udp.fwd_out, + NULL, "lo", 1, NUM_PORTS - 1, + NULL, 1, FWD_SCAN); + } + if (!c->quiet) conf_print(c); } diff --git a/fwd.c b/fwd.c index a8477607..5e5dc58c 100644 --- a/fwd.c +++ b/fwd.c @@ -331,7 +331,7 @@ void fwd_table_add(struct fwd_ports *fwd, uint8_t flags, in_port_t first, in_port_t last, in_port_t to) { /* Flags which can be set from the caller */ - const uint8_t allowed_flags = FWD_WEAK; + const uint8_t allowed_flags = FWD_WEAK | FWD_SCAN; struct fwd_entry *new; ASSERT(!(flags & ~allowed_flags)); @@ -371,6 +371,7 @@ void fwd_table_print(const struct fwd_ports *fwd) for (i = 0; i < fwd->count; i++) { const struct fwd_entry *fe = &fwd->tab[i]; const char *weak = fe->flags & FWD_WEAK ? " WEAK" : ""; + const char *scan = fe->flags & FWD_SCAN ? " AUTO" : ""; const char *percent = *fe->ifname ? "%" : ""; char addr[INANY_ADDRSTRLEN] = "*"; @@ -378,13 +379,14 @@ void fwd_table_print(const struct fwd_ports *fwd) inany_ntop(&fe->addr, addr, sizeof(addr)); if (fe->first == fe->last) { - info(" [%s]%s%s:%hu => %hu %s", + info(" [%s]%s%s:%hu => %hu %s%s", addr, percent, fe->ifname, - fe->first, fe->to, weak); + fe->first, fe->to, weak, scan); } else { - info(" [%s]%s%s:%hu-%hu => %hu-%hu %s", + info(" [%s]%s%s:%hu-%hu => %hu-%hu %s%s", addr, percent, fe->ifname, fe->first, fe->last, - fe->to, fe->last - fe->first + fe->to, weak); + fe->to, fe->last - fe->first + fe->to, + weak, scan); } } } diff --git a/fwd.h b/fwd.h index 21f00cf8..eef507c6 100644 --- a/fwd.h +++ b/fwd.h @@ -26,6 +26,7 @@ bool fwd_port_is_ephemeral(in_port_t port); * @flags: Flag mask * FWD_DUAL_STACK - forward both IPv4 and IPv6 (requires @addr be ::) * FWD_WEAK - Don't give an error if binds fail for some forwards + * FWD_SCAN - Only forward if we scan a listener on the target * * FIXME: @addr and @ifname currently ignored for outbound tables */ @@ -35,6 +36,7 @@ struct fwd_entry { in_port_t first, last, to; #define FWD_DUAL_STACK BIT(0) #define FWD_WEAK BIT(1) +#define FWD_SCAN BIT(2) uint8_t flags; }; -- 2.52.0