<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/parse.h, branch master</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>fwd_rule: Rewrite forward rule parsing using parse.c helpers</title>
<updated>2026-07-04T11:14:32+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:45+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=bf2103815db917e532cad0b9b3530604de463d5a'/>
<id>bf2103815db917e532cad0b9b3530604de463d5a</id>
<content type='text'>
Forwarding rules for the -[tTuU] options are parsed in fwd_rule_parse()
and fwd_rule_parse_ports().  Currently those use a mix of loosely
recursive descent parsing helpers, consuming input from left to right,
and ad-hoc C parsing - searching for delimiters with strchr() or the like
and breaking down on that basis.

As well as being a slightly awkward mix, the current approach will not work
for adding target addresses to the rules: we can't easily split the
listening from target parts first, because the ':' delimiter could appear
multiple times for multiple port ranges, or in IPv6 addresses.  However,
without splitting the target part first, we can't first split off the
listening address and interface because the '/' delimiter could appear in
the target portion, but not the listening portion, e.g.:
    -t 12345:192.0.1.1/12345

To address this, rewrite the entirety of the parsing so we consume the
input left to right in a more-or-less recursive descent manner.  This means
we no longer rely on certain delimiters having a single meaning over the
whole input, just the next part of it.

Because of the semantics of port specs, we need to make several passes
over the list of comma separated chunks.  Previously, some of the logic was
duplicated between the two passes, making it fragile.  Now, we introduce
a parse_port_chunk() helper which we re-use in each pass to make it clearer
we parse exactly the same way on each pass.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Forwarding rules for the -[tTuU] options are parsed in fwd_rule_parse()
and fwd_rule_parse_ports().  Currently those use a mix of loosely
recursive descent parsing helpers, consuming input from left to right,
and ad-hoc C parsing - searching for delimiters with strchr() or the like
and breaking down on that basis.

As well as being a slightly awkward mix, the current approach will not work
for adding target addresses to the rules: we can't easily split the
listening from target parts first, because the ':' delimiter could appear
multiple times for multiple port ranges, or in IPv6 addresses.  However,
without splitting the target part first, we can't first split off the
listening address and interface because the '/' delimiter could appear in
the target portion, but not the listening portion, e.g.:
    -t 12345:192.0.1.1/12345

To address this, rewrite the entirety of the parsing so we consume the
input left to right in a more-or-less recursive descent manner.  This means
we no longer rely on certain delimiters having a single meaning over the
whole input, just the next part of it.

Because of the semantics of port specs, we need to make several passes
over the list of comma separated chunks.  Previously, some of the logic was
duplicated between the two passes, making it fragile.  Now, we introduce
a parse_port_chunk() helper which we re-use in each pass to make it clearer
we parse exactly the same way on each pass.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Use new parsing tools to handle -a option</title>
<updated>2026-07-04T11:14:25+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:43+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=289638b6d8cd22b5907af6ae1be6201e68103716'/>
<id>289638b6d8cd22b5907af6ae1be6201e68103716</id>
<content type='text'>
The -a command line option can take either an address prefix, or a bare
address.  Current parsing of this is pretty awkward, using the special
purpose helper inany_prefix_pton().  With the new incremental parsing
helpers this can be done more naturally.  Rework it to use them.

This does requiring extending parse_inany() to parse_inany_() which also
reports the format of the address as parse, as opposed to the family of
the resulting address.  This is so that ::ffff:192.0.1.1/112 will be
correctly interpreted the same as 192.0.1.1/16, rather than the
nonsensical 192.0.0.1/112.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The -a command line option can take either an address prefix, or a bare
address.  Current parsing of this is pretty awkward, using the special
purpose helper inany_prefix_pton().  With the new incremental parsing
helpers this can be done more naturally.  Rework it to use them.

This does requiring extending parse_inany() to parse_inany_() which also
reports the format of the address as parse, as opposed to the family of
the resulting address.  This is so that ::ffff:192.0.1.1/112 will be
correctly interpreted the same as 192.0.1.1/16, rather than the
nonsensical 192.0.0.1/112.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>parse: Add helpers for parsing IP addresses</title>
<updated>2026-07-04T11:14:09+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:40+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=11f4fba6a9a90efccf16d6438065d22c5878734a'/>
<id>11f4fba6a9a90efccf16d6438065d22c5878734a</id>
<content type='text'>
parse_ipv[46]() are wrappers around inet_pton() that are more
convenient for use when the IP is part of a longer string, rather than
the entire string.  parse_inany() replaces inany_pton() which again
will become more convenient for strings including IPs that aren't just
an IP.

For now we only have some simple and sometimes awkward use cases,
we'll replace these with more natural uses in future.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
parse_ipv[46]() are wrappers around inet_pton() that are more
convenient for use when the IP is part of a longer string, rather than
the entire string.  parse_inany() replaces inany_pton() which again
will become more convenient for strings including IPs that aren't just
an IP.

For now we only have some simple and sometimes awkward use cases,
we'll replace these with more natural uses in future.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>parse: Move parse_port_range() to new parsing framework</title>
<updated>2026-07-04T11:14:07+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:39+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=42069134e9ff3cbcb35dccf92a0a044a4b71999b'/>
<id>42069134e9ff3cbcb35dccf92a0a044a4b71999b</id>
<content type='text'>
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 &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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 &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>parse: Add helper to parse unsigned integer values</title>
<updated>2026-07-04T11:14:04+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:38+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8ffff9b9fca92afb785a37ddde1397805122befc'/>
<id>8ffff9b9fca92afb785a37ddde1397805122befc</id>
<content type='text'>
Most places we need to parse an integer encoded as a string, we use
strtol() or strtoul().  These already work a bit like descent parser
helpers, in that they consume as much as they can, but don't require the
number parsed to be the whole of the einput string.  Make a wrapper to
parse unsigned integers as part of our parsing helper.  This wrapper
handles the mildly fiddly error checking requirements for strtoul().

We replace a number, though not all, of our existing strtoul() uses with
the new parse_unsigned().  We also replace a number of strtol() use cases,
because, despite using that instead of strtoul() they are only used for
non-negative values.  In some cases this makes the logic a little more
straightforward.  In some other cases it will catch some error cases we
previously could have missed.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Most places we need to parse an integer encoded as a string, we use
strtol() or strtoul().  These already work a bit like descent parser
helpers, in that they consume as much as they can, but don't require the
number parsed to be the whole of the einput string.  Make a wrapper to
parse unsigned integers as part of our parsing helper.  This wrapper
handles the mildly fiddly error checking requirements for strtoul().

We replace a number, though not all, of our existing strtoul() uses with
the new parse_unsigned().  We also replace a number of strtol() use cases,
because, despite using that instead of strtoul() they are only used for
non-negative values.  In some cases this makes the logic a little more
straightforward.  In some other cases it will catch some error cases we
previously could have missed.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>parse: Start splitting out parsing helpers</title>
<updated>2026-07-04T11:13:56+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:35+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=d29eb296a3004d435914d8be05d3bdb9e44bc755'/>
<id>d29eb296a3004d435914d8be05d3bdb9e44bc755</id>
<content type='text'>
As we add more complexity to what forwarding rules are allowed, our
existing ad-hoc C parsing is starting to become quite awkward.  We already
have some parts that resemble a very simple recursive[0] descent parser,
with composable subfunctions that consume as much input as they need,
rather than pre-splitting based on known delimiters.

Start extending this approach, by creating parse.[ch] with parsing helpers
with a uniform interface.  Initially we start with very simple cases: the
parse_keyword() function from fwd_rule.c and another helper to check that
we've reached the end of input.

Rename parse_keyword() to parse_literal(), because it's not just useful
for "keywords" as such.  We can use it in a bunch of additional places for
parsing delimiters and other symbols.  This doesn't gain us a lot now but
will make things clearer as we use more such parser helpers.

[0] Except that the grammars we have aren't actually recursive, so neither
    is the code.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As we add more complexity to what forwarding rules are allowed, our
existing ad-hoc C parsing is starting to become quite awkward.  We already
have some parts that resemble a very simple recursive[0] descent parser,
with composable subfunctions that consume as much input as they need,
rather than pre-splitting based on known delimiters.

Start extending this approach, by creating parse.[ch] with parsing helpers
with a uniform interface.  Initially we start with very simple cases: the
parse_keyword() function from fwd_rule.c and another helper to check that
we've reached the end of input.

Rename parse_keyword() to parse_literal(), because it's not just useful
for "keywords" as such.  We can use it in a bunch of additional places for
parsing delimiters and other symbols.  This doesn't gain us a lot now but
will make things clearer as we use more such parser helpers.

[0] Except that the grammars we have aren't actually recursive, so neither
    is the code.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
