<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/passt.c, branch 2026_05_07.1afd4ed</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>pesto, conf: Have pesto connect to passt and check versions</title>
<updated>2026-05-07T06:06:30+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-03T21:55:53+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=f1d893ca1926e58ae5a2bf5602b515a883f3f994'/>
<id>f1d893ca1926e58ae5a2bf5602b515a883f3f994</id>
<content type='text'>
Start implementing pesto in earnest.  Create a control/configuration
socket in passt.  Have pesto connect to it and retrieve a server greeting
Perform some basic version checking.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Avoid potential recursive calling between conf_accept() and
 conf_close(), reported by clang-tidy]
[sbrivio: In conf(), check we're not exceeding sizeof(c-&gt;control_path)
 instead of sizeof(c-&gt;socket_path), and, in pesto's main(), print
 argv[optind] instead of argv[1] to indicate an invalid socket path,
 both reported by Jon Maloy]
[sbrivio: In pesto's main(), drop unnecessary newline from error
 message, reported by Laurent]
[sbrivio: Don't use SOCK_NONBLOCK on accept4(), as that only applies
 to the *new* file descriptor, which we don't want -- set O_NONBLOCK
 on the listening file descriptor using fcntl()]
[sbrivio: Switch to protocol version 1, and reflect the true magic
 behind pesto, i.e. basil, into the magic string]
[sbrivio: Fix conflicts in the Makefile caused by the fact that I'm
 not merging a previous series reworking it]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Start implementing pesto in earnest.  Create a control/configuration
socket in passt.  Have pesto connect to it and retrieve a server greeting
Perform some basic version checking.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Avoid potential recursive calling between conf_accept() and
 conf_close(), reported by clang-tidy]
[sbrivio: In conf(), check we're not exceeding sizeof(c-&gt;control_path)
 instead of sizeof(c-&gt;socket_path), and, in pesto's main(), print
 argv[optind] instead of argv[1] to indicate an invalid socket path,
 both reported by Jon Maloy]
[sbrivio: In pesto's main(), drop unnecessary newline from error
 message, reported by Laurent]
[sbrivio: Don't use SOCK_NONBLOCK on accept4(), as that only applies
 to the *new* file descriptor, which we don't want -- set O_NONBLOCK
 on the listening file descriptor using fcntl()]
[sbrivio: Switch to protocol version 1, and reflect the true magic
 behind pesto, i.e. basil, into the magic string]
[sbrivio: Fix conflicts in the Makefile caused by the fact that I'm
 not merging a previous series reworking it]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@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>fwd: Unify TCP and UDP forwarding tables</title>
<updated>2026-03-11T21:11:30+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-11T12:03:11+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=d460ca3236bafa724686a5ad7f585d70962f7373'/>
<id>d460ca3236bafa724686a5ad7f585d70962f7373</id>
<content type='text'>
Currently TCP and UDP each have their own forwarding tables.  This is
awkward in a few places, where we need switch statements to select the
correct table.  More importantly, it would make things awkward and messy to
extend to other protocols in future, which we're likely to want to do.

Merge the TCP and UDP tables into a single table per (source) pif, with the
protocol given in each rule entry.

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 TCP and UDP each have their own forwarding tables.  This is
awkward in a few places, where we need switch statements to select the
correct table.  More importantly, it would make things awkward and messy to
extend to other protocols in future, which we're likely to want to do.

Merge the TCP and UDP tables into a single table per (source) pif, with the
protocol given in each rule entry.

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, fwd: Move initialisation of auto port scanning out of conf()</title>
<updated>2025-12-12T21:38:56+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-12-12T07:10:35+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=35fa86a7871767d6a382b13e71c429abf47f88ab'/>
<id>35fa86a7871767d6a382b13e71c429abf47f88ab</id>
<content type='text'>
We call fwd_scan_ports_init() at (almost) the end of conf().  It's a bit
odd to do actual work from a function that's ostensibly about getting our
configuration.  It's not the only instance of this, but to make things a
bit clearer move the call to main(), right after flow_init().

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 call fwd_scan_ports_init() at (almost) the end of conf().  It's a bit
odd to do actual work from a function that's ostensibly about getting our
configuration.  It's not the only instance of this, but to make things a
bit clearer move the call to main(), right after flow_init().

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: Introduce passt_exit() helper</title>
<updated>2025-12-12T21:20:02+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-12-11T03:54:35+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=e6612fe0a7cf4860b0d81d3b886f95273d979d1d'/>
<id>e6612fe0a7cf4860b0d81d3b886f95273d979d1d</id>
<content type='text'>
In d0006fa78 ("treewide: use _exit() over exit()"), we replaced use of
the normal exit(3) with direct calls to _exit(2).  That was because glibc
exit(3) made some unexpected futex() calls, which hit our seccomp profile.

We've since had some bugs due to missing the extra cleanup that exit(3)
implemented, for which we've added explicit cleanup calls.  Specifically,
we have fflush() calls in some places to avoid leaving incomplete messages
on stdout/stderr, and in other places fsync_pcap_and_log() to avoid
leaving incomplete log or pcap files.

It's easy to forget these when adding new error paths, so instead,
implement our own passt_exit() wrapper to perform vital cleanup then call
_exit(2).  This also provides an obvious place to add any additional
cleanups we discover we need 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>
In d0006fa78 ("treewide: use _exit() over exit()"), we replaced use of
the normal exit(3) with direct calls to _exit(2).  That was because glibc
exit(3) made some unexpected futex() calls, which hit our seccomp profile.

We've since had some bugs due to missing the extra cleanup that exit(3)
implemented, for which we've added explicit cleanup calls.  Specifically,
we have fflush() calls in some places to avoid leaving incomplete messages
on stdout/stderr, and in other places fsync_pcap_and_log() to avoid
leaving incomplete log or pcap files.

It's easy to forget these when adding new error paths, so instead,
implement our own passt_exit() wrapper to perform vital cleanup then call
_exit(2).  This also provides an obvious place to add any additional
cleanups we discover we need 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>seccomp: Fix build and operation on 32-bit musl targets</title>
<updated>2025-12-07T22:17:25+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-12-04T20:48:20+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=9e2e381be1d2ff6b385067af276d0e38f202422c'/>
<id>9e2e381be1d2ff6b385067af276d0e38f202422c</id>
<content type='text'>
On 32-bit musl targets (for example, Alpine i386 / i586), we need to:

- use the set of system calls already defined for i686. While Alpine's
  kernel supports i586 as well (Debian for example doesn't), it's the
  same architecture, so change i386/i486/i586 machine strings to i686
  in seccomp.sh

- allow clock_gettime64() as an alternative to clock_gettime() (not
  just added on top, rather replacing it), because clock_gettime()
  isn't available as a system call name at all in musl headers (while
  glibc aliases it to the kernel's clock_gettime64())

- similarly, allow timerfd_gettime64() as a name for timerfd_gettime()

- allow timerfd_settime32() as a name for timerfd_settime(), even
  though there's no such system call declared in Linux kernel headers,
  as musl uses that name to distinguish it from timerfd_settime64()

- unconditionally allow timerfd_settime64(), because musl uses it
  whenever the 'old' argument is non-NULL and sizeof(time_t) &gt; 4,
  which happens to be the case in tcp_timer_handler()

Reported-by: John D. Rowell &lt;me@jdrowell.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=177
Link: https://gitlab.alpinelinux.org/alpine/aports/-/issues/17686
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
On 32-bit musl targets (for example, Alpine i386 / i586), we need to:

- use the set of system calls already defined for i686. While Alpine's
  kernel supports i586 as well (Debian for example doesn't), it's the
  same architecture, so change i386/i486/i586 machine strings to i686
  in seccomp.sh

- allow clock_gettime64() as an alternative to clock_gettime() (not
  just added on top, rather replacing it), because clock_gettime()
  isn't available as a system call name at all in musl headers (while
  glibc aliases it to the kernel's clock_gettime64())

- similarly, allow timerfd_gettime64() as a name for timerfd_gettime()

- allow timerfd_settime32() as a name for timerfd_settime(), even
  though there's no such system call declared in Linux kernel headers,
  as musl uses that name to distinguish it from timerfd_settime64()

- unconditionally allow timerfd_settime64(), because musl uses it
  whenever the 'old' argument is non-NULL and sizeof(time_t) &gt; 4,
  which happens to be the case in tcp_timer_handler()

Reported-by: John D. Rowell &lt;me@jdrowell.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=177
Link: https://gitlab.alpinelinux.org/alpine/aports/-/issues/17686
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>util: Extend sock_probe_mem() to sock_probe_features()</title>
<updated>2025-12-02T22:06:25+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-12-02T04:02:02+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0ae7b8c21bdb6130686f6c8aead3e8ab4c0921c8'/>
<id>0ae7b8c21bdb6130686f6c8aead3e8ab4c0921c8</id>
<content type='text'>
sock_probe_mem() currently checks whether we're able to allocate large
socket buffers.  Extend it to also check whether the SO_BINDTODEVICE
socket option is available.  Rename to sock_probe_features() to reflect the
new functionality.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Add whitespace around "-" in sock_probe_features()]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
sock_probe_mem() currently checks whether we're able to allocate large
socket buffers.  Extend it to also check whether the SO_BINDTODEVICE
socket option is available.  Rename to sock_probe_features() to reflect the
new functionality.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Add whitespace around "-" in sock_probe_features()]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tcp, udp, fwd: Run all port scanning from a single timer</title>
<updated>2025-10-31T23:22:55+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-10-31T04:19:24+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=260075bde769b6abbf6350e930f44b9fc7d5303a'/>
<id>260075bde769b6abbf6350e930f44b9fc7d5303a</id>
<content type='text'>
With -t auto and similar options we need to periodically scan /proc for
listening ports.  Currently we do this separately for TCP and UDP, from
tcp_timer() and udp_timer().

For upcoming changes (leading eventually to a more general forwarding
table), it's awkward to have these separate.  Move them to a single common
timer.  For now this just calls new tcp_scan_ports() and udp_scan_ports()
functions, but we'll consolidate more thoroughly in later patches.

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>
With -t auto and similar options we need to periodically scan /proc for
listening ports.  Currently we do this separately for TCP and UDP, from
tcp_timer() and udp_timer().

For upcoming changes (leading eventually to a more general forwarding
table), it's awkward to have these separate.  Move them to a single common
timer.  For now this just calls new tcp_scan_ports() and udp_scan_ports()
functions, but we'll consolidate more thoroughly in later patches.

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>icmp: Remove vestiges of ICMP timer</title>
<updated>2025-10-31T23:22:52+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-10-31T04:19:23+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=1f2c08b57c6b22fdcc2a0dc06887f75a215e4c84'/>
<id>1f2c08b57c6b22fdcc2a0dc06887f75a215e4c84</id>
<content type='text'>
We no longer have a global ICMP timer (timers for individual flows are
handled through the flow timer).  We still have an ICMP_TIMER_INTERVAL
define, though.  Remove it.

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 no longer have a global ICMP timer (timers for individual flows are
handled through the flow timer).  We still have an ICMP_TIMER_INTERVAL
define, though.  Remove it.

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>passt: Move main event loop processing into passt_worker()</title>
<updated>2025-10-30T14:33:58+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2025-10-21T21:01:16+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=57446ca9c3850b671c997674957f4ea2dfb0d0be'/>
<id>57446ca9c3850b671c997674957f4ea2dfb0d0be</id>
<content type='text'>
Extract the epoll event processing logic from main() into a separate
passt_worker() function. This refactoring prepares the code for future
threading support where passt_worker() will be called as a worker thread
callback.

The new function handles:
- Processing epoll events and dispatching to protocol handlers
- Event statistics tracking and printing
- Post-handler periodic tasks (timers, deferred work)
- Migration handling

No functional changes, purely a code restructuring.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Handle new EPOLL_TYPE_NL_NEIGH in passt_worker() as well]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Extract the epoll event processing logic from main() into a separate
passt_worker() function. This refactoring prepares the code for future
threading support where passt_worker() will be called as a worker thread
callback.

The new function handles:
- Processing epoll events and dispatching to protocol handlers
- Event statistics tracking and printing
- Post-handler periodic tasks (timers, deferred work)
- Migration handling

No functional changes, purely a code restructuring.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Handle new EPOLL_TYPE_NL_NEIGH in passt_worker() as well]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
