<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/conf.c, branch 2026_07_28.f8df3f1</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>conf, fwd: Prefer same-scope address as inbound source address from host</title>
<updated>2026-07-28T16:09:27+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-22T22:14:39+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=4c9ec30abbcac635a989a1929a4fcb10d6d4bb9e'/>
<id>4c9ec30abbcac635a989a1929a4fcb10d6d4bb9e</id>
<content type='text'>
We might have situations, such as the one described in
https://bugs.passt.top/show_bug.cgi?id=217, where using a link-local
address as source in a given namespace doesn't guarantee that we can
reach the intended destination, because, for instance, the inbound
traffic we forward is in turn forwarded to a different interface, such
as a bridge.

In that case, the assumption from 9618d247006a ("ndp, dhcpv6, tcp,
udp: Always use link-local as source if gateway isn't") isn't a safe
one: the user might have specified a valid gateway address, matching
the scope of the destination address, but we won't use it as address
of last resort, and prefer a link-local address with a mismatch in
scope instead.

So, if the user specifies a given default gateway address for IPv6,
note that as 'our_tap_addr', like we would do with with IPv4, and
stick to Rule 2 of RFC 6724, Section 5, when selecting a source
address, by preferring an address with the same scope, if available.

Note that this preference will be applied only if, at the point of
the source address selection, the destination address is already
known, which, in general, only happens if there's an explicit mapping
rule specifying the target destination address.

Otherwise, if there's no explicit rule picking the destination
address, we select the destination address after selecting the source
address. This should probably be improved at some point, to select
matching address pairs (when a compatible one is available) instead of
sequentially picking source and destination addresses. That appears to
be beyond the scope of this patch, though.

Reported-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=217
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We might have situations, such as the one described in
https://bugs.passt.top/show_bug.cgi?id=217, where using a link-local
address as source in a given namespace doesn't guarantee that we can
reach the intended destination, because, for instance, the inbound
traffic we forward is in turn forwarded to a different interface, such
as a bridge.

In that case, the assumption from 9618d247006a ("ndp, dhcpv6, tcp,
udp: Always use link-local as source if gateway isn't") isn't a safe
one: the user might have specified a valid gateway address, matching
the scope of the destination address, but we won't use it as address
of last resort, and prefer a link-local address with a mismatch in
scope instead.

So, if the user specifies a given default gateway address for IPv6,
note that as 'our_tap_addr', like we would do with with IPv4, and
stick to Rule 2 of RFC 6724, Section 5, when selecting a source
address, by preferring an address with the same scope, if available.

Note that this preference will be applied only if, at the point of
the source address selection, the destination address is already
known, which, in general, only happens if there's an explicit mapping
rule specifying the target destination address.

Otherwise, if there's no explicit rule picking the destination
address, we select the destination address after selecting the source
address. This should probably be improved at some point, to select
matching address pairs (when a compatible one is available) instead of
sequentially picking source and destination addresses. That appears to
be beyond the scope of this patch, though.

Reported-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=217
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf: Honour --address, --gateway, --netmask in local mode as well</title>
<updated>2026-07-28T16:01:00+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-22T21:41:50+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=4e8aa70379a35ec9deb11d76513e7f6c4123b667'/>
<id>4e8aa70379a35ec9deb11d76513e7f6c4123b667</id>
<content type='text'>
When I implemented local mode in 14b84a7f077e ("treewide: Introduce
'local mode' for disconnected setups"), I didn't consider the
possibility that, also in that case, the user might want to override
addresses, default gateway or netmask, even though I expressly
mentioned this in the man page:

  In this case, **unless configured otherwise**, they will assign the
  IPv4 link-local address 169.254.2.1 to the guest or target
  namespace, and no IPv6 address.

Fix this by checking if an address, gateway, or netmask length was
explicitly set by the user, before overriding them with the default
parameters for local mode.

This might lead to invalid configurations where we won't be able to
set the default gateway passed by the user, but we print a warning
message, and we assume users know what they're doing in that case.

Link: https://bugs.passt.top/show_bug.cgi?id=217
Fixes: 14b84a7f077e ("treewide: Introduce 'local mode' for disconnected setups")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When I implemented local mode in 14b84a7f077e ("treewide: Introduce
'local mode' for disconnected setups"), I didn't consider the
possibility that, also in that case, the user might want to override
addresses, default gateway or netmask, even though I expressly
mentioned this in the man page:

  In this case, **unless configured otherwise**, they will assign the
  IPv4 link-local address 169.254.2.1 to the guest or target
  namespace, and no IPv6 address.

Fix this by checking if an address, gateway, or netmask length was
explicitly set by the user, before overriding them with the default
parameters for local mode.

This might lead to invalid configurations where we won't be able to
set the default gateway passed by the user, but we print a warning
message, and we assume users know what they're doing in that case.

Link: https://bugs.passt.top/show_bug.cgi?id=217
Fixes: 14b84a7f077e ("treewide: Introduce 'local mode' for disconnected setups")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pasta: Do not configure ID mappings when invoked with --netns-only</title>
<updated>2026-07-23T09:46:49+00:00</updated>
<author>
<name>Dwayne B. Bent</name>
<email>dbb@dbb.dev</email>
</author>
<published>2026-07-22T15:32:41+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=ffa5cee6bb781d7ced19a69659c3d443ea734163'/>
<id>ffa5cee6bb781d7ced19a69659c3d443ea734163</id>
<content type='text'>
Add a `bool` argument `config_idmaps` to `pasta_start_ns()` that guards
the logic to configure user and group ID mappings. It is set to `false`
when `netns_only` is `true`. Fixes bug 216.

Link: https://bugs.passt.top/show_bug.cgi?id=216
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Dwayne B. Bent &lt;dbb@dbb.dev&gt;
Reviewed-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>
Add a `bool` argument `config_idmaps` to `pasta_start_ns()` that guards
the logic to configure user and group ID mappings. It is set to `false`
when `netns_only` is `true`. Fixes bug 216.

Link: https://bugs.passt.top/show_bug.cgi?id=216
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Dwayne B. Bent &lt;dbb@dbb.dev&gt;
Reviewed-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>isolation: Move --fd descriptor to a number of our choosing</title>
<updated>2026-07-18T07:54:31+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:33+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=fd5b0807f5d0706e9247662f26c31b6bc8337f19'/>
<id>fd5b0807f5d0706e9247662f26c31b6bc8337f19</id>
<content type='text'>
Some users of passt pass an fd for the tap interface in, with the --fd
parameter, rather than having passt open it itself.  This requires some
slightly fiddly logic in isolate_fds() so we don't close() it along with
any other file descriptors leaked into us by the parent.

More importantly, this is broken if the passed fd is 0, 1 or 2, since in
that case we will assume it's a standard stream and close it in __daemon().
We explicitly disallow 1 or 2 in conf_tap_fd(), but 0 has been permitted
since aa1cc8922 ("conf: allow --fd 0").  It looks like the use case of the
contributor of that patch didn't involve daemonizing passt.

To fix this more robustly, use dup2() to move to the passed fd to 3.  This
removes the possibility of mixing it up with a standard stream, and as a
bonus makes the close_range() logic much simpler.  With isolate_fds() made
safe for --fd 1 and --fd 2, we can remove the logic excluding those from
conf_fd_tap().

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>
Some users of passt pass an fd for the tap interface in, with the --fd
parameter, rather than having passt open it itself.  This requires some
slightly fiddly logic in isolate_fds() so we don't close() it along with
any other file descriptors leaked into us by the parent.

More importantly, this is broken if the passed fd is 0, 1 or 2, since in
that case we will assume it's a standard stream and close it in __daemon().
We explicitly disallow 1 or 2 in conf_tap_fd(), but 0 has been permitted
since aa1cc8922 ("conf: allow --fd 0").  It looks like the use case of the
contributor of that patch didn't involve daemonizing passt.

To fix this more robustly, use dup2() to move to the passed fd to 3.  This
removes the possibility of mixing it up with a standard stream, and as a
bonus makes the close_range() logic much simpler.  With isolate_fds() made
safe for --fd 1 and --fd 2, we can remove the logic excluding those from
conf_fd_tap().

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: Make conf_tap_fd() operate more like conf_mode()</title>
<updated>2026-07-18T07:54:29+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:32+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=ab825955836cb04c1e994d17af4c50a243ea67a0'/>
<id>ab825955836cb04c1e994d17af4c50a243ea67a0</id>
<content type='text'>
We have two cases where we need to parse specific options early:
conf_tap_fd() and conf_mode().  conf_tap_fd() has a slightly odd interface,
requiring the caller to use getopt_long() to find the right option, then
pass it in.  Alter it to work like conf_mode() instead, where all the
command line parsing logic is contained within the conf.c function.

This is slightly more lines, but has a clearer division of responsibility.

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>
We have two cases where we need to parse specific options early:
conf_tap_fd() and conf_mode().  conf_tap_fd() has a slightly odd interface,
requiring the caller to use getopt_long() to find the right option, then
pass it in.  Alter it to work like conf_mode() instead, where all the
command line parsing logic is contained within the conf.c function.

This is slightly more lines, but has a clearer division of responsibility.

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>isolation, conf: Set c-&gt;fd_tap from early parse of --fd</title>
<updated>2026-07-18T07:54:27+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:31+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=33e0fbc396f494e2fdd8033191b76d2c4aef43ec'/>
<id>33e0fbc396f494e2fdd8033191b76d2c4aef43ec</id>
<content type='text'>
We parse --fd twice: once in isolate_initial() just to avoid clobbering
the passed in fd.  Then we parse it "for real" in conf(), to set c-&gt;fd_tap
and other configuration variables.

Change this, so that we return the value parsed early from
isolate_initial() and set c-&gt;fd_tap from that.  This doesn't accomplish
much immediately, but will make some further cleanups possible.

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>
We parse --fd twice: once in isolate_initial() just to avoid clobbering
the passed in fd.  Then we parse it "for real" in conf(), to set c-&gt;fd_tap
and other configuration variables.

Change this, so that we return the value parsed early from
isolate_initial() and set c-&gt;fd_tap from that.  This doesn't accomplish
much immediately, but will make some further cleanups possible.

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>fwd: Clarify semantics of --host-lo-to-ns-lo</title>
<updated>2026-07-14T23:22:40+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-13T05:38:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=26f2130de6dc3bba45bfab435531d909d219f7a6'/>
<id>26f2130de6dc3bba45bfab435531d909d219f7a6</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 theoretically, 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 other upcoming changes to the forwarding logic.

Link: https://bugs.passt.top/show_bug.cgi?id=212
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 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 theoretically, 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 other upcoming changes to the forwarding logic.

Link: https://bugs.passt.top/show_bug.cgi?id=212
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>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>
</feed>
