diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2021-10-20 11:10:23 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2021-10-20 11:10:23 +0200 |
commit | 9618d247006a41fba5c1b0470e4723196f96b424 (patch) | |
tree | 915f636f855f4cae765ecb1eb6542a387282633f /tcp.c | |
parent | 12cfa6444cd239dbc04391027ad3161f53b6901c (diff) | |
download | passt-9618d247006a41fba5c1b0470e4723196f96b424.tar passt-9618d247006a41fba5c1b0470e4723196f96b424.tar.gz passt-9618d247006a41fba5c1b0470e4723196f96b424.tar.bz2 passt-9618d247006a41fba5c1b0470e4723196f96b424.tar.lz passt-9618d247006a41fba5c1b0470e4723196f96b424.tar.xz passt-9618d247006a41fba5c1b0470e4723196f96b424.tar.zst passt-9618d247006a41fba5c1b0470e4723196f96b424.zip |
ndp, dhcpv6, tcp, udp: Always use link-local as source if gateway isn't
This shouldn't happen on any sane configuration, but I just met an
example of that: the default IPv6 gateway on the host is configured
with a global unicast address, we use that as source for RA, DHCPv6
replies, and the guest ignores it. Same later on if we talk TCP or
UDP and the guest has no idea where that address comes from.
Use our link-local address in case the gateway address is global.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'tcp.c')
-rw-r--r-- | tcp.c | 12 |
1 files changed, 10 insertions, 2 deletions
@@ -2921,8 +2921,16 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref, if (IN6_IS_ADDR_LOOPBACK(&sa6.sin6_addr) || !memcmp(&sa6.sin6_addr, &c->addr6_seen, sizeof(c->gw6)) || - !memcmp(&sa6.sin6_addr, &c->addr6, sizeof(c->gw6))) - memcpy(&sa6.sin6_addr, &c->gw6, sizeof(c->gw6)); + !memcmp(&sa6.sin6_addr, &c->addr6, sizeof(c->gw6))) { + struct in6_addr *src; + + if (IN6_IS_ADDR_LINKLOCAL(&c->gw6)) + src = &c->gw6; + else + src = &c->addr6_ll; + + memcpy(&sa6.sin6_addr, src, sizeof(*src)); + } memcpy(&conn->a.a6, &sa6.sin6_addr, sizeof(conn->a.a6)); |