Currently, most places we use c->ip[46].nattohost we also need to check c->no_map_gw to see if we should even be applying this address remapping. However, now that the remapping address is split into its own field we can just use the unspecified address to indicate no remapping, and avoid the extra flag. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- conf.c | 35 +++++++++++++++++++++-------------- passt.h | 2 -- tcp.c | 10 ++++------ udp.c | 6 ++---- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/conf.c b/conf.c index bfc825b..dd8a835 100644 --- a/conf.c +++ b/conf.c @@ -418,12 +418,13 @@ static void add_dns4(struct ctx *c, struct in_addr *addr, struct in_addr **conf) { /* Guest or container can only access local addresses via redirect */ if (IN4_IS_ADDR_LOOPBACK(addr)) { - if (!c->no_map_gw) { - **conf = c->ip4.nattohost; + const struct in_addr *nat = &c->ip4.nattohost; + if (!IN4_IS_ADDR_UNSPECIFIED(nat)) { + **conf = *nat; (*conf)++; if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.dns_match)) - c->ip4.dns_match = c->ip4.nattohost; + c->ip4.dns_match = *nat; } } else { **conf = *addr; @@ -445,8 +446,9 @@ static void add_dns6(struct ctx *c, { /* Guest or container can only access local addresses via redirect */ if (IN6_IS_ADDR_LOOPBACK(addr)) { - if (!c->no_map_gw) { - memcpy(*conf, &c->ip6.nattohost, sizeof(**conf)); + const struct in6_addr *nat = &c->ip6.nattohost; + if (!IN6_IS_ADDR_UNSPECIFIED(nat)) { + memcpy(*conf, nat, sizeof(**conf)); (*conf)++; if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns_match)) @@ -628,11 +630,12 @@ static int conf_ip4_prefix(const char *arg) * @ifi: Host interface to attempt (0 to determine one) * @ip4: IPv4 context (will be written) * @mac: MAC address to use (written if unset) + * @gwnat: If set, use gateway as default nattohost address * * Return: Interface index for IPv4, or 0 on failure. */ -static unsigned int conf_ip4(unsigned int ifi, - struct ip4_ctx *ip4, unsigned char *mac) +static unsigned int conf_ip4(unsigned int ifi, struct ip4_ctx *ip4, + unsigned char *mac, bool gwnat) { in_addr_t addr, gw; int shift; @@ -688,7 +691,8 @@ static unsigned int conf_ip4(unsigned int ifi, if (MAC_IS_ZERO(mac)) nl_link(0, ifi, mac, 0, 0); - ip4->nattohost = ip4->router; + if (gwnat && IN4_IS_ADDR_UNSPECIFIED(&ip4->nattohost)) + ip4->nattohost = ip4->router; if (IN4_IS_ADDR_UNSPECIFIED(&ip4->router) || IN4_IS_ADDR_UNSPECIFIED(&ip4->addr) || @@ -703,11 +707,12 @@ static unsigned int conf_ip4(unsigned int ifi, * @ifi: Host interface to attempt (0 to determine one) * @ip6: IPv6 context (will be written) * @mac: MAC address to use (written if unset) + * @gwnat: If set, use gateway as default nattohost address * * Return: Interface index for IPv6, or 0 on failure. */ -static unsigned int conf_ip6(unsigned int ifi, - struct ip6_ctx *ip6, unsigned char *mac) +static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6, + unsigned char *mac, bool gwnat) { int prefix_len = 0; @@ -732,7 +737,8 @@ static unsigned int conf_ip6(unsigned int ifi, if (MAC_IS_ZERO(mac)) nl_link(0, ifi, mac, 0, 0); - ip6->nattohost = ip6->router; + if (gwnat && IN6_IS_ADDR_UNSPECIFIED(&ip6->nattohost)) + ip6->nattohost = ip6->router; if (IN6_IS_ADDR_UNSPECIFIED(&ip6->router) || IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) || @@ -1163,6 +1169,7 @@ static void conf_ugid(char *runas, uid_t *uid, gid_t *gid) void conf(struct ctx *c, int argc, char **argv) { int netns_only = 0; + int no_map_gw = 0; struct option options[] = { {"debug", no_argument, NULL, 'd' }, {"quiet", no_argument, NULL, 'q' }, @@ -1191,7 +1198,7 @@ void conf(struct ctx *c, int argc, char **argv) {"no-dhcpv6", no_argument, &c->no_dhcpv6, 1 }, {"no-ndp", no_argument, &c->no_ndp, 1 }, {"no-ra", no_argument, &c->no_ra, 1 }, - {"no-map-gw", no_argument, &c->no_map_gw, 1 }, + {"no-map-gw", no_argument, &no_map_gw, 1 }, {"ipv4-only", no_argument, NULL, '4' }, {"ipv6-only", no_argument, NULL, '6' }, {"one-off", no_argument, NULL, '1' }, @@ -1671,9 +1678,9 @@ void conf(struct ctx *c, int argc, char **argv) nl_sock_init(c, false); if (!v6_only) - c->ifi4 = conf_ip4(ifi4, &c->ip4, c->mac); + c->ifi4 = conf_ip4(ifi4, &c->ip4, c->mac, !no_map_gw); if (!v4_only) - c->ifi6 = conf_ip6(ifi6, &c->ip6, c->mac); + c->ifi6 = conf_ip6(ifi6, &c->ip6, c->mac, !no_map_gw); if ((!c->ifi4 && !c->ifi6) || (*c->ip4.ifname_out && !c->ifi4) || (*c->ip6.ifname_out && !c->ifi6)) diff --git a/passt.h b/passt.h index e308fe1..9f05bca 100644 --- a/passt.h +++ b/passt.h @@ -201,7 +201,6 @@ struct ip6_ctx { * @no_dhcpv6: Disable DHCPv6 server * @no_ndp: Disable NDP handler altogether * @no_ra: Disable router advertisements - * @no_map_gw: Don't map connections, untracked UDP to gateway to host * @low_wmem: Low probed net.core.wmem_max * @low_rmem: Low probed net.core.rmem_max */ @@ -261,7 +260,6 @@ struct ctx { int no_dhcpv6; int no_ndp; int no_ra; - int no_map_gw; int low_wmem; int low_rmem; diff --git a/tcp.c b/tcp.c index b0dacab..aa65d6e 100644 --- a/tcp.c +++ b/tcp.c @@ -2040,12 +2040,10 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, if ((s = tcp_conn_new_sock(c, af)) < 0) return; - if (!c->no_map_gw) { - if (af == AF_INET && IN4_ARE_ADDR_EQUAL(addr, &c->ip4.nattohost)) - addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost)) - addr6.sin6_addr = in6addr_loopback; - } + if (af == AF_INET && IN4_ARE_ADDR_EQUAL(addr, &c->ip4.nattohost)) + addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost)) + addr6.sin6_addr = in6addr_loopback; if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr)) { struct sockaddr_in6 addr6_ll = { diff --git a/udp.c b/udp.c index 1533cee..6234a8d 100644 --- a/udp.c +++ b/udp.c @@ -841,8 +841,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.dns_match) && ntohs(s_in.sin_port) == 53) { s_in.sin_addr = c->ip4.dns_host; - } else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.nattohost) && - !c->no_map_gw) { + } else if (IN4_ARE_ADDR_EQUAL(&s_in.sin_addr, &c->ip4.nattohost)) { if (!(udp_tap_map[V4][dst].flags & PORT_LOCAL) || (udp_tap_map[V4][dst].flags & PORT_LOOPBACK)) s_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -887,8 +886,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) && ntohs(s_in6.sin6_port) == 53) { s_in6.sin6_addr = c->ip6.dns_host; - } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost) && - !c->no_map_gw) { + } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.nattohost)) { if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) || (udp_tap_map[V6][dst].flags & PORT_LOOPBACK)) s_in6.sin6_addr = in6addr_loopback; -- 2.40.1