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=202606 header.b=ReLdm18F; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 037DE5A0652 for ; Thu, 02 Jul 2026 02:59:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202606; t=1782953982; bh=kQVD3ldJ5EgAxS2WacEwUf2RIoU8T74/juXSRv+yu/A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ReLdm18FnNYVLdITvmlj347K03E1fId1/j4XRiXtp+hRgWR+Ah81J6tySOUpzEKhy 67BkONIu1wg5F3ULV5+t8CslBCkYjsQFOjAutKObW47y18GAvJj2C9XFwGziafFv8d OmsWvv0UaSm62aeo9l2bOAMMLoy7O12h3WBQj5B+htliCGK2Ovm9xHEPOWU1Ophtku aP4KD6Wy0ZMT/u4myT0GSV79sul4Xe1dE3jWIS4GQYk86BKi7H5lKkPMbjDlm3INkr /R4GsXCOa9xy0K3pYWoHCvgqVK99owHN5JKLyHt+p9EQDee51NaoStcODlDID8JTFh KQIFQ9QsYOHYQ== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4grJSZ1NZ3z58mg; Thu, 02 Jul 2026 10:59:42 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v3 07/13] parse: Move parse_port_range() to new parsing framework Date: Thu, 2 Jul 2026 10:58:55 +1000 Message-ID: <20260702005901.2010709-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260702005901.2010709-1-david@gibson.dropbear.id.au> References: <20260702005901.2010709-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: JJZMYXJ5TT4646ZAKLFP5F4U535HZY4B X-Message-ID-Hash: JJZMYXJ5TT4646ZAKLFP5F4U535HZY4B 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: parse_port_range() in fwd_rule.c takes an approach similar to that used by the new parsing helpers in parse.c (and is partially inspiration for it), but isn't quite the same. Move it into parse.c, and bring it into line with that file's conventions. Signed-off-by: David Gibson --- common.h | 3 +++ fwd_rule.c | 53 +++-------------------------------------------------- fwd_rule.h | 2 -- parse.c | 28 ++++++++++++++++++++++++++++ parse.h | 13 +++++++++++++ 5 files changed, 47 insertions(+), 52 deletions(-) diff --git a/common.h b/common.h index f2518f66..16b9dc8c 100644 --- a/common.h +++ b/common.h @@ -113,4 +113,7 @@ static inline const char *strerror_(int errnum) #define ntohll(x) (be64toh((x))) #define htonll(x) (htobe64((x))) +/* Number of ports for both TCP and UDP */ +#define NUM_PORTS (1U << 16) + #endif /* COMMON_H */ diff --git a/fwd_rule.c b/fwd_rule.c index d4b422d7..0b85b17e 100644 --- a/fwd_rule.c +++ b/fwd_rule.c @@ -367,53 +367,6 @@ int fwd_rule_add(struct fwd_table *fwd, const struct fwd_rule *new) return 0; } -/** - * port_range() - Represents a non-empty range of ports - * @first: First port number in the range - * @last: Last port number in the range (inclusive) - * - * Invariant: @last >= @first - */ -struct port_range { - in_port_t first, last; -}; - -/** - * parse_port_range() - Parse a range of port numbers '[-]' - * @s: String to parse - * @endptr: Update to the character after the parsed range (similar to - * strtol() etc.) - * @range: Update with the parsed values on success - * - * Return: -EINVAL on parsing error, -ERANGE on out of range port - * numbers, 0 on success - */ -static int parse_port_range(const char *s, const char **endptr, - struct port_range *range) -{ - unsigned long first, last; - char *ep; - - last = first = strtoul(s, &ep, 10); - if (ep == s) /* Parsed nothing */ - return -EINVAL; - if (*ep == '-') { /* we have a last value too */ - const char *lasts = ep + 1; - last = strtoul(lasts, &ep, 10); - if (ep == lasts) /* Parsed nothing */ - return -EINVAL; - } - - if ((last < first) || (last >= NUM_PORTS)) - return -ERANGE; - - range->first = first; - range->last = last; - *endptr = ep; - - return 0; -} - /** * fwd_rule_range_except() - Set up forwarding for a range of ports minus a * bitmap of exclusions @@ -550,7 +503,7 @@ static void fwd_rule_parse_ports(struct fwd_table *fwd, bool del, uint8_t proto, if (!parse_literal(&p, "~")) goto bad; - if (parse_port_range(p, &p, &xrange)) + if (!parse_port_range(&p, &xrange)) goto bad; if (p != ep) /* Garbage after the range */ goto bad; @@ -577,12 +530,12 @@ static void fwd_rule_parse_ports(struct fwd_table *fwd, bool del, uint8_t proto, /* Already parsed */ continue; - if (parse_port_range(p, &p, &orig_range)) + if (!parse_port_range(&p, &orig_range)) goto bad; if (parse_literal(&p, ":")) { /* There's a range to map to as well */ - if (parse_port_range(p, &p, &mapped_range)) + if (!parse_port_range(&p, &mapped_range)) goto bad; if ((mapped_range.last - mapped_range.first) != (orig_range.last - orig_range.first)) diff --git a/fwd_rule.h b/fwd_rule.h index ae9a3cb0..435be5bd 100644 --- a/fwd_rule.h +++ b/fwd_rule.h @@ -18,8 +18,6 @@ #include "inany.h" #include "bitmap.h" -/* Number of ports for both TCP and UDP */ -#define NUM_PORTS (1U << 16) #define PORT_BITMAP_SIZE DIV_ROUND_UP(NUM_PORTS, 8) /* Forwarding capability bits */ diff --git a/parse.c b/parse.c index 9bd0e81f..ad210406 100644 --- a/parse.c +++ b/parse.c @@ -17,6 +17,7 @@ #include #include +#include "common.h" #include "parse.h" /** @@ -83,3 +84,30 @@ bool parse_unsigned(const char **cursor, int base, unsigned long *valp) *cursor = p; return true; } + +/** + * parse_port_range() - Parse a range of port numbers '[-]' + * @range: Update with the parsed values on success + */ +bool parse_port_range(const char **cursor, struct port_range *range) +{ + unsigned long first, last; + const char *p = *cursor; + + if (!parse_unsigned(&p, 10, &first)) + return false; + + last = first; + + if (parse_literal(&p, "-")) + if (!parse_unsigned(&p, 10, &last)) + return false; + + if ((last < first) || (last >= NUM_PORTS)) + return false; + + range->first = first; + range->last = last; + *cursor = p; + return true; +} diff --git a/parse.h b/parse.h index 4f38c28b..155b3995 100644 --- a/parse.h +++ b/parse.h @@ -7,9 +7,22 @@ #define PARSE_H #include +#include + +/** + * port_range() - Represents a non-empty range of ports + * @first: First port number in the range + * @last: Last port number in the range (inclusive) + * + * Invariant: @last >= @first + */ +struct port_range { + in_port_t first, last; +}; bool parse_literal(const char **cursor, const char *lit); bool parse_eoi(const char *cursor); bool parse_unsigned(const char **cursor, int base, unsigned long *valp); +bool parse_port_range(const char **cursor, struct port_range *range); #endif /* _PARSE_H */ -- 2.54.0