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
---
fwd.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/fwd.c b/fwd.c
index 90297ef7..7d39898e 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);
--
2.55.0