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=202602 header.b=XopRLg8U; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id C34355A0775 for ; Fri, 10 Apr 2026 03:03:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1775782993; bh=d63iVd0vjnpW3UbaMz42nE15SXLrxUx/6AVRwRlR92Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XopRLg8UTEQ4Mut3MG8JfujglKtL9Tgp/anVbmFOmcDZhhKaF8arf2YYC2Yo1snDc 1Ik7eBYFOvlyaFVwqhvfzwn+5RmWwdLjjBXZ9V5fzWQMRlNvNV4CPudqGq7MYtPTFf w4qdHpnnRE/D+ZLo0TgqCV3NAfuDlQSkD32z0Lqjo7q4vOuNl87hceCw+IH7TDS/OZ KNsO7CFnbyul9vkMQ9CAsP+BnbrZFZBZNvjb2QTmYxiUoH/yKXUIcw7TiayqDZaGAr Fl0ioYSG2ZNL8bp6R58SB/vF4dxDtCvRpHqETTpiAEaOewgLjEh+sKOCCDZMaB4Eo2 +LmABro/0WHNA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fsJSx1jNwz4wpy; Fri, 10 Apr 2026 11:03:13 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 22/23] fwd_rule: Move ephemeral port probing to fwd_rule.c Date: Fri, 10 Apr 2026 11:03:08 +1000 Message-ID: <20260410010309.736855-23-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260410010309.736855-1-david@gibson.dropbear.id.au> References: <20260410010309.736855-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 6RTLXHTC57RLHLC6IGHYCRZDWSNL5G4F X-Message-ID-Hash: 6RTLXHTC57RLHLC6IGHYCRZDWSNL5G4F 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: We want to move parsing of forward rule options to fwd_rule.c so it can eventually be shared with a configuration client. As a preliminary step, move the ephemeral port probing there, which that will need to use. Signed-off-by: David Gibson --- fwd.c | 73 -------------------------------------------------- fwd.h | 6 ----- fwd_rule.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fwd_rule.h | 6 +++++ 4 files changed, 84 insertions(+), 79 deletions(-) diff --git a/fwd.c b/fwd.c index 98b04d0c..f2f7b648 100644 --- a/fwd.c +++ b/fwd.c @@ -34,12 +34,6 @@ #include "arp.h" #include "ndp.h" -/* Ephemeral port range: values from RFC 6335 */ -static in_port_t fwd_ephemeral_min = (1 << 15) + (1 << 14); -static in_port_t fwd_ephemeral_max = NUM_PORTS - 1; - -#define PORT_RANGE_SYSCTL "/proc/sys/net/ipv4/ip_local_port_range" - #define NEIGH_TABLE_SLOTS 1024 #define NEIGH_TABLE_SIZE (NEIGH_TABLE_SLOTS / 2) static_assert((NEIGH_TABLE_SLOTS & (NEIGH_TABLE_SLOTS - 1)) == 0, @@ -249,73 +243,6 @@ void fwd_neigh_table_init(const struct ctx *c) fwd_neigh_table_update(c, &mga, c->our_tap_mac, true); } -/** fwd_probe_ephemeral() - Determine what ports this host considers ephemeral - * - * Work out what ports the host thinks are emphemeral and record it for later - * use by fwd_port_is_ephemeral(). If we're unable to probe, assume the range - * recommended by RFC 6335. - */ -void fwd_probe_ephemeral(void) -{ - char *line, *tab, *end; - struct lineread lr; - long min, max; - ssize_t len; - int fd; - - fd = open(PORT_RANGE_SYSCTL, O_RDONLY | O_CLOEXEC); - if (fd < 0) { - warn_perror("Unable to open %s", PORT_RANGE_SYSCTL); - return; - } - - lineread_init(&lr, fd); - len = lineread_get(&lr, &line); - close(fd); - - if (len < 0) - goto parse_err; - - tab = strchr(line, '\t'); - if (!tab) - goto parse_err; - *tab = '\0'; - - errno = 0; - min = strtol(line, &end, 10); - if (*end || errno) - goto parse_err; - - errno = 0; - max = strtol(tab + 1, &end, 10); - if (*end || errno) - goto parse_err; - - if (min < 0 || min >= (long)NUM_PORTS || - max < 0 || max >= (long)NUM_PORTS) - goto parse_err; - - fwd_ephemeral_min = min; - fwd_ephemeral_max = max; - - return; - -parse_err: - warn("Unable to parse %s", PORT_RANGE_SYSCTL); -} - -/** - * fwd_port_map_ephemeral() - Mark ephemeral ports in a bitmap - * @map: Bitmap to update - */ -void fwd_port_map_ephemeral(uint8_t *map) -{ - unsigned port; - - for (port = fwd_ephemeral_min; port <= fwd_ephemeral_max; port++) - bitmap_set(map, port); -} - /* Forwarding table storage, generally accessed via pointers in struct ctx */ static struct fwd_table fwd_in; static struct fwd_table fwd_out; diff --git a/fwd.h b/fwd.h index 3e365d35..e664d1d0 100644 --- a/fwd.h +++ b/fwd.h @@ -20,12 +20,6 @@ struct flowside; -/* Number of ports for both TCP and UDP */ -#define NUM_PORTS (1U << 16) - -void fwd_probe_ephemeral(void); -void fwd_port_map_ephemeral(uint8_t *map); - #define FWD_RULE_BITS 8 #define MAX_FWD_RULES MAX_FROM_BITS(FWD_RULE_BITS) #define FWD_NO_HINT (-1) diff --git a/fwd_rule.c b/fwd_rule.c index 47d8df1c..9d489827 100644 --- a/fwd_rule.c +++ b/fwd_rule.c @@ -15,9 +15,87 @@ * Author: David Gibson */ +#include +#include #include +#include #include "fwd_rule.h" +#include "lineread.h" +#include "log.h" + +/* Ephemeral port range: values from RFC 6335 */ +static in_port_t fwd_ephemeral_min = (1 << 15) + (1 << 14); +static in_port_t fwd_ephemeral_max = NUM_PORTS - 1; + +#define PORT_RANGE_SYSCTL "/proc/sys/net/ipv4/ip_local_port_range" + +/** fwd_probe_ephemeral() - Determine what ports this host considers ephemeral + * + * Work out what ports the host thinks are emphemeral and record it for later + * use by fwd_port_is_ephemeral(). If we're unable to probe, assume the range + * recommended by RFC 6335. + */ +void fwd_probe_ephemeral(void) +{ + char *line, *tab, *end; + struct lineread lr; + long min, max; + ssize_t len; + int fd; + + fd = open(PORT_RANGE_SYSCTL, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + warn_perror("Unable to open %s", PORT_RANGE_SYSCTL); + return; + } + + lineread_init(&lr, fd); + len = lineread_get(&lr, &line); + close(fd); + + if (len < 0) + goto parse_err; + + tab = strchr(line, '\t'); + if (!tab) + goto parse_err; + *tab = '\0'; + + errno = 0; + min = strtol(line, &end, 10); + if (*end || errno) + goto parse_err; + + errno = 0; + max = strtol(tab + 1, &end, 10); + if (*end || errno) + goto parse_err; + + if (min < 0 || min >= (long)NUM_PORTS || + max < 0 || max >= (long)NUM_PORTS) + goto parse_err; + + fwd_ephemeral_min = min; + fwd_ephemeral_max = max; + + return; + +parse_err: + warn("Unable to parse %s", PORT_RANGE_SYSCTL); +} + +/** + * fwd_port_map_ephemeral() - Mark ephemeral ports in a bitmap + * @map: Bitmap to update + */ +void fwd_port_map_ephemeral(uint8_t *map) +{ + unsigned port; + + for (port = fwd_ephemeral_min; port <= fwd_ephemeral_max; port++) + bitmap_set(map, port); +} /** * fwd_rule_addr() - Return match address for a rule diff --git a/fwd_rule.h b/fwd_rule.h index edba6782..5c7b67aa 100644 --- a/fwd_rule.h +++ b/fwd_rule.h @@ -17,6 +17,9 @@ #include "inany.h" #include "bitmap.h" +/* Number of ports for both TCP and UDP */ +#define NUM_PORTS (1U << 16) + /* Forwarding capability bits */ #define FWD_CAP_IPV4 BIT(0) #define FWD_CAP_IPV6 BIT(1) @@ -51,6 +54,9 @@ struct fwd_rule { uint8_t flags; }; +void fwd_probe_ephemeral(void); +void fwd_port_map_ephemeral(uint8_t *map); + #define FWD_RULE_STRLEN \ (IPPROTO_STRLEN - 1 \ + INANY_ADDRSTRLEN - 1 \ -- 2.53.0