<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/fwd.c, branch bug209</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>fwd: Don't rewrite inbound multicast destinations</title>
<updated>2026-07-10T05:50:35+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-10T05:38:42+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=e5932b92fded86b8077d0b5a737e5477bb0c946d'/>
<id>e5932b92fded86b8077d0b5a737e5477bb0c946d</id>
<content type='text'>
fwd_nat_from_host() (nearly) always rewrites the destination address for
inbound flows to the observed guest address.  Usually, that makes sense:
regardless of the host address to which the new flow arrived, we want to
direct it to the guest.  However, that clearly does not make sense for
multicast - it should still appear as a multicast transmission to the
guest.

In particular this can work very badly for multicast protocols which use
the same source and destination ports by convention (e.g. mDNS).  In this
case, we will attempt to forword multicast packets to our own socket,
causing a forwarding loop (see bug 209 for more details).

While it's certainly not enough to make us handle multicast correctly in
all circumstances, not translating multicast destinations is closer to
correct, and prevents bug 209 at least.

Link: https://bugs.passt.top/show_bug.cgi?id=209
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fwd_nat_from_host() (nearly) always rewrites the destination address for
inbound flows to the observed guest address.  Usually, that makes sense:
regardless of the host address to which the new flow arrived, we want to
direct it to the guest.  However, that clearly does not make sense for
multicast - it should still appear as a multicast transmission to the
guest.

In particular this can work very badly for multicast protocols which use
the same source and destination ports by convention (e.g. mDNS).  In this
case, we will attempt to forword multicast packets to our own socket,
causing a forwarding loop (see bug 209 for more details).

While it's certainly not enough to make us handle multicast correctly in
all circumstances, not translating multicast destinations is closer to
correct, and prevents bug 209 at least.

Link: https://bugs.passt.top/show_bug.cgi?id=209
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Reorder DNAPT and SNAT steps in fwd_nat_from_host()</title>
<updated>2026-07-10T05:26:51+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-10T05:26:51+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=2ef86a35c5f9e2c518329a64162ecee7838f190a'/>
<id>2ef86a35c5f9e2c518329a64162ecee7838f190a</id>
<content type='text'>
The order in which we translate source and destination addresses is a bit
unclear in fwd_nat_from_host().  Reorder things to make it clearer:
   1. Pick guest-side destination address, where options require it
   2. Pick guest-side source address (needs to be different for SPLICE and
      TAP)
   3. If (1) didn't determine destination, pick a fallback to match family
      and scope of source address from (2).

As a small bonus this lets us make step (1) common between SPLICE and TAP
paths.  The value of this is a bit dubious right now, but it will make some
future changes clearer.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The order in which we translate source and destination addresses is a bit
unclear in fwd_nat_from_host().  Reorder things to make it clearer:
   1. Pick guest-side destination address, where options require it
   2. Pick guest-side source address (needs to be different for SPLICE and
      TAP)
   3. If (1) didn't determine destination, pick a fallback to match family
      and scope of source address from (2).

As a small bonus this lets us make step (1) common between SPLICE and TAP
paths.  The value of this is a bit dubious right now, but it will make some
future changes clearer.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Rework default address logic for inbound flows</title>
<updated>2026-07-10T05:19:29+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-10T05:13:57+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=058d9cfed9289654fa0be94b09d8d0bfd13648b7'/>
<id>058d9cfed9289654fa0be94b09d8d0bfd13648b7</id>
<content type='text'>
fwd_nat_from_host() needs to determine the guest side destination address
for the new flow.  In some cases that's controlled by the forwarding rule
or -host-lo-to-ns-lo logic, but by default we use the observed guest
address.  We need to pick the right one to match the source address,
though.

Currently this is done with similar, but not quite identical logic in the
spliced and non-spliced paths.  Introduce a new fwd_default_guest_addr()
helper to make explicit:
 * We have the same logic for splice and tap paths
 * This is a fallback path if nothing else determined the address (we
   use this default nearly all the time now, but it might change in future)
 * We're matching IP family and scope with the guest side source address

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fwd_nat_from_host() needs to determine the guest side destination address
for the new flow.  In some cases that's controlled by the forwarding rule
or -host-lo-to-ns-lo logic, but by default we use the observed guest
address.  We need to pick the right one to match the source address,
though.

Currently this is done with similar, but not quite identical logic in the
spliced and non-spliced paths.  Introduce a new fwd_default_guest_addr()
helper to make explicit:
 * We have the same logic for splice and tap paths
 * This is a fallback path if nothing else determined the address (we
   use this default nearly all the time now, but it might change in future)
 * We're matching IP family and scope with the guest side source address

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Clarify semantics of --host-lo-to-ns-lo</title>
<updated>2026-07-09T01:02:34+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-06-30T04:09:47+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0d91b54eaf2ba12e584e6be985804b153cd792f6'/>
<id>0d91b54eaf2ba12e584e6be985804b153cd792f6</id>
<content type='text'>
The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoreically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with upcoming remapping of target address by forwarding rules.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoreically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with upcoming remapping of target address by forwarding rules.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd, fwd_rule: Implement configurable target address mapping</title>
<updated>2026-07-08T18:59:11+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-07T04:24:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=e67acdebc2b725a9b4f80eaec17ff0d9771229fc'/>
<id>e67acdebc2b725a9b4f80eaec17ff0d9771229fc</id>
<content type='text'>
Add a 'taddr' field to forwarding rules, which controls the destination
address on the target side.  Since changing the structure alters the pesto
update protocol, bump the protocol version number

[dwg: Split from option parsing code, added protocol version bump,
 explicitly exclude splicing with target address for now]
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>
Add a 'taddr' field to forwarding rules, which controls the destination
address on the target side.  Since changing the structure alters the pesto
update protocol, bump the protocol version number

[dwg: Split from option parsing code, added protocol version bump,
 explicitly exclude splicing with target address for now]
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: Remove duplicated logic between tcp_listen() and udp_listen()</title>
<updated>2026-06-16T21:49:57+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-06-16T01:09:35+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=50e3dcc44074dea26ed8486f65aa02d1dc2291ec'/>
<id>50e3dcc44074dea26ed8486f65aa02d1dc2291ec</id>
<content type='text'>
tcp_listen() and udp_listen() have only some simple logic around a call to
pif_listen(), and it's basically identical in each case.  If we move the
common logic into pif_listen() we can then remove {tcp,udp}_listen()
entirely, with their caller in fwd_sync_one() calling pif_listen()
directly.

We also move the logic converting from a protocol id to an epoll type from
fwd_sync_one() into pif_listen().  It's a bit arbitrary, but seems slightly
nicer that way.

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>
tcp_listen() and udp_listen() have only some simple logic around a call to
pif_listen(), and it's basically identical in each case.  If we move the
common logic into pif_listen() we can then remove {tcp,udp}_listen()
entirely, with their caller in fwd_sync_one() calling pif_listen()
directly.

We also move the logic converting from a protocol id to an epoll type from
fwd_sync_one() into pif_listen().  It's a bit arbitrary, but seems slightly
nicer that way.

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>clang-tidy: Suppress sscanf() warning harder</title>
<updated>2026-05-11T22:04:05+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-11T10:03:19+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=7bafe7163ab0bfafc3d90dcba06c1b045b57a285'/>
<id>7bafe7163ab0bfafc3d90dcba06c1b045b57a285</id>
<content type='text'>
We already have a clang-tidy suppression to stop if complaining about our
use of sscanf() in procfs_scan_listen().  However, it now (clang-tidy
22.1.4 or thereabouts) seems there's an additional warning category that
complains about the same thing.  Add that to the suppression.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
We already have a clang-tidy suppression to stop if complaining about our
use of sscanf() in procfs_scan_listen().  However, it now (clang-tidy
22.1.4 or thereabouts) seems there's an additional warning category that
complains about the same thing.  Add that to the suppression.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf, fwd: Allow switching to new rules received from pesto</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:56:00+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=4ff9887bfe630aa27178ec38c69e69f7960e1d50'/>
<id>4ff9887bfe630aa27178ec38c69e69f7960e1d50</id>
<content type='text'>
We can now receive updates to the forwarding rules from the pesto client
and store them in a "pending" copy of the forwarding tables.  Implement
switching to using the new rules.

The logic is in a new fwd_listen_switch().  For now this closes all
listening sockets related to the old tables, swaps the active and pending
tables, then listens based on the new tables.  In future we look to improve
this so that we don't temporarily stop listening on ports that both the
old and new tables specify.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: In fwd_listen_switch(), use the destination size as argument
 to memcpy(), instead of sizeof(tmp), as suggested by Laurent]
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>
We can now receive updates to the forwarding rules from the pesto client
and store them in a "pending" copy of the forwarding tables.  Implement
switching to using the new rules.

The logic is in a new fwd_listen_switch().  For now this closes all
listening sockets related to the old tables, swaps the active and pending
tables, then listens based on the new tables.  In future we look to improve
this so that we don't temporarily stop listening on ports that both the
old and new tables specify.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: In fwd_listen_switch(), use the destination size as argument
 to memcpy(), instead of sizeof(tmp), as suggested by Laurent]
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>pesto, conf: Send updated rules from pesto back to passt/pasta</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:59+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=7c5b1d72ffa4225929e99ac32604df4648d20eed'/>
<id>7c5b1d72ffa4225929e99ac32604df4648d20eed</id>
<content type='text'>
Extend pesto to send the updated rule configuration back to passt/pasta.
Extend passt/pasta to read the new configuration and store the new rules in
a "pending" table.   We don't yet attempt to activate them.

Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
[dwg: Based on an early draft from Stefano]
[sbrivio: Add redundant check on interface names being terminated in
 conf_recv_rules(), to make static checkers happy]
[sbrivio: Make conf_recv_rules() return -1 if fwd_rule_read() fails,
 as suggested by Jon Maloy]
[sbrivio: Fix conflicts in Makefile]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Extend pesto to send the updated rule configuration back to passt/pasta.
Extend passt/pasta to read the new configuration and store the new rules in
a "pending" table.   We don't yet attempt to activate them.

Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
[dwg: Based on an early draft from Stefano]
[sbrivio: Add redundant check on interface names being terminated in
 conf_recv_rules(), to make static checkers happy]
[sbrivio: Make conf_recv_rules() return -1 if fwd_rule_read() fails,
 as suggested by Jon Maloy]
[sbrivio: Fix conflicts in Makefile]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>inany: Prepare inany.[ch] for sharing 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:56+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=24c7ef9724929b6e7e3ffd35909f79f61959e57a'/>
<id>24c7ef9724929b6e7e3ffd35909f79f61959e57a</id>
<content type='text'>
inany contains a number of helpful functions for dealing with addresses
which might be IPv4 or IPv6.  We're going to want to use that in pesto.
For the most part inany doesn't depend on other passt/pasta internals,
however it does depend on siphash.h, which pesto doesn't need.

Move the single dependent function, inany_siphash_feed() to siphash.h,
renaming to match.  Use that include inany.[ch] into pesto as well as
passt/pasta.  While we're there reformat pesto.c's header comment to match
the convention used in most other files.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-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>
inany contains a number of helpful functions for dealing with addresses
which might be IPv4 or IPv6.  We're going to want to use that in pesto.
For the most part inany doesn't depend on other passt/pasta internals,
however it does depend on siphash.h, which pesto doesn't need.

Move the single dependent function, inany_siphash_feed() to siphash.h,
renaming to match.  Use that include inany.[ch] into pesto as well as
passt/pasta.  While we're there reformat pesto.c's header comment to match
the convention used in most other files.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
