aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-07-10 15:26:51 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2026-07-10 15:26:51 +1000
commit2ef86a35c5f9e2c518329a64162ecee7838f190a (patch)
tree74c0f7cfffe47258bef99fa6f66d456ce139b0d9
parent058d9cfed9289654fa0be94b09d8d0bfd13648b7 (diff)
downloadpasst-2ef86a35c5f9e2c518329a64162ecee7838f190a.tar
passt-2ef86a35c5f9e2c518329a64162ecee7838f190a.tar.gz
passt-2ef86a35c5f9e2c518329a64162ecee7838f190a.tar.bz2
passt-2ef86a35c5f9e2c518329a64162ecee7838f190a.tar.lz
passt-2ef86a35c5f9e2c518329a64162ecee7838f190a.tar.xz
passt-2ef86a35c5f9e2c518329a64162ecee7838f190a.tar.zst
passt-2ef86a35c5f9e2c518329a64162ecee7838f190a.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>
-rw-r--r--fwd.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/fwd.c b/fwd.c
index 90297ef..7d39898 100644
--- a/fwd.c
+++ b/fwd.c
@@ -1041,8 +1041,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) &&
@@ -1059,10 +1063,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
@@ -1082,6 +1084,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))
@@ -1094,9 +1097,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))
fwd_default_guest_addr(c, &tgt->eaddr, &tgt->oaddr);