* [PATCH RFT] fwd: Only do inbound IPv6 NAT to map_host_loopback / map_guest_addr with matching scope
@ 2026-05-07 4:31 Stefano Brivio
0 siblings, 0 replies; only message in thread
From: Stefano Brivio @ 2026-05-07 4:31 UTC (permalink / raw)
To: passt-dev; +Cc: Paul Holzinger
I'm sharing this mostly for debugging / investigation of:
https://github.com/containers/container-libs/pull/755#issuecomment-4390420134
even though the change is probably correct and needed regardless of
that.
If we have map_guest_addr or map_host_loopback addresses set for IPv6,
before using them for inbound NAT from the host, make sure they match
the scope of the original packet, otherwise we might unexpectedly
turn global unicast addresses into link-local ones for packets coming
from the host itself.
Link: https://github.com/containers/container-libs/pull/755#issuecomment-4390420134
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
fwd.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/fwd.c b/fwd.c
index 0697435..d224c0a 100644
--- a/fwd.c
+++ b/fwd.c
@@ -974,6 +974,20 @@ uint8_t fwd_nat_from_splice(const struct fwd_rule *rule, uint8_t proto,
return PIF_HOST;
}
+/**
+ * fwd_scope6_match() - Check if the IPv6 scope of two addresses match
+ * @a: First address
+ * @b: Second address
+ *
+ * Return: true for two IPv6 link-local or both not link-local, false otherwise
+ *
+ * NOTE: This currently ignores any other difference in scope
+ */
+bool fwd_scope6_match(const struct in6_addr *a, const struct in6_addr *b)
+{
+ return IN6_IS_ADDR_LINKLOCAL(a) == IN6_IS_ADDR_LINKLOCAL(b);
+}
+
/**
* nat_inbound() - Apply address translation for inbound (HOST to TAP)
* @c: Execution context
@@ -993,13 +1007,15 @@ bool nat_inbound(const struct ctx *c, const union inany_addr *addr,
/* Specifically 127.0.0.1, not 127.0.0.0/8 */
*translated = inany_from_v4(c->ip4.map_host_loopback);
} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_host_loopback) &&
- inany_equals6(addr, &in6addr_loopback)) {
+ inany_equals6(addr, &in6addr_loopback) &&
+ fwd_scope6_match(&addr->a6, &c->ip6.map_host_loopback)) {
translated->a6 = c->ip6.map_host_loopback;
} else if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.map_guest_addr) &&
inany_equals4(addr, &c->ip4.addr)) {
*translated = inany_from_v4(c->ip4.map_guest_addr);
} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.map_guest_addr) &&
- inany_equals6(addr, &c->ip6.addr)) {
+ inany_equals6(addr, &c->ip6.addr) &&
+ fwd_scope6_match(&addr->a6, &c->ip6.map_guest_addr)) {
translated->a6 = c->ip6.map_guest_addr;
} else if (fwd_guest_accessible(c, addr)) {
*translated = *addr;
--
2.43.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-07 4:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-07 4:31 [PATCH RFT] fwd: Only do inbound IPv6 NAT to map_host_loopback / map_guest_addr with matching scope Stefano Brivio
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).