diff options
| author | David Gibson <david@gibson.dropbear.id.au> | 2026-07-13 15:38:55 +1000 |
|---|---|---|
| committer | Stefano Brivio <sbrivio@redhat.com> | 2026-07-15 01:22:47 +0200 |
| commit | 9013b5911f5f53d34e6e1a2f4683c616a13d2209 (patch) | |
| tree | 98cdcf65f0a13e4307dde5934ef36f3838c24d6e | |
| parent | addd76dd9bc4306aa620bb0177d63368a24dc59d (diff) | |
| download | passt-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.c | 14 |
1 files changed, 7 insertions, 7 deletions
@@ -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); |
