<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/udp.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>tap, tcp, udp: Use rate-limited logging</title>
<updated>2026-04-15T18:59:35+00:00</updated>
<author>
<name>Anshu Kumari</name>
<email>anskuma@redhat.com</email>
</author>
<published>2026-04-10T10:37:37+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=5ac9cf11a512e6d54c94a2e6a7ddaabc10cb5b9b'/>
<id>5ac9cf11a512e6d54c94a2e6a7ddaabc10cb5b9b</id>
<content type='text'>
Now that rate-limited logging macros are available, promote several
debug messages to higher severity levels.  These messages were
previously kept at debug to prevent guests from flooding host
logs, but with rate limiting they can safely be made visible in
normal operation.

In tap.c, refactor tap4_is_fragment() to use warn_ratelimit() instead
of its ad-hoc rate limiting, and promote the guest MAC address change
message to info level.

In tcp.c, promote the invalid TCP SYN endpoint message to warn level.

In udp.c, promote dropped datagram messages to warn level, and
rate-limit the unrecoverable socket error message.

In udp_flow.c, promote flow allocation failures to err_ratelimit.

Link: https://bugs.passt.top/show_bug.cgi?id=134
Signed-off-by: Anshu Kumari &lt;anskuma@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>
Now that rate-limited logging macros are available, promote several
debug messages to higher severity levels.  These messages were
previously kept at debug to prevent guests from flooding host
logs, but with rate limiting they can safely be made visible in
normal operation.

In tap.c, refactor tap4_is_fragment() to use warn_ratelimit() instead
of its ad-hoc rate limiting, and promote the guest MAC address change
message to info level.

In tcp.c, promote the invalid TCP SYN endpoint message to warn level.

In udp.c, promote dropped datagram messages to warn level, and
rate-limit the unrecoverable socket error message.

In udp_flow.c, promote flow allocation failures to err_ratelimit.

Link: https://bugs.passt.top/show_bug.cgi?id=134
Signed-off-by: Anshu Kumari &lt;anskuma@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: 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>fwd: Split forwarding table from port scanning state</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:10+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=bb2e4dda0f7c9b92195ab84920430659425afbc0'/>
<id>bb2e4dda0f7c9b92195ab84920430659425afbc0</id>
<content type='text'>
For hsitorical reasons, struct fwd_ports contained both the new forwarding
table and some older state related to port / scanning auto-forwarding
detection.  They are related, but keeping them together prevents some
future reworks we want to do.

Separate them into struct fwd_table (for the table) and struct fwd_scan
for the scanning state.  Adjusting all the users makes for a logically
straightforward, but fairly extensive patch.

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>
For hsitorical reasons, struct fwd_ports contained both the new forwarding
table and some older state related to port / scanning auto-forwarding
detection.  They are related, but keeping them together prevents some
future reworks we want to do.

Separate them into struct fwd_table (for the table) and struct fwd_scan
for the scanning state.  Adjusting all the users makes for a logically
straightforward, but fairly extensive patch.

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, pif: Replace with pif_sock_l4() with pif_listen()</title>
<updated>2026-03-04T16:52:55+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-02T04:31:34+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=9ee780567310f2486e1510db502a96e5b1a81a1c'/>
<id>9ee780567310f2486e1510db502a96e5b1a81a1c</id>
<content type='text'>
It turns out all users of pif_sock_l4() use it for "listening" sockets,
which now all have a common epoll reference format.  We can take advantage
of that to pass the necessary epoll information into pif_sock_l4() in a
more natural way, rather than as an opaque u32.

That in turn allows union fwd_listen_ref can become a struct, since the
union only exist to allow the meaningful fields to be coerced into a u32
for pif_sock_l4().

Rename pif_sock_l4() to pif_listen() to reflect the new semantics.  While
we're there, remove the static_assert() on the fwd_listen_ref's size.  We
do still need it to fit into 32 bits, but that constraint is imposed only
by the fact that it needs to fit into the whole, epoll_ref structure,
which we already check with a static_assert() in epoll_ctl.h.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reported-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>
It turns out all users of pif_sock_l4() use it for "listening" sockets,
which now all have a common epoll reference format.  We can take advantage
of that to pass the necessary epoll information into pif_sock_l4() in a
more natural way, rather than as an opaque u32.

That in turn allows union fwd_listen_ref can become a struct, since the
union only exist to allow the meaningful fields to be coerced into a u32
for pif_sock_l4().

Rename pif_sock_l4() to pif_listen() to reflect the new semantics.  While
we're there, remove the static_assert() on the fwd_listen_ref's size.  We
do still need it to fit into 32 bits, but that constraint is imposed only
by the fact that it needs to fit into the whole, epoll_ref structure,
which we already check with a static_assert() in epoll_ctl.h.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reported-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp: Split activity timeouts for UDP flows</title>
<updated>2026-02-15T01:48:34+00:00</updated>
<author>
<name>Yumei Huang</name>
<email>yuhuang@redhat.com</email>
</author>
<published>2026-02-14T07:31:36+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=bebafa72a982784164a7d556bd860ec0ed1e02c7'/>
<id>bebafa72a982784164a7d556bd860ec0ed1e02c7</id>
<content type='text'>
Frequent DNS queries over UDP from a container or guest can result
in many sockets shown in ss(8), typically one per flow. This is
expected and harmless, but it can make the output of ss(8) look
noisy and potentially concern users.

This patch splits UDP flow timeouts into two, mirroring the Linux
kernel, and sources the values from kernel parameters. The shorter
timeout is applied to unidirectional flows and minimal bidirectional
exchanges (single datagram and reply), while the longer timeout is
used for bidirectional flows with multiple datagrams on either side.

Link: https://bugs.passt.top/show_bug.cgi?id=197
Suggested-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
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>
Frequent DNS queries over UDP from a container or guest can result
in many sockets shown in ss(8), typically one per flow. This is
expected and harmless, but it can make the output of ss(8) look
noisy and potentially concern users.

This patch splits UDP flow timeouts into two, mirroring the Linux
kernel, and sources the values from kernel parameters. The shorter
timeout is applied to unidirectional flows and minimal bidirectional
exchanges (single datagram and reply), while the longer timeout is
used for bidirectional flows with multiple datagrams on either side.

Link: https://bugs.passt.top/show_bug.cgi?id=197
Suggested-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
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>flow, fwd: Optimise forwarding rule lookup using epoll ref when possible</title>
<updated>2026-01-18T11:48:09+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-01-16T00:59:26+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=4a0d507296ef8c1349669e95fd672539734d9a6c'/>
<id>4a0d507296ef8c1349669e95fd672539734d9a6c</id>
<content type='text'>
Now that listening sockets include a reference to the forwarding rule
which created them we can, in many cases, avoid a linear search of the
forwarding table when we want to find the relevant rule.  Instead we
can take the rule index from the socket's epoll reference, and use
that to immediately find the correct rule.

This is conceptually simple, but requires a moderate amount of
plumbing to get the index from the reference through to the rule
lookup.  We still allow fall back to linear search if we don't have
the index, and this may (rarely) be used in the udp_flush_flow() case,
where we could get packets for one flow on a different flow's socket,
rather than through a listening socket as usual.

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>
Now that listening sockets include a reference to the forwarding rule
which created them we can, in many cases, avoid a linear search of the
forwarding table when we want to find the relevant rule.  Instead we
can take the rule index from the socket's epoll reference, and use
that to immediately find the correct rule.

This is conceptually simple, but requires a moderate amount of
plumbing to get the index from the reference through to the rule
lookup.  We still allow fall back to linear search if we don't have
the index, and this may (rarely) be used in the udp_flush_flow() case,
where we could get packets for one flow on a different flow's socket,
rather than through a listening socket as usual.

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, tcp, udp: Add forwarding rule to listening socket epoll references</title>
<updated>2026-01-18T11:48:06+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-01-16T00:59:25+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=fe37028466d3d29d74ebf53e9c53c9f139fbc74e'/>
<id>fe37028466d3d29d74ebf53e9c53c9f139fbc74e</id>
<content type='text'>
Now that we have a table of all our forwarding rules, every listening
socket can be associated with a specific rule.  Add an index allowing us to
locate that rule from the socket's epoll reference.  We don't use it yet,
but we'll use it to optimise rule lookup when forwarding new flows.

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>
Now that we have a table of all our forwarding rules, every listening
socket can be associated with a specific rule.  Add an index allowing us to
locate that rule from the socket's epoll reference.  We don't use it yet,
but we'll use it to optimise rule lookup when forwarding new flows.

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>tcp, udp: Remove old auto-forwarding socket arrays</title>
<updated>2026-01-18T11:47:50+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-01-16T00:59:20+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=acb7a3057bbc6af72399c44d747c1cf7fb92d17f'/>
<id>acb7a3057bbc6af72399c44d747c1cf7fb92d17f</id>
<content type='text'>
Now that we've moved listening socket management to the new forwarding
table data structure, the existing arrays of socket fds are maintained,
but never consulted.  Remove them.

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>
Now that we've moved listening socket management to the new forwarding
table data structure, the existing arrays of socket fds are maintained,
but never consulted.  Remove them.

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, tcp, udp: Set up listening sockets based on forward table</title>
<updated>2026-01-18T11:47:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-01-16T00:59:19+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=b223bec48213060304c09882ce5b3055b15b7e07'/>
<id>b223bec48213060304c09882ce5b3055b15b7e07</id>
<content type='text'>
Previously we created inbound listening sockets as we parsed the forwarding
options (-t, -u) whereas outbound listening sockets were created during
{tcp,udp}_init().  Now that we have a data structure recording the full
details of the listening options we can move all listening socket creation
to {tcp,udp}_init().  This means that errors for either direction are
detected and reported the same way.

Introduce fwd_listen_sync() which synchronizes the state of listening
sockets to the forwarding rules table, both for fixed and automatic
forwards.

This does cause a change in semantics for "exclude only" port
specifications.  Previously an option like -t ~6000 wouldn't cause a
fatal error, as long as we could bind at least one port.  Now, it
requires at least one port for each generated rule; that is for each
of the contiguous blocks of ports the specification resolves to.  With
typical ephemeral ports settings that's one port each in 1..5999,
6001..32767 and 61000..65535.

Preserving the exact behaviour for this case would require a considerably
more complex data structure, so I'm hoping this is a sufficiently niche
case for the change to be acceptable.

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>
Previously we created inbound listening sockets as we parsed the forwarding
options (-t, -u) whereas outbound listening sockets were created during
{tcp,udp}_init().  Now that we have a data structure recording the full
details of the listening options we can move all listening socket creation
to {tcp,udp}_init().  This means that errors for either direction are
detected and reported the same way.

Introduce fwd_listen_sync() which synchronizes the state of listening
sockets to the forwarding rules table, both for fixed and automatic
forwards.

This does cause a change in semantics for "exclude only" port
specifications.  Previously an option like -t ~6000 wouldn't cause a
fatal error, as long as we could bind at least one port.  Now, it
requires at least one port for each generated rule; that is for each
of the contiguous blocks of ports the specification resolves to.  With
typical ephemeral ports settings that's one port each in 1..5999,
6001..32767 and 61000..65535.

Preserving the exact behaviour for this case would require a considerably
more complex data structure, so I'm hoping this is a sufficiently niche
case for the change to be acceptable.

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>
