<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/pasta.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, log: Share log.h (but not log.c) with pesto tool</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:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8ad7dd45281935e8fd471fb3d3d33875ce4192b3'/>
<id>8ad7dd45281935e8fd471fb3d3d33875ce4192b3</id>
<content type='text'>
In pesto we're going to want several levels of error/warning messages, much
like passt itself.  Particularly as we start to share mode code between
passt and pesto, we want to use a similar interface to emit those.  However
we don't want to use the same implementation - logging to a file or syslog
doesn't make sense for the command line tool.

To accomplish this loosely share log.h, but not log.c between pesto and
passt.  In fact, an #ifdef means even most of log.h isn't actually shared,
but we do provide similar warn(), die() etc. macros.

This includes the *_perror() variants, which need strerror().  However,
we want to avoid allocations for pesto as we do for passt, and strerror()
allocates in some libc versions.  Therefore, also move our workaround for
this to be shared with pesto.

Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[dwg: Based on changes part of a larger patch by Stefano]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Dropped debug_perror_() as it's not used anyway, Laurent was
 asking about its name]
[sbrivio: Fix conflicts in the Makefile caused by the fact that I'm
 not merging a previous series reworking it]
[sbrivio: For some reason, this triggers some unrelated, but valid,
 cppcheck warnings in tap.c and conf.c: fix / suppress them]
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 pesto we're going to want several levels of error/warning messages, much
like passt itself.  Particularly as we start to share mode code between
passt and pesto, we want to use a similar interface to emit those.  However
we don't want to use the same implementation - logging to a file or syslog
doesn't make sense for the command line tool.

To accomplish this loosely share log.h, but not log.c between pesto and
passt.  In fact, an #ifdef means even most of log.h isn't actually shared,
but we do provide similar warn(), die() etc. macros.

This includes the *_perror() variants, which need strerror().  However,
we want to avoid allocations for pesto as we do for passt, and strerror()
allocates in some libc versions.  Therefore, also move our workaround for
this to be shared with pesto.

Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[dwg: Based on changes part of a larger patch by Stefano]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Dropped debug_perror_() as it's not used anyway, Laurent was
 asking about its name]
[sbrivio: Fix conflicts in the Makefile caused by the fact that I'm
 not merging a previous series reworking it]
[sbrivio: For some reason, this triggers some unrelated, but valid,
 cppcheck warnings in tap.c and conf.c: fix / suppress them]
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, pasta: Add --splice-only option</title>
<updated>2026-01-19T08:12:27+00:00</updated>
<author>
<name>Yumei Huang</name>
<email>yuhuang@redhat.com</email>
</author>
<published>2026-01-16T03:25:09+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=cee7eb0dbf89cc096b8dea50999c6b90708defe4'/>
<id>cee7eb0dbf89cc096b8dea50999c6b90708defe4</id>
<content type='text'>
This patch introduces a mode where we only forward loopback connections
and traffic between two namespaces (via the loopback interface, 'lo'),
without a tap device.

It might be used to fix up podman IPv4 / IPv6 loopback mapping when using
rootlesskit for forwarding ports, or a way to implement isolated containers.

In this mode, --host-lo-to-ns-lo and --no-icmp are automatically enabled.
Option --no-splice is rejected.

Link: https://bugs.passt.top/show_bug.cgi?id=149
Signed-off-by: Yumei Huang &lt;yuhuang@redhat.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>
This patch introduces a mode where we only forward loopback connections
and traffic between two namespaces (via the loopback interface, 'lo'),
without a tap device.

It might be used to fix up podman IPv4 / IPv6 loopback mapping when using
rootlesskit for forwarding ports, or a way to implement isolated containers.

In this mode, --host-lo-to-ns-lo and --no-icmp are automatically enabled.
Option --no-splice is rejected.

Link: https://bugs.passt.top/show_bug.cgi?id=149
Signed-off-by: Yumei Huang &lt;yuhuang@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pasta: Warn, disable matching IP version if not supported, in local mode</title>
<updated>2025-12-23T14:10:02+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-12-23T12:39:17+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=75dcbc300bf09c3649823b12d30c4f24de7271d4'/>
<id>75dcbc300bf09c3649823b12d30c4f24de7271d4</id>
<content type='text'>
...instead of exiting, but only if local mode is enabled, that is, if
we couldn't find a template interface or if the user didn't specify
one.

With IPv4, we always try to set or copy an address, so check if that
fails.

With IPv6, in local mode, we rely on the link-local address that's
automatically generated inside the target namespace, and only fail
later, as we try to set up routes. Check if that fails, instead.

Otherwise, we'll fail to start if IPv6 support is not built in or
disabled by the kernel ("ipv6.disable=1" on the command line),
because, in that case, we'll try to enable local mode by default, and
then fail to set any address or route.

It would probably be more elegant to check for IP version support in
conf_ip4_local() and conf_ip6_local(), and not even try to enable
connectivity for unsupported versions, but it looks less robust than
trying and failing, as there might be other ways to disable a given
IP version.

Note that there's currently no way to disable IPv4 support on the
kernel command line, that is, there's no such thing as an
ipv4.disable boot parameter. But I guess that's due to be eventually
implemented, one day, so let's cover that case as well, also for
consistency.

Reported-by: Iyan &lt;iyanmv@gmail.com&gt;
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2424192
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;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
...instead of exiting, but only if local mode is enabled, that is, if
we couldn't find a template interface or if the user didn't specify
one.

With IPv4, we always try to set or copy an address, so check if that
fails.

With IPv6, in local mode, we rely on the link-local address that's
automatically generated inside the target namespace, and only fail
later, as we try to set up routes. Check if that fails, instead.

Otherwise, we'll fail to start if IPv6 support is not built in or
disabled by the kernel ("ipv6.disable=1" on the command line),
because, in that case, we'll try to enable local mode by default, and
then fail to set any address or route.

It would probably be more elegant to check for IP version support in
conf_ip4_local() and conf_ip6_local(), and not even try to enable
connectivity for unsupported versions, but it looks less robust than
trying and failing, as there might be other ways to disable a given
IP version.

Note that there's currently no way to disable IPv4 support on the
kernel command line, that is, there's no such thing as an
ipv4.disable boot parameter. But I guess that's due to be eventually
implemented, one day, so let's cover that case as well, also for
consistency.

Reported-by: Iyan &lt;iyanmv@gmail.com&gt;
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2424192
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;
</pre>
</div>
</content>
</entry>
<entry>
<title>pasta: Clean up waiting pasta child on failures</title>
<updated>2025-12-12T21:23:14+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-12-11T03:54:36+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=87f1a917d881d0881d6db5fdc2345f345a0e30d1'/>
<id>87f1a917d881d0881d6db5fdc2345f345a0e30d1</id>
<content type='text'>
When pasta is invoked with a command rather than an existing namespace to
attach to, it spawns a child process to run a shell or other command.  We
create that process during conf(), since we need the namespace to exist for
much of our setup.  However, we don't want the specified command to run
until the pasta network interface is ready for use.  Therefore,
pasta_spawn_cmd() executing in the child waits before exec()ing.  main()
signals the child to continue with SIGUSR1 shortly before entering the
main forwarding loop.

This has the downside that if we exit due to any kind of failure between
conf() and the SIGUSR1, the child process will be around waiting
indefinitely.  The user must manually clean this up.

Make this cleaner, by having the child use PR_SET_PDEATHSIG to have
itself killed if the parent dies during this window.  Technically
speaking this is racy: if the parent dies before the child can call
the prctl() it will be left zombie-like as before.  However, as long
as the parent completes pasta_wait_for_ns() before dying, I wasn't
able to trigger the race.  Since the consequences of this going wrong
are merely a bit ugly, I think that's good enough.

Suggested-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Paul Holzinger &lt;pholzing@redhat.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>
When pasta is invoked with a command rather than an existing namespace to
attach to, it spawns a child process to run a shell or other command.  We
create that process during conf(), since we need the namespace to exist for
much of our setup.  However, we don't want the specified command to run
until the pasta network interface is ready for use.  Therefore,
pasta_spawn_cmd() executing in the child waits before exec()ing.  main()
signals the child to continue with SIGUSR1 shortly before entering the
main forwarding loop.

This has the downside that if we exit due to any kind of failure between
conf() and the SIGUSR1, the child process will be around waiting
indefinitely.  The user must manually clean this up.

Make this cleaner, by having the child use PR_SET_PDEATHSIG to have
itself killed if the parent dies during this window.  Technically
speaking this is racy: if the parent dies before the child can call
the prctl() it will be left zombie-like as before.  However, as long
as the parent completes pasta_wait_for_ns() before dying, I wasn't
able to trigger the race.  Since the consequences of this going wrong
are merely a bit ugly, I think that's good enough.

Suggested-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Paul Holzinger &lt;pholzing@redhat.com&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>epoll_ctl: Extract epoll operations</title>
<updated>2025-10-30T14:32:12+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2025-10-21T21:01:11+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=965ea66068e653934c0016281df86c17e2a65625'/>
<id>965ea66068e653934c0016281df86c17e2a65625</id>
<content type='text'>
Centralize epoll_add() and epoll_del() helper functions into new
epoll_ctl.c/h files.

This also moves the union epoll_ref definition from passt.h to
epoll_ctl.h where it's more logically placed.

The new epoll_add() helper simplifies adding file descriptors to epoll
by taking an epoll_ref and events, handling error reporting
consistently across all call sites.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Include epoll_ctl.h from netlink.c as it's now needed there]
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>
Centralize epoll_add() and epoll_del() helper functions into new
epoll_ctl.c/h files.

This also moves the union epoll_ref definition from passt.h to
epoll_ctl.h where it's more logically placed.

The new epoll_add() helper simplifies adding file descriptors to epoll
by taking an epoll_ref and events, handling error reporting
consistently across all call sites.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Include epoll_ctl.h from netlink.c as it's now needed there]
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>tcp: forward external source MAC address through tap interface</title>
<updated>2025-10-30T11:01:01+00:00</updated>
<author>
<name>Jon Maloy</name>
<email>jmaloy@redhat.com</email>
</author>
<published>2025-10-24T01:29:31+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=860a487d81e4e4240b0b41c9025bd3cbe6add0c1'/>
<id>860a487d81e4e4240b0b41c9025bd3cbe6add0c1</id>
<content type='text'>
We forward the incoming mac address through the tap interface when
receiving incoming packets from network local hosts.

This is a part of the solution to bug
https://bugs.passt.top/show_bug.cgi?id=120

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>
We forward the incoming mac address through the tap interface when
receiving incoming packets from network local hosts.

This is a part of the solution to bug
https://bugs.passt.top/show_bug.cgi?id=120

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>treewide: Flush pcap and log files, if used, before exiting</title>
<updated>2025-08-19T14:29:52+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-08-13T16:45:05+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=b4fc6cd31a8729b92a305008e443b56310fd30d4'/>
<id>b4fc6cd31a8729b92a305008e443b56310fd30d4</id>
<content type='text'>
I didn't imagine that occasionally truncated pcap and log files, as a
result of commit d0006fa784a7 ("treewide: use _exit() over exit()"),
would be such a big deal, until I tried to debug TCP issues with this
beauty:

  while true; do ./pasta --trace -l /tmp/pasta.log -p /tmp/pasta.pcap --config-net -t 5555 -- socat TCP-LISTEN:5555 OPEN:/tmp/large.rcv,trunc &amp; (sleep 0.3; socat -T2 OPEN:large.bin TCP:88.198.0.164:5555; ); wait; diff large.bin /tmp/large.rcv || break; done

...flush files and pcap if we're using them. Ignore fsync() errors for
the log file as we obviously can't reliably log them.

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>
I didn't imagine that occasionally truncated pcap and log files, as a
result of commit d0006fa784a7 ("treewide: use _exit() over exit()"),
would be such a big deal, until I tried to debug TCP issues with this
beauty:

  while true; do ./pasta --trace -l /tmp/pasta.log -p /tmp/pasta.pcap --config-net -t 5555 -- socat TCP-LISTEN:5555 OPEN:/tmp/large.rcv,trunc &amp; (sleep 0.3; socat -T2 OPEN:large.bin TCP:88.198.0.164:5555; ); wait; diff large.bin /tmp/large.rcv || break; done

...flush files and pcap if we're using them. Ignore fsync() errors for
the log file as we obviously can't reliably log them.

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>Correct various function comment headers</title>
<updated>2025-06-04T10:32:04+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2025-05-19T08:52:56+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=2c883498b58a3dab702b3376a2ca828e61d3283d'/>
<id>2c883498b58a3dab702b3376a2ca828e61d3283d</id>
<content type='text'>
This commit refines function comment headers for improved accuracy
and consistency. Key changes include:

- Corrected parameter/return descriptions (e.g., `logtime`, `__daemon`).
- Added missing and removed incorrect parameter documentation (e.g.,
  `tcp_vu_sock_recv`, `ndp`).
- Standardized comments to the `/** ... */` style for functions
  like `udp_flow_close` and `ns_enter`.
- Ensured function names in comments consistently use `()`.
- Addressed minor typos and updated comments for renamed functions.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.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>
This commit refines function comment headers for improved accuracy
and consistency. Key changes include:

- Corrected parameter/return descriptions (e.g., `logtime`, `__daemon`).
- Added missing and removed incorrect parameter documentation (e.g.,
  `tcp_vu_sock_recv`, `ndp`).
- Standardized comments to the `/** ... */` style for functions
  like `udp_flow_close` and `ns_enter`.
- Ensured function names in comments consistently use `()`.
- Addressed minor typos and updated comments for renamed functions.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pasta, passt-repair: Support multiple events per read() in inotify handlers</title>
<updated>2025-03-28T12:24:44+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2025-03-28T00:39:58+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=42a854a52b6fa2bbd70cbc0c7657c8a49a9c3d2d'/>
<id>42a854a52b6fa2bbd70cbc0c7657c8a49a9c3d2d</id>
<content type='text'>
The current code assumes that we'll get one event per read() on
inotify descriptors, but that's not the case, not from documentation,
and not from reports.

Add loops in the two inotify handlers we have, in pasta-specific code
and passt-repair, to go through all the events we receive.

Link: https://bugs.passt.top/show_bug.cgi?id=119
[dwg: Remove unnecessary buffer expansion, use strnlen instead of strlen
 to make Coverity happier]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Add additional check on ev-&gt;name and ev-&gt;len in passt-repair]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The current code assumes that we'll get one event per read() on
inotify descriptors, but that's not the case, not from documentation,
and not from reports.

Add loops in the two inotify handlers we have, in pasta-specific code
and passt-repair, to go through all the events we receive.

Link: https://bugs.passt.top/show_bug.cgi?id=119
[dwg: Remove unnecessary buffer expansion, use strnlen instead of strlen
 to make Coverity happier]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Add additional check on ev-&gt;name and ev-&gt;len in passt-repair]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
