<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/conf.c, branch bug209</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>fwd: Clarify semantics of --host-lo-to-ns-lo</title>
<updated>2026-07-09T01:02:34+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-06-30T04:09:47+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0d91b54eaf2ba12e584e6be985804b153cd792f6'/>
<id>0d91b54eaf2ba12e584e6be985804b153cd792f6</id>
<content type='text'>
The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoreically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with upcoming remapping of target address by forwarding rules.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoreically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with upcoming remapping of target address by forwarding rules.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>isolation: Add --chroot-fallback option</title>
<updated>2026-07-08T19:41:33+00:00</updated>
<author>
<name>Mateusz Andrzejewski</name>
<email>mandrzejewski06@gmail.com</email>
</author>
<published>2026-07-02T07:13:31+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=6ef3d1c86ffc690a17a9a4445df4a741446bcd44'/>
<id>6ef3d1c86ffc690a17a9a4445df4a741446bcd44</id>
<content type='text'>
For integrations, which use rootfs on tmpfs or initramfs, it is not
allowed to use pivot_root(). It results with invalid argument (EINVAL)
error. Introduce --chroot-fallback option as a workaround with
MS_MOVE + chroot().

Due to weaker isolation of chroot() method (we don't unmount old root),
user has tu explicitly enable fallback with the new option. First,
always try to sandbox with pivot_root(). In both cases the new root is
placed into an empty tmpfs.

For the solution to work we keep CAP_SYS_CHROOT capability, which is
dropped at the end of the isolate_prefork() function.

Link: https://bugs.passt.top/show_bug.cgi?id=104
Signed-off-by: Mateusz Andrzejewski &lt;mateusz.andrzejewski@mikronika.com.pl&gt;
[sbrivio: Minor tweaks to comments, usage, man page]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For integrations, which use rootfs on tmpfs or initramfs, it is not
allowed to use pivot_root(). It results with invalid argument (EINVAL)
error. Introduce --chroot-fallback option as a workaround with
MS_MOVE + chroot().

Due to weaker isolation of chroot() method (we don't unmount old root),
user has tu explicitly enable fallback with the new option. First,
always try to sandbox with pivot_root(). In both cases the new root is
placed into an empty tmpfs.

For the solution to work we keep CAP_SYS_CHROOT capability, which is
dropped at the end of the isolate_prefork() function.

Link: https://bugs.passt.top/show_bug.cgi?id=104
Signed-off-by: Mateusz Andrzejewski &lt;mateusz.andrzejewski@mikronika.com.pl&gt;
[sbrivio: Minor tweaks to comments, usage, man page]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd_rule: Allow "all" port specs to be combined with other options</title>
<updated>2026-07-04T11:14:30+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:44+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0581b0ab0f58d5c2fa4cb06ab614055749c4404b'/>
<id>0581b0ab0f58d5c2fa4cb06ab614055749c4404b</id>
<content type='text'>
Currently we handle -t all and the like as a special case, it can't be
combined with other port specifier options.  Remove that restriction,
allowing combined options like:
     -t all,~9999          # Forward everything non-ephemeral except 9999
     -t all,auto           # Equivalent to -t auto
     -t all,33000          # Forward non-ephemeral plus port 33,000

This isn't particularly useful immediately, but will become important for
destination address specification - it provides a place to attach the
target address for "all" or exclude only mappings.  It will also work
better with some parsing reworks we want to make.

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>
Currently we handle -t all and the like as a special case, it can't be
combined with other port specifier options.  Remove that restriction,
allowing combined options like:
     -t all,~9999          # Forward everything non-ephemeral except 9999
     -t all,auto           # Equivalent to -t auto
     -t all,33000          # Forward non-ephemeral plus port 33,000

This isn't particularly useful immediately, but will become important for
destination address specification - it provides a place to attach the
target address for "all" or exclude only mappings.  It will also work
better with some parsing reworks we want to make.

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>conf: Remove unnecessary mode checks from conf_addr()</title>
<updated>2026-07-04T11:14:22+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:42+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=b1d400f40ed3507acdc69d1c8d52ce61c8d3b80d'/>
<id>b1d400f40ed3507acdc69d1c8d52ce61c8d3b80d</id>
<content type='text'>
conf_addr() sets c-&gt;ip[46]no_copy_addrs conditional upon being in pasta
mode.  That sort of makes sense, since address copying is only a thing for
pasta mode.  However, setting the variables anyway is harmless, and
arguably more logically consistent.  If we had a way of copying addresses
for passt mode (or some future mode), it would still be incorrect to do so
in these circumstances.

So, make the assignments unconditional.

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>
conf_addr() sets c-&gt;ip[46]no_copy_addrs conditional upon being in pasta
mode.  That sort of makes sense, since address copying is only a thing for
pasta mode.  However, setting the variables anyway is harmless, and
arguably more logically consistent.  If we had a way of copying addresses
for passt mode (or some future mode), it would still be incorrect to do so
in these circumstances.

So, make the assignments unconditional.

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: Move address configuration into helper function</title>
<updated>2026-07-04T11:14:15+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:41+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=aaa0482d5aa64b1414dc91f35aa6335138cb14cf'/>
<id>aaa0482d5aa64b1414dc91f35aa6335138cb14cf</id>
<content type='text'>
The handling of the -a option is getting complex enough that it's pretty
bulky inside its switch label.  Move it into a new conf_addr() function.
We also rename the bulky addr_has_prefix_len and prefix_len_from_opt
variables to the terser 'opt_a_is_prefix' and 'opt_n', since they are
specifically about those command line options.

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 handling of the -a option is getting complex enough that it's pretty
bulky inside its switch label.  Move it into a new conf_addr() function.
We also rename the bulky addr_has_prefix_len and prefix_len_from_opt
variables to the terser 'opt_a_is_prefix' and 'opt_n', since they are
specifically about those command line options.

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: 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>conf: Clean up conf_ip4_prefix()</title>
<updated>2026-07-04T11:14:02+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:37+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=9f8fcdcf96aff9c872189b081d62b1a061579b20'/>
<id>9f8fcdcf96aff9c872189b081d62b1a061579b20</id>
<content type='text'>
Restructure conf_ip4_prefix() so that success is the early exit path and
failure is the "default" path.  Also move the error handling (die()) into
it from the caller.

This saves a handful of lines for now, and will make integration with
upcoming parsing changes nicer.

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>
Restructure conf_ip4_prefix() so that success is the early exit path and
failure is the "default" path.  Also move the error handling (die()) into
it from the caller.

This saves a handful of lines for now, and will make integration with
upcoming parsing changes nicer.

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: Remove duplicate parsing of -F option</title>
<updated>2026-07-04T11:13:59+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-03T03:54:36+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=2cdb27a32f3d494109d7eb3737fb7362340515c1'/>
<id>2cdb27a32f3d494109d7eb3737fb7362340515c1</id>
<content type='text'>
The -F option is parsed in conf() along with everything else.  However,
because it informs what fds we can close at startup, we also have a special
case parse of it in close_open_files().

At present we duplicate the parsing and validation code, which is a bit
risky.  Avoid that with a conf_tap_fd() helper.

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 -F option is parsed in conf() along with everything else.  However,
because it informs what fds we can close at startup, we also have a special
case parse of it in close_open_files().

At present we duplicate the parsing and validation code, which is a bit
risky.  Avoid that with a conf_tap_fd() helper.

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>
