diff options
| author | David Gibson <david@gibson.dropbear.id.au> | 2026-05-03 23:55:45 +0200 |
|---|---|---|
| committer | Stefano Brivio <sbrivio@redhat.com> | 2026-05-07 08:06:30 +0200 |
| commit | 21d565d639cc1752a9981e7d2bfc3965069e45a7 (patch) | |
| tree | 74c38d03aac65700b7f64bd9c5d23105ae760587 | |
| parent | 0aeda87ca1855eac36842f602f8276762edffd1f (diff) | |
| download | passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.tar passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.tar.gz passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.tar.bz2 passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.tar.lz passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.tar.xz passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.tar.zst passt-21d565d639cc1752a9981e7d2bfc3965069e45a7.zip | |
fwd_rule: Move ephemeral port probing to fwd_rule.c
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 <david@gibson.dropbear.id.au>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
| -rw-r--r-- | fwd.c | 73 | ||||
| -rw-r--r-- | fwd.h | 6 | ||||
| -rw-r--r-- | fwd_rule.c | 78 | ||||
| -rw-r--r-- | fwd_rule.h | 6 |
4 files changed, 84 insertions, 79 deletions
@@ -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; @@ -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) @@ -15,9 +15,87 @@ * Author: David Gibson <david@gibson.dropbear.id.au> */ +#include <errno.h> +#include <fcntl.h> #include <stdio.h> +#include <unistd.h> #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 @@ -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 \ |
