For inbound packets address to host's ::1 we rewrite the source address to be the @nattohost address. Unless the @nattohost address is not link local, in which case we use the host's link-local address instead. Confusingly we don't mirror this logic for outbound packets. We rewrite the destination for packets bound to @nattohost into ::1, but we don't alter packets bound for the host's link-local address. This will probably still work in most cases, since the host's link-local address will still go to the host, but it's a weird assymetry. Remove the assymetry and simplify the code, by always using the @nattohost address alone, but instead setting the @nattohost address to the host link-local address rather than the gateway if the gateway isn't a link-local address. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- conf.c | 8 ++++++-- tcp.c | 5 +---- udp.c | 5 +---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/conf.c b/conf.c index dd8a835..45f49eb 100644 --- a/conf.c +++ b/conf.c @@ -737,8 +737,12 @@ static unsigned int conf_ip6(unsigned int ifi, struct ip6_ctx *ip6, if (MAC_IS_ZERO(mac)) nl_link(0, ifi, mac, 0, 0); - if (gwnat && IN6_IS_ADDR_UNSPECIFIED(&ip6->nattohost)) - ip6->nattohost = ip6->router; + if (gwnat && IN6_IS_ADDR_UNSPECIFIED(&ip6->nattohost)) { + if (IN6_IS_ADDR_LINKLOCAL(&ip6->router)) + ip6->nattohost = ip6->router; + else + ip6->nattohost = ip6->addr_ll; + } if (IN6_IS_ADDR_UNSPECIFIED(&ip6->router) || IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) || diff --git a/tcp.c b/tcp.c index aa65d6e..d91e786 100644 --- a/tcp.c +++ b/tcp.c @@ -2718,10 +2718,7 @@ static void tcp_snat_inbound(const struct ctx *c, union inany_addr *addr) if (IN6_IS_ADDR_LOOPBACK(addr6) || IN6_ARE_ADDR_EQUAL(addr6, &c->ip6.addr_seen) || IN6_ARE_ADDR_EQUAL(addr6, &c->ip6.addr)) { - if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.nattohost)) - *addr6 = c->ip6.nattohost; - else - *addr6 = c->ip6.addr_ll; + *addr6 = c->ip6.nattohost; } } } diff --git a/udp.c b/udp.c index 6234a8d..6cd2813 100644 --- a/udp.c +++ b/udp.c @@ -662,10 +662,7 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport, bitmap_set(udp_act[V6][UDP_ACT_TAP], src_port); - if (IN6_IS_ADDR_LINKLOCAL(&c->ip6.nattohost)) - src = &c->ip6.nattohost; - else - src = &c->ip6.addr_ll; + src = &c->ip6.nattohost; } b->ip6h.saddr = *src; -- 2.40.1