<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt, 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>fwd: Don't log warnings when failing to bind "weak" ports, just debug messages</title>
<updated>2026-07-28T16:10:08+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-27T00:41:51+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=f8df3f1b228fe19a74a269334fdfe6cc7d0605ce'/>
<id>f8df3f1b228fe19a74a269334fdfe6cc7d0605ce</id>
<content type='text'>
When ports are forwarded by exclusion, we might fail to bind all
privileged ports (typically lower than 1024), but that's actually
expected, and we shouldn't log warnings just because of that.

Now, if those ports are automatically forwarded, and we have a
container binding some low ports, we'll log those warnings messages
every second, which is just unnecessary noise in the system log or
in log files.

Use LOG_DEBUG as severity for those messages, instead of LOG_WARNING,
so that they are only printed when --debug is given: that should be
convenient enough to investigate things, while avoiding excess noise
during regular operations.

There might be more sophisticated ways to limit this noise, but this
might be a significant regression in some setups, introduced by recent
changes in port forwarding handling, so I'm going for a somewhat
minimal fix for the moment, which can be improved later on if needed.

Reported-by: frajo &lt;frajo@frajo.fi&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=213
Fixes: b223bec48213 ("fwd, tcp, udp: Set up listening sockets based on forward table")
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 ports are forwarded by exclusion, we might fail to bind all
privileged ports (typically lower than 1024), but that's actually
expected, and we shouldn't log warnings just because of that.

Now, if those ports are automatically forwarded, and we have a
container binding some low ports, we'll log those warnings messages
every second, which is just unnecessary noise in the system log or
in log files.

Use LOG_DEBUG as severity for those messages, instead of LOG_WARNING,
so that they are only printed when --debug is given: that should be
convenient enough to investigate things, while avoiding excess noise
during regular operations.

There might be more sophisticated ways to limit this noise, but this
might be a significant regression in some setups, introduced by recent
changes in port forwarding handling, so I'm going for a somewhat
minimal fix for the moment, which can be improved later on if needed.

Reported-by: frajo &lt;frajo@frajo.fi&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=213
Fixes: b223bec48213 ("fwd, tcp, udp: Set up listening sockets based on forward table")
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>treewide: Sandbox qrap</title>
<updated>2026-07-28T16:09:54+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-18T07:32:57+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=12b02aaebcc69d4506b1a65ef8251fc0453a1d1b'/>
<id>12b02aaebcc69d4506b1a65ef8251fc0453a1d1b</id>
<content type='text'>
No sunsetting or rightsizing for you, qrap: dig, bury, and cover.

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>
No sunsetting or rightsizing for you, qrap: dig, bury, and cover.

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, 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: Regression test for bug 216</title>
<updated>2026-07-23T09:47:08+00:00</updated>
<author>
<name>Dwayne B. Bent</name>
<email>dbb@dbb.dev</email>
</author>
<published>2026-07-22T15:32:42+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=37a73a24512f967665d1d018d340f999ed888127'/>
<id>37a73a24512f967665d1d018d340f999ed888127</id>
<content type='text'>
Adds a test that asserts that when pasta is invoked via `unshare -r` in
standalone mode with `--netns-only` it does not print any warnings, and
the command executes successfully.

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>
Adds a test that asserts that when pasta is invoked via `unshare -r` in
standalone mode with `--netns-only` it does not print any warnings, and
the command executes successfully.

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>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>pif: Add message to static_assert for C11 compliance, fix build with gcc 8</title>
<updated>2026-07-21T10:08:10+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-18T05:03:38+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=316cb2e74751ca1bffbb265cd8531126f5a74aa2'/>
<id>316cb2e74751ca1bffbb265cd8531126f5a74aa2</id>
<content type='text'>
Seen with gcc 8.5:

---
In file included from passt.h:18,
                 from qrap.c:36:
pif.h: In function 'pif_type':
pif.h:48:44: error: expected ',' before ')' token
  static_assert(sizeof("?") &lt;= PIF_NAME_SIZE);
                                            ^
make: *** [Makefile:105: qrap] Error 1
---

As noted in ba84a3b17af8 ("treewide: Add messages to static_assert()
calls"), static_assert() calls need a message to comply with C11. The
form without message is supported starting from C23 only.

Fixes: cbcd4284111f ("pif: Limit pif names to 128 bytes")
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>
Seen with gcc 8.5:

---
In file included from passt.h:18,
                 from qrap.c:36:
pif.h: In function 'pif_type':
pif.h:48:44: error: expected ',' before ')' token
  static_assert(sizeof("?") &lt;= PIF_NAME_SIZE);
                                            ^
make: *** [Makefile:105: qrap] Error 1
---

As noted in ba84a3b17af8 ("treewide: Add messages to static_assert()
calls"), static_assert() calls need a message to comply with C11. The
form without message is supported starting from C23 only.

Fixes: cbcd4284111f ("pif: Limit pif names to 128 bytes")
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>udp, icmp: Remove unused timer_run fields from protocol contexts</title>
<updated>2026-07-20T21:27:10+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-06-19T10:30:06+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=81a99ce3e73bde052f792d52d260eef5b2a821a8'/>
<id>81a99ce3e73bde052f792d52d260eef5b2a821a8</id>
<content type='text'>
Since 260075bde769 ("tcp, udp, fwd: Run all port scanning from a
single timer"), CALL_PROTO_HANDLER() is only used for TCP.  UDP and
ICMP timers now run from flow_defer_handler(), making the timer_run
fields in struct udp_ctx and struct icmp_ctx dead stores.

Remove the unused fields, drop struct icmp_ctx entirely (it has no
remaining members), and stop initialising them in timer_init().

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&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>
Since 260075bde769 ("tcp, udp, fwd: Run all port scanning from a
single timer"), CALL_PROTO_HANDLER() is only used for TCP.  UDP and
ICMP timers now run from flow_defer_handler(), making the timer_run
fields in struct udp_ctx and struct icmp_ctx dead stores.

Remove the unused fields, drop struct icmp_ctx entirely (it has no
remaining members), and stop initialising them in timer_init().

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&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>main: Ensure fds 0-2 are populated</title>
<updated>2026-07-18T07:54:37+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:34+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=c80d9db312dfa98909bf3b3a5b2655785cdb3b07'/>
<id>c80d9db312dfa98909bf3b3a5b2655785cdb3b07</id>
<content type='text'>
Usually fds 0-2 are stdin, stdout and stderr.  However, there are certain
use cases where passt can be invoked with one or more of those standard fds
closed.  In those cases, anything we open might be placed in one of the
standard slots.  For the handful of things we open early enough, this can
be a problem because we close fds 0-2 in __daemon(), replacing them with
dupes of /dev/null.

We could avoid closing those fds in __daemon() if they're not standard
streams.  However, leaving things other than the standard streams in fds
0-2 is a footgun: a stray printf() that occurs in a circumstance it
shouldn't could send harmful garbage to a device or socket.  It's also
likely to be confusing if debugging with strace or similar.

To avoid this, fill any missing standard streams with a dupe of /dev/null,
right after isolate_fds().  Since open()ing /dev/null itself could land in
one of those fd 0-2 slots, we need to be careful when we close it not to
leave a new gap.

Link: https://bugs.passt.top/show_bug.cgi?id=215
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>
Usually fds 0-2 are stdin, stdout and stderr.  However, there are certain
use cases where passt can be invoked with one or more of those standard fds
closed.  In those cases, anything we open might be placed in one of the
standard slots.  For the handful of things we open early enough, this can
be a problem because we close fds 0-2 in __daemon(), replacing them with
dupes of /dev/null.

We could avoid closing those fds in __daemon() if they're not standard
streams.  However, leaving things other than the standard streams in fds
0-2 is a footgun: a stray printf() that occurs in a circumstance it
shouldn't could send harmful garbage to a device or socket.  It's also
likely to be confusing if debugging with strace or similar.

To avoid this, fill any missing standard streams with a dupe of /dev/null,
right after isolate_fds().  Since open()ing /dev/null itself could land in
one of those fd 0-2 slots, we need to be careful when we close it not to
leave a new gap.

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