changeset 5195:45226e01fbdd draft

inet6: Move BSD get/set scope function to ipv6 for general use It seems that FreeBSD doesn't allow binding to scoped addresses, so let's use our functions everwhere rather than directly setting scope.
author Roy Marples <roy@marples.name>
date Thu, 07 May 2020 14:29:44 +0100
parents c37ba778f32b
children 6f2362548171
files src/dhcp6.c src/if-bsd.c src/ipv6.c src/ipv6.h
diffstat 4 files changed, 54 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/src/dhcp6.c	Thu May 07 00:08:41 2020 +0100
+++ b/src/dhcp6.c	Thu May 07 14:29:44 2020 +0100
@@ -3223,12 +3223,14 @@
 			state->state = DH6S_BOUND;
 		state->failed = false;
 
-		if (state->renew && state->renew != ND6_INFINITE_LIFETIME)
+		if ((state->renew != 0 || state->rebind != 0) &&
+		    state->renew != ND6_INFINITE_LIFETIME)
 			eloop_timeout_add_sec(ifp->ctx->eloop,
 			    state->renew,
 			    state->state == DH6S_INFORMED ?
 			    dhcp6_startinform : dhcp6_startrenew, ifp);
-		if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME)
+		if ((state->rebind != 0 || state->expire != 0) &&
+		    state->rebind != ND6_INFINITE_LIFETIME)
 			eloop_timeout_add_sec(ifp->ctx->eloop,
 			    state->rebind, dhcp6_startrebind, ifp);
 		if (state->expire != ND6_INFINITE_LIFETIME)
@@ -3792,7 +3794,7 @@
 
 	if (ia != NULL) {
 		memcpy(&sa.sin6_addr, ia, sizeof(sa.sin6_addr));
-		sa.sin6_scope_id = ifindex;
+		ipv6_setscope(&sa, ifindex);
 	}
 
 	if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1)
--- a/src/if-bsd.c	Thu May 07 00:08:41 2020 +0100
+++ b/src/if-bsd.c	Thu May 07 14:29:44 2020 +0100
@@ -109,11 +109,6 @@
 	NULL
 };
 
-#ifdef INET6
-static void ifa_setscope(struct sockaddr_in6 *, unsigned int);
-static unsigned int ifa_getscope(const struct sockaddr_in6 *);
-#endif
-
 struct priv {
 	int pf_inet6_fd;
 };
@@ -580,7 +575,7 @@
 		struct ipv6_addr *ia;
 
 		sin = (const void *)sa;
-		scope = ifa_getscope(sin);
+		scope = ipv6_getscope(sin);
 		if (scope != 0)
 			return if_findindex(ctx->ifaces, scope);
 		if ((ia = ipv6_findmaskaddr(ctx, &sin->sin6_addr)))
@@ -737,7 +732,7 @@
 			if_copysa(&gateway.sa, &rt->rt_gateway);
 #ifdef INET6
 			if (gateway.sa.sa_family == AF_INET6)
-				ifa_setscope(&gateway.sin6, rt->rt_ifp->index);
+				ipv6_setscope(&gateway.sin6, rt->rt_ifp->index);
 #endif
 			ADDSA(&gateway.sa);
 		}
@@ -960,44 +955,6 @@
 #endif /* INET */
 
 #ifdef INET6
-static void
-ifa_setscope(struct sockaddr_in6 *sin, unsigned int ifindex)
-{
-
-#ifdef __KAME__
-	/* KAME based systems want to store the scope inside the sin6_addr
-	 * for link local addresses */
-	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) {
-		uint16_t scope = htons((uint16_t)ifindex);
-		memcpy(&sin->sin6_addr.s6_addr[2], &scope,
-		    sizeof(scope));
-	}
-	sin->sin6_scope_id = 0;
-#else
-	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
-		sin->sin6_scope_id = ifindex;
-	else
-		sin->sin6_scope_id = 0;
-#endif
-}
-
-static unsigned int
-ifa_getscope(const struct sockaddr_in6 *sin)
-{
-#ifdef __KAME__
-	uint16_t scope;
-#endif
-
-	if (!IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
-		return 0;
-#ifdef __KAME__
-	memcpy(&scope, &sin->sin6_addr.s6_addr[2], sizeof(scope));
-	return (unsigned int)ntohs(scope);
-#else
-	return (unsigned int)sin->sin6_scope_id;
-#endif
-}
-
 static int
 if_ioctl6(struct dhcpcd_ctx *ctx, unsigned long req, void *data, size_t len)
 {
@@ -1042,7 +999,7 @@
 	}
 
 	ADDADDR(&ifa.ifra_addr, &ia->addr);
-	ifa_setscope(&ifa.ifra_addr, ia->iface->index);
+	ipv6_setscope(&ifa.ifra_addr, ia->iface->index);
 	ipv6_mask(&mask, ia->prefix_len);
 	ADDADDR(&ifa.ifra_prefixmask, &mask);
 
@@ -1120,7 +1077,7 @@
 	strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
 	ifr6.ifr_addr.sin6_family = AF_INET6;
 	ifr6.ifr_addr.sin6_addr = *addr;
-	ifa_setscope(&ifr6.ifr_addr, ifp->index);
+	ipv6_setscope(&ifr6.ifr_addr, ifp->index);
 	priv = (struct priv *)ifp->ctx->priv;
 	if (ioctl(priv->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
 		flags = ifr6.ifr_ifru.ifru_flags6;
@@ -1141,7 +1098,7 @@
 	strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
 	ifr6.ifr_addr.sin6_family = AF_INET6;
 	ifr6.ifr_addr.sin6_addr = ia->addr;
-	ifa_setscope(&ifr6.ifr_addr, ia->iface->index);
+	ipv6_setscope(&ifr6.ifr_addr, ia->iface->index);
 	priv = (struct priv *)ia->iface->ctx->priv;
 	if (ioctl(priv->pf_inet6_fd, SIOCGIFALIFETIME_IN6, &ifr6) == -1)
 		return -1;
@@ -1517,7 +1474,7 @@
 
 #ifdef INET6
 	if (sa->sa_family == AF_INET6)
-		ifa_setscope(satosin6(sa), ifp->index);
+		ipv6_setscope(satosin6(sa), ifp->index);
 #else
 	UNUSED(ifp);
 #endif
@@ -1530,7 +1487,7 @@
 
 #ifdef INET6
 	if (sa->sa_family == AF_INET6)
-		ifa_setscope(satosin6(sa), 0);
+		ipv6_setscope(satosin6(sa), 0);
 #endif
 
 	return 0;
--- a/src/ipv6.c	Thu May 07 00:08:41 2020 +0100
+++ b/src/ipv6.c	Thu May 07 14:29:44 2020 +0100
@@ -1532,6 +1532,44 @@
 	return ipv6_addlinklocal(ifp);
 }
 
+void
+ipv6_setscope(struct sockaddr_in6 *sin, unsigned int ifindex)
+{
+
+#ifdef __KAME__
+	/* KAME based systems want to store the scope inside the sin6_addr
+	 * for link local addresses */
+	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) {
+		uint16_t scope = htons((uint16_t)ifindex);
+		memcpy(&sin->sin6_addr.s6_addr[2], &scope,
+		    sizeof(scope));
+	}
+	sin->sin6_scope_id = 0;
+#else
+	if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
+		sin->sin6_scope_id = ifindex;
+	else
+		sin->sin6_scope_id = 0;
+#endif
+}
+
+unsigned int
+ipv6_getscope(const struct sockaddr_in6 *sin)
+{
+#ifdef __KAME__
+	uint16_t scope;
+#endif
+
+	if (!IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
+		return 0;
+#ifdef __KAME__
+	memcpy(&scope, &sin->sin6_addr.s6_addr[2], sizeof(scope));
+	return (unsigned int)ntohs(scope);
+#else
+	return (unsigned int)sin->sin6_scope_id;
+#endif
+}
+
 struct ipv6_addr *
 ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
     uint8_t prefix_len, unsigned int flags)
--- a/src/ipv6.h	Thu May 07 00:08:41 2020 +0100
+++ b/src/ipv6.h	Thu May 07 14:29:44 2020 +0100
@@ -287,8 +287,10 @@
     const struct in6_addr *);
 #define ipv6_linklocal(ifp) ipv6_iffindaddr((ifp), NULL, IN6_IFF_NOTUSEABLE)
 int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *);
-struct ipv6_addr *ipv6_newaddr(struct interface *, const struct in6_addr *, uint8_t,
-    unsigned int);
+void ipv6_setscope(struct sockaddr_in6 *, unsigned int);
+unsigned int ipv6_getscope(const struct sockaddr_in6 *);
+struct ipv6_addr *ipv6_newaddr(struct interface *, const struct in6_addr *,
+    uint8_t, unsigned int);
 void ipv6_freeaddr(struct ipv6_addr *);
 void ipv6_freedrop(struct interface *, int);
 #define ipv6_free(ifp) ipv6_freedrop((ifp), 0)