aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--fwd.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/fwd.c b/fwd.c
index 8440094..90297ef 100644
--- a/fwd.c
+++ b/fwd.c
@@ -1006,6 +1006,27 @@ bool nat_inbound(const struct ctx *c, const union inany_addr *addr,
}
/**
+ * fwd_default_geuest_addr() - Get appropriate guest address to send to
+ * @c: Execution context
+ * @guest_addr: Updated with chosen guest address
+ * @template: Address to match IP version and scope of
+ *
+ * Sets @guest_addr to have the address of the guest, matching the IP version
+ * and scope of @template where possible.
+ */
+static void fwd_default_guest_addr(const struct ctx *c,
+ union inany_addr *guest_addr,
+ const union inany_addr *template)
+{
+ if (inany_v4(template))
+ *guest_addr = inany_from_v4(c->ip4.addr_seen);
+ else if (inany_is_linklocal6(template))
+ guest_addr->a6 = c->ip6.addr_ll_seen;
+ else
+ guest_addr->a6 = c->ip6.addr_seen;
+}
+
+/**
* fwd_nat_from_host() - Determine to forward a flow from the host interface
* @c: Execution context
* @rule: Forwarding rule to apply
@@ -1040,13 +1061,9 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
*/
if (c->host_lo_to_ns_lo && inany_is_loopback(&ini->oaddr))
tgt->eaddr = ini->oaddr;
- else if (inany_v4(&ini->eaddr))
- tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
- else
- tgt->eaddr.a6 = c->ip6.addr_seen;
/* Let the kernel pick source address and port */
- if (inany_v4(&tgt->eaddr))
+ if (inany_v4(&ini->eaddr))
tgt->oaddr = inany_any4;
else
tgt->oaddr = inany_any6;
@@ -1056,6 +1073,9 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
/* But for UDP preserve the source port */
tgt->oport = ini->eport;
+ /* Use guest address as destination, if otherwise unspecified */
+ if (inany_is_unspecified(&tgt->eaddr))
+ fwd_default_guest_addr(c, &tgt->eaddr, &tgt->oaddr);
return PIF_SPLICE;
}
@@ -1074,16 +1094,12 @@ uint8_t fwd_nat_from_host(const struct ctx *c,
}
tgt->oport = ini->eport;
- if (!inany_is_unspecified(&rule->taddr)) {
+ if (!inany_is_unspecified(&rule->taddr))
tgt->eaddr = rule->taddr;
- } else if (inany_v4(&tgt->oaddr)) {
- tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
- } else {
- if (inany_is_linklocal6(&tgt->oaddr))
- tgt->eaddr.a6 = c->ip6.addr_ll_seen;
- else
- tgt->eaddr.a6 = c->ip6.addr_seen;
- }
+
+ /* Use guest address as destination, if otherwise unspecified */
+ if (inany_is_unspecified(&tgt->eaddr))
+ fwd_default_guest_addr(c, &tgt->eaddr, &tgt->oaddr);
return PIF_TAP;
}