aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-07-13 15:38:55 +1000
committerStefano Brivio <sbrivio@redhat.com>2026-07-15 01:22:47 +0200
commit9013b5911f5f53d34e6e1a2f4683c616a13d2209 (patch)
tree98cdcf65f0a13e4307dde5934ef36f3838c24d6e
parentaddd76dd9bc4306aa620bb0177d63368a24dc59d (diff)
downloadpasst-9013b5911f5f53d34e6e1a2f4683c616a13d2209.tar
passt-9013b5911f5f53d34e6e1a2f4683c616a13d2209.tar.gz
passt-9013b5911f5f53d34e6e1a2f4683c616a13d2209.tar.bz2
passt-9013b5911f5f53d34e6e1a2f4683c616a13d2209.tar.lz
passt-9013b5911f5f53d34e6e1a2f4683c616a13d2209.tar.xz
passt-9013b5911f5f53d34e6e1a2f4683c616a13d2209.tar.zst
passt-9013b5911f5f53d34e6e1a2f4683c616a13d2209.zip
fwd: Reorder DNAPT and SNAT steps in fwd_nat_from_host()
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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--fwd.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/fwd.c b/fwd.c
index de444d9..1369bae 100644
--- a/fwd.c
+++ b/fwd.c
@@ -1038,8 +1038,12 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
const struct fwd_rule *rule, uint8_t proto,
const struct flowside *ini, struct flowside *tgt)
{
- /* Common for spliced and non-spliced cases */
+ /* DNAPT: Common for splice and non-spliced where possible */
tgt->eport = rule->to + (ini->oport - rule->first);
+ if (!inany_is_unspecified(&rule->taddr))
+ tgt->eaddr = rule->taddr;
+ else if (c->host_lo_to_ns_lo && inany_is_loopback(&ini->oaddr))
+ tgt->eaddr = ini->oaddr;
/* TODO: Allow splicing with specified target address */
if (!c->no_splice && inany_is_unspecified(&rule->taddr) &&
@@ -1056,10 +1060,8 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
* In either case, let the kernel pick the source address to
* match.
*/
- if (c->host_lo_to_ns_lo && inany_is_loopback(&ini->oaddr))
- tgt->eaddr = ini->oaddr;
- /* Let the kernel pick source address and port */
+ /* SNAT: (implicit) let the kernel pick source addr/port */
if (inany_v4(&ini->eaddr))
tgt->oaddr = inany_any4;
else
@@ -1079,6 +1081,7 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
if (c->splice_only)
return PIF_NONE;
+ /* SNAT: translate source address if necessary */
if (!nat_inbound(c, &ini->eaddr, &tgt->oaddr)) {
if (inany_v4(&ini->eaddr)) {
if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.our_tap_addr))
@@ -1091,9 +1094,6 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
}
tgt->oport = ini->eport;
- if (!inany_is_unspecified(&rule->taddr))
- tgt->eaddr = rule->taddr;
-
/* Use guest address as destination, if otherwise unspecified */
if (inany_is_unspecified(&tgt->eaddr))
tgt->eaddr = fwd_default_guest_addr(c, &tgt->oaddr);