summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2024-06-07 09:48:20 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2024-06-07 09:48:20 +0000
commit111693711acb83a0ac5459d966b139ac968d38e0 (patch)
tree60c3c931f4ab19acf81ccd4e6f73a05e97d8435d /sys/netinet6
parentfb76c2fa0111d39b72e26bed56fb93c6039e52ec (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.c21
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;
}
/*