<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/util.c, branch bug209</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<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>
<entry>
<title>pif, util: Move listen(2) call from sock_l4_() to pif_listen()</title>
<updated>2026-06-16T21:50:00+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-06-16T01:09:36+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=ab2260a0c73623f51e95f922002393170d0abe1f'/>
<id>ab2260a0c73623f51e95f922002393170d0abe1f</id>
<content type='text'>
It's a bit odd to have the listen(2) call for TCP listening sockets, down
deep in sock_l4_() conditional upon the epoll type passed in.  Move it to
pif_listen(), which is at least about listening, although it does still
need to be conditional on TCP.

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>
It's a bit odd to have the listen(2) call for TCP listening sockets, down
deep in sock_l4_() conditional upon the epoll type passed in.  Move it to
pif_listen(), which is at least about listening, although it does still
need to be conditional on TCP.

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>cppcheck: Add workaround for cppcheck bug 14847</title>
<updated>2026-06-16T21:49:36+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-06-15T08:18:30+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=46048603c0cbf4899323447e72720e550a684599'/>
<id>46048603c0cbf4899323447e72720e550a684599</id>
<content type='text'>
It seems the function pointer argument confuses cppcheck 2.21.0 (at least),
causing it to think do_clone()'s definition has different argument names
than it's declaration, even though that's not the case.  I made a minimal
reproducer and filed a cppcheck bug for this (see link).  In the meanwhile
work around it with an explicit suppression.

Link: https://trac.cppcheck.net/ticket/14847
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>
It seems the function pointer argument confuses cppcheck 2.21.0 (at least),
causing it to think do_clone()'s definition has different argument names
than it's declaration, even though that's not the case.  I made a minimal
reproducer and filed a cppcheck bug for this (see link).  In the meanwhile
work around it with an explicit suppression.

Link: https://trac.cppcheck.net/ticket/14847
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>util, passt: Close daemon-lifetime fds on exit to avoid Coverity warning</title>
<updated>2026-06-11T23:02:35+00:00</updated>
<author>
<name>Jon Maloy</name>
<email>jmaloy@redhat.com</email>
</author>
<published>2026-06-11T15:15:21+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=a9c61ffaf15347b8dfcc2347c5440e4b0e82333b'/>
<id>a9c61ffaf15347b8dfcc2347c5440e4b0e82333b</id>
<content type='text'>
conf_open_files() opens three file descriptors (fd_tap_listen,
fd_repair_listen, fd_control_listen) that are held for the entire
daemon lifetime.  Because no close() call exists for them
anywhere, Coverity flags each as INCOMPLETE_DEALLOCATOR. This is
clearly a false positive, but we still want to get rid of this
warning.

We now register the execution context in global area so that
passt_exit() can use it to close these descriptors before calling
_exit().  All exit paths (signal handler, die(), die_perror())
funnel through passt_exit(), so this covers all cases.

Signed-off-by: Jon Maloy &lt;jmaloy@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>
conf_open_files() opens three file descriptors (fd_tap_listen,
fd_repair_listen, fd_control_listen) that are held for the entire
daemon lifetime.  Because no close() call exists for them
anywhere, Coverity flags each as INCOMPLETE_DEALLOCATOR. This is
clearly a false positive, but we still want to get rid of this
warning.

We now register the execution context in global area so that
passt_exit() can use it to close these descriptors before calling
_exit().  All exit paths (signal handler, die(), die_perror())
funnel through passt_exit(), so this covers all cases.

Signed-off-by: Jon Maloy &lt;jmaloy@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>conf, util: Disable IPv6 if explicit IPv6 socket probe fails</title>
<updated>2026-06-10T14:48:44+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-06-08T19:06:17+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=e1a6d9ef626aa6dbcfeef97dbbab3bd69c35b4b1'/>
<id>e1a6d9ef626aa6dbcfeef97dbbab3bd69c35b4b1</id>
<content type='text'>
In https://bugs.passt.top/show_bug.cgi?id=188, I originally reported
that if IPv6 is disabled in the kernel (for example via command line
parameter ipv6.disable=1, or disabled in build configuration), and we
attempt to forward any port, we'll exit right away after failing to
set up dual-stack listening sockets.

The original instance of that issue is now fixed for pasta by commit
75dcbc300bf0 ("pasta: Warn, disable matching IP version if not
supported, in local mode") together with the new implementation of
the rule forwarding table, starting from commit b223bec48213 ("fwd,
tcp, udp: Set up listening sockets based on forward table"), because
we first parse forwarding options, then probe for IPv6 support in the
target namespace (and disable IPv6 as a result), and finally bind
sockets once we already know that IPv6 support is disabled.

But we don't do that when invoked as passt, because we have no target
namespace and hence no probing for IPv6 support whatsoever.

Add IPv6 to the socket features we test in sock_probe_features(), and,
if we fail to create an IPv6 socket for whatever reason (which might
include security policies as well), disable IPv6 support altogether,
so that we won't attempt to use dual-stack sockets for port forwarding
either.

Note that the probe comes without any sort of debug message, because
at this point we haven't parsed the configuration yet, and we would
therefore print that regardless of the selected logging level and
other options, including --ipv4-only, which would be rather confusing.
I doubt we'll miss this kind of message though, IPv6 support being
disabled is anyway obvious from the initial configuration dump.

Reported-by: Chi Cuong HA &lt;ChiCuong.HA@amadeus.com&gt;
Reported-by: Romain Geissler &lt;romain.geissler@amadeus.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=188
Fixes: 4ddd59bc6085 ("conf: Separate local mode for each IP version, don't enable disabled IP version")
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>
In https://bugs.passt.top/show_bug.cgi?id=188, I originally reported
that if IPv6 is disabled in the kernel (for example via command line
parameter ipv6.disable=1, or disabled in build configuration), and we
attempt to forward any port, we'll exit right away after failing to
set up dual-stack listening sockets.

The original instance of that issue is now fixed for pasta by commit
75dcbc300bf0 ("pasta: Warn, disable matching IP version if not
supported, in local mode") together with the new implementation of
the rule forwarding table, starting from commit b223bec48213 ("fwd,
tcp, udp: Set up listening sockets based on forward table"), because
we first parse forwarding options, then probe for IPv6 support in the
target namespace (and disable IPv6 as a result), and finally bind
sockets once we already know that IPv6 support is disabled.

But we don't do that when invoked as passt, because we have no target
namespace and hence no probing for IPv6 support whatsoever.

Add IPv6 to the socket features we test in sock_probe_features(), and,
if we fail to create an IPv6 socket for whatever reason (which might
include security policies as well), disable IPv6 support altogether,
so that we won't attempt to use dual-stack sockets for port forwarding
either.

Note that the probe comes without any sort of debug message, because
at this point we haven't parsed the configuration yet, and we would
therefore print that regardless of the selected logging level and
other options, including --ipv4-only, which would be rather confusing.
I doubt we'll miss this kind of message though, IPv6 support being
disabled is anyway obvious from the initial configuration dump.

Reported-by: Chi Cuong HA &lt;ChiCuong.HA@amadeus.com&gt;
Reported-by: Romain Geissler &lt;romain.geissler@amadeus.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=188
Fixes: 4ddd59bc6085 ("conf: Separate local mode for each IP version, don't enable disabled IP version")
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>pcap: Pass explicit L2 length to pcap_iov()</title>
<updated>2026-05-19T23:21:42+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:15+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=533ef11ecb4edd98c7adad3b51c40fdcc2f0671d'/>
<id>533ef11ecb4edd98c7adad3b51c40fdcc2f0671d</id>
<content type='text'>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@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>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@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>bitmap: Split bitmap helper functions into their own module</title>
<updated>2026-03-28T13:36:02+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-27T04:34:29+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=51eaaa7be714229c1b2e2f7ba5f3c5eae36c8a61'/>
<id>51eaaa7be714229c1b2e2f7ba5f3c5eae36c8a61</id>
<content type='text'>
Currently bitmap functions are in util.[ch] along with a lot of other
stuff.  In preparation for sharing them with a configuration client, move
these out into their own files.

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 bitmap functions are in util.[ch] along with a lot of other
stuff.  In preparation for sharing them with a configuration client, move
these out into their own files.

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>serialise: Split functions user for serialisation from util.c</title>
<updated>2026-03-28T13:35:41+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-27T04:34:16+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8081aa597be4007f3ef15fe8ce11ec8ad0ab8b42'/>
<id>8081aa597be4007f3ef15fe8ce11ec8ad0ab8b42</id>
<content type='text'>
The read_all_buf() and write_all_buf() functions in util.c are
primarily used for serialising data structures to a stream during
migraiton.  We're going to have further use for such serialisation
when we add dynamic configuration updates, where we'll want to share
the code with the client program.

To make that easier move the functions into a new serialise.c
file, and rename thematically.

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 read_all_buf() and write_all_buf() functions in util.c are
primarily used for serialising data structures to a stream during
migraiton.  We're going to have further use for such serialisation
when we add dynamic configuration updates, where we'll want to share
the code with the client program.

To make that easier move the functions into a new serialise.c
file, and rename thematically.

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>treewide: Spell ASSERT() as assert()</title>
<updated>2026-03-20T20:05:29+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-19T06:11:43+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=bc872d91765dfd6ff34b0e9a34bce410fac1cef3'/>
<id>bc872d91765dfd6ff34b0e9a34bce410fac1cef3</id>
<content type='text'>
The standard library assert(3), at least with glibc, hits our seccomp
filter and dies with SIGSYS before it's able to print a message, making it
near useless.  Therefore, since 7a8ed9459dfe ("Make assertions actually
useful") we've instead used our own implementation, named ASSERT().

This makes our code look slightly odd though - ASSERT() has the same
overall effect as assert(), it's just a different implementation.  More
importantly this makes it awkward to share code between passt/pasta proper
and things that compile in a more typical environment.  We're going to want
that for our upcoming dynamic configuration tool.

Address this by overriding the standard library's assert() implementation
with our own, instead of giving ours its own name.

The standard assert() is supposed to be omitted if NDEBUG is defined,
which ours doesn't do.  Implement that as well, so ours doesn't
unexpectedly differ.  For the -DNDEBUG case we do this by *not* overriding
assert(), since it will be a no-op anyway.  This requires a few places to
add a #include &lt;assert.h&gt; to let us compile (albeit with warnings) when
-DNDEBUG.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Fix some conflicts and missing conversions as a result of
 applying "vu_common: Move iovec management into vu_collect()" first]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The standard library assert(3), at least with glibc, hits our seccomp
filter and dies with SIGSYS before it's able to print a message, making it
near useless.  Therefore, since 7a8ed9459dfe ("Make assertions actually
useful") we've instead used our own implementation, named ASSERT().

This makes our code look slightly odd though - ASSERT() has the same
overall effect as assert(), it's just a different implementation.  More
importantly this makes it awkward to share code between passt/pasta proper
and things that compile in a more typical environment.  We're going to want
that for our upcoming dynamic configuration tool.

Address this by overriding the standard library's assert() implementation
with our own, instead of giving ours its own name.

The standard assert() is supposed to be omitted if NDEBUG is defined,
which ours doesn't do.  Implement that as well, so ours doesn't
unexpectedly differ.  For the -DNDEBUG case we do this by *not* overriding
assert(), since it will be a no-op anyway.  This requires a few places to
add a #include &lt;assert.h&gt; to let us compile (albeit with warnings) when
-DNDEBUG.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Fix some conflicts and missing conversions as a result of
 applying "vu_common: Move iovec management into vu_collect()" first]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add missing includes to headers</title>
<updated>2026-03-04T16:39:57+00:00</updated>
<author>
<name>Peter Foley</name>
<email>pefoley@google.com</email>
</author>
<published>2026-02-23T18:11:19+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=adbf5c135f19db5b6751393b7f5cbf516031bde8'/>
<id>adbf5c135f19db5b6751393b7f5cbf516031bde8</id>
<content type='text'>
Support build systems like bazel that check that headers are
self-contained.

Also update includes so that clang-include-cleaner succeeds.

Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c

Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Support build systems like bazel that check that headers are
self-contained.

Also update includes so that clang-include-cleaner succeeds.

Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c

Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
