[PATCH v2 0/5] Fix bug 209
Here are a handful of changes to forwarding ant multicast handling, that fix bug 209. It also gets us closer to correct multicast handling, though we're certainly not there yet - multicast things currently only really work at all because IP_MULTICAST_ALL defaults to on, and for the common protocols the host is likely to be already a group member. v2: * Assorted minor polish based on feedback David Gibson (5): fwd: Clarify semantics of --host-lo-to-ns-lo udp: Validate that we have a unicast source address fwd: Rework default address logic for inbound flows fwd: Reorder DNAPT and SNAT steps in fwd_nat_from_host() fwd: Don't rewrite inbound multicast destinations conf.c | 2 ++ fwd.c | 58 ++++++++++++++++++++++++++++++++---------------------- inany.h | 2 ++ passt.1 | 9 +++++---- udp_flow.c | 2 +- 5 files changed, 45 insertions(+), 28 deletions(-) -- 2.55.0
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
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 theoretically, 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 other upcoming changes to the forwarding logic.
Signed-off-by: David Gibson
When creating a UDP flow from a socket we, correctly, check that the source
address is unicast - multicast addresses are not valid as a source address.
However, when creating a flow from tap we only check the source address
is specified, not that it is unicast. Correct this.
Signed-off-by: David Gibson
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
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
On Mon, 13 Jul 2026 15:38:52 +1000
David Gibson
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 theoretically, 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 other upcoming changes to the forwarding logic.
Signed-off-by: David Gibson
I added: Link: https://bugs.passt.top/show_bug.cgi?id=212 -- Stefano
On Mon, 13 Jul 2026 15:38:51 +1000
David Gibson
Here are a handful of changes to forwarding ant multicast handling, that fix bug 209. It also gets us closer to correct multicast handling, though we're certainly not there yet - multicast things currently only really work at all because IP_MULTICAST_ALL defaults to on, and for the common protocols the host is likely to be already a group member.
v2: * Assorted minor polish based on feedback
Applied. -- Stefano
On Wed, Jul 15, 2026 at 09:11:30AM +0200, Stefano Brivio wrote:
On Mon, 13 Jul 2026 15:38:52 +1000 David Gibson
wrote: 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 theoretically, 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 other upcoming changes to the forwarding logic.
Signed-off-by: David Gibson
I added:
Thanks. Having fixed the bug before it was reported, I chose not to strain my powers of precognition by also predicting the bug number :). -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
participants (2)
-
David Gibson
-
Stefano Brivio