diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2024-06-07 09:48:20 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2024-06-07 09:48:20 +0000 |
commit | 111693711acb83a0ac5459d966b139ac968d38e0 (patch) | |
tree | 60c3c931f4ab19acf81ccd4e6f73a05e97d8435d /sys/netinet6 | |
parent | fb76c2fa0111d39b72e26bed56fb93c6039e52ec (diff) |
Fix slaac on P2P interfaces
slaacd(8) can work on P2P interfaces, it will just never configure the
destination address. But this works fine on at least pppoe(4) and
tun(4).
To make this less confusing pull ifra_dstaddr into dst6 or gw6
depending on if we are doing autoconf or not.
I accidentally broke this when implementing rule 5.5 of RFC 6724.
reported by & testing naddy
OK bluhm
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index d5e8e2c25a7..9202ddacb21 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.266 2024/05/21 15:12:25 florian Exp $ */ +/* $OpenBSD: in6.c,v 1.267 2024/06/07 09:48:19 florian Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -549,7 +549,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia6) { int error = 0, hostIsNew = 0, plen = -1; - struct sockaddr_in6 dst6; + struct sockaddr_in6 dst6, gw6; struct in6_addrlifetime *lt; struct in6_multi_mship *imm; struct rtentry *rt; @@ -604,7 +604,13 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL); } - dst6 = ifra->ifra_dstaddr; + if (ifra->ifra_flags & IN6_IFF_AUTOCONF) { + gw6 = ifra->ifra_dstaddr; + memset(&dst6, 0, sizeof(dst6)); + } else { + dst6 = ifra->ifra_dstaddr; + memset(&gw6, 0, sizeof(gw6)); + } if (dst6.sin6_family == AF_INET6) { error = in6_check_embed_scope(&dst6, ifp->if_index); if (error) @@ -614,6 +620,11 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, (ifp->if_flags & IFF_LOOPBACK)) && plen != 128) return (EINVAL); } + if (gw6.sin6_family == AF_INET6) { + error = in6_check_embed_scope(&gw6, ifp->if_index); + if (error) + return error; + } /* lifetime consistency check */ lt = &ifra->ifra_lifetime; if (lt->ia6t_pltime > lt->ia6t_vltime) @@ -702,10 +713,10 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, } if ((ifra->ifra_flags & IN6_IFF_AUTOCONF) && - dst6.sin6_family == AF_INET6 && + gw6.sin6_family == AF_INET6 && !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_gwaddr.sin6_addr)) { /* Set or update announcing router */ - ia6->ia_gwaddr = dst6; + ia6->ia_gwaddr = gw6; } /* |