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 07/12] parse: Move parse_port_range() to new parsing framework
Date: Fri, 26 Jun 2026 17:09:58 +1000 [thread overview]
Message-ID: <20260626071003.3472194-8-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260626071003.3472194-1-david@gibson.dropbear.id.au>
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 <david@gibson.dropbear.id.au>
---
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 '<first>[-<last>]'
- * @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 8abfd4dd..bd091fde 100644
--- a/parse.c
+++ b/parse.c
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "parse.h"
/**
@@ -82,3 +83,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 '<first>[-<last>]'
+ * @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 <stdbool.h>
+#include <netinet/in.h>
+
+/**
+ * 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
next prev parent reply other threads:[~2026-06-26 7:10 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 7:09 [PATCH 00/12] Rework option parsing in preparation for destination remapping David Gibson
2026-06-26 7:09 ` [PATCH 01/12] Makefile: Add missing PESTO_HEADERS variable David Gibson
2026-06-26 7:09 ` [PATCH 02/12] conf: Use parameter instead of global in conf_nat() David Gibson
2026-06-26 7:09 ` [PATCH 03/12] parse: Start splitting out parsing helpers David Gibson
2026-06-26 7:09 ` [PATCH 04/12] conf: Remove duplicate parsing of -F option David Gibson
2026-06-26 7:09 ` [PATCH 05/12] conf: Clean up conf_ip4_prefix() David Gibson
2026-06-26 7:09 ` [PATCH 06/12] parse: Add helper to parse unsigned integer values David Gibson
2026-06-26 7:09 ` David Gibson [this message]
2026-06-26 7:09 ` [PATCH 08/12] parse: Add helpers for parsing IP addresses David Gibson
2026-06-26 7:10 ` [PATCH 09/12] conf: Move address configuration into helper function David Gibson
2026-06-26 7:10 ` [PATCH 10/12] conf: Use new parsing tools to handle -a option David Gibson
2026-06-26 7:10 ` [PATCH 11/12] fwd_rule: Allow "all" port specs to be combined with other options David Gibson
2026-06-26 7:10 ` [PATCH 12/12] fwd_rule: Rewrite forward rule parsing using parse.c helpers David Gibson
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=20260626071003.3472194-8-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).