dhcpcd-discuss

Re: 8.0.4 stopped setting ipv6 default route on FreeBSD 12.0

Roy Marples

Thu Sep 05 01:59:01 2019

Hi Athan

On 05/09/2019 02:24, Athan Papadimitriou wrote:
My FreeBSD 12.0 routing setup stopped setting ipv6 default route since yesterday's dhcpcd 8.0.4 release. It used to work fine with all previous 7.xx and 8.xx versions, including 8.0.3 which is the one i downgraded to for now.

8.0.4 has a new feature:
 * inet6: Fon't install a default route if only lladdresses


My dhcpcd.conf follows

clientid
noipv4
noipv4ll
noipv6rs

No IPv6RS? Where do you expect the default route to come from?

ipv6only
release
option rapid_commit
option interface_mtu
option classless_static_routes
require dhcp_server_identifier

nohook resolv.conf, hostname, ntp, test, dump

allowinterfaces ng0 bridge0

interface ng0
     ipv6rs

OK, so default route *could* come from here.

     ipv6ra_noautoconf

But no addresses?

     iaid 0
     ia_pd 0/::/56 bridge0/0/64

So this is entirely reliant on a global address on another interface?
Fair enough. Does the attached patch help?

Roy
diff --git a/src/ipv6.c b/src/ipv6.c
index ca54dab9..958d90d6 100644
--- a/src/ipv6.c
+++ b/src/ipv6.c
@@ -1065,28 +1065,31 @@ ipv6_getstate(struct interface *ifp)
 }
 
 struct ipv6_addr *
-ipv6_ifanyglobal(struct interface *ifp)
+ipv6_anyglobal(struct dhcpcd_ctx *ctx)
 {
+	struct interface *ifp;
 	struct ipv6_state *state;
 	struct ipv6_addr *ia;
 
-	if (ifp->carrier == LINK_DOWN)
-		return NULL;
-
-	state = IPV6_STATE(ifp);
-	if (state == NULL)
-		return NULL;
+	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+		if (ifp->carrier == LINK_DOWN)
+			continue;
 
-	TAILQ_FOREACH(ia, &state->addrs, next) {
-		if (IN6_IS_ADDR_LINKLOCAL(&ia->addr))
+		state = IPV6_STATE(ifp);
+		if (state == NULL)
 			continue;
-		/* Let's be optimistic.
-		 * Any decent OS won't forward or accept traffic
-		 * from/to tentative or detached addresses. */
-		if (!(ia->addr_flags & IN6_IFF_DUPLICATED))
-			break;
+
+		TAILQ_FOREACH(ia, &state->addrs, next) {
+			if (IN6_IS_ADDR_LINKLOCAL(&ia->addr))
+				continue;
+			/* Let's be optimistic.
+			 * Any decent OS won't forward or accept traffic
+			 * from/to tentative or detached addresses. */
+			if (!(ia->addr_flags & IN6_IFF_DUPLICATED))
+				return ia;
+		}
 	}
-	return ia;
+	return NULL;
 }
 
 void
@@ -1133,7 +1136,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 		return;
 	if ((state = ipv6_getstate(ifp)) == NULL)
 		return;
-	anyglobal = ipv6_ifanyglobal(ifp) != NULL;
+	anyglobal = ipv6_anyglobal(ifp->ctx) != NULL;
 
 	TAILQ_FOREACH(ia, &state->addrs, next) {
 		if (IN6_ARE_ADDR_EQUAL(&ia->addr, addr))
@@ -1252,7 +1255,7 @@ out:
 	 * call rt_build to add/remove the default route. */
 	if (ifp->active && ifp->options->options & DHCPCD_IPV6 &&
 	    !(ctx->options & DHCPCD_RTBUILD) &&
-	    (ipv6_ifanyglobal(ifp) != NULL) != anyglobal)
+	    (ipv6_anyglobal(ifp->ctx) != NULL) != anyglobal)
 		rt_build(ctx, AF_INET6);
 }
 
@@ -2335,7 +2338,7 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx)
 		}
 		if (rap->lifetime == 0)
 			continue;
-		if (ipv6_ifanyglobal(rap->iface) == NULL)
+		if (ipv6_anyglobal(ctx) == NULL)
 			continue;
 		rt = inet6_makerouter(rap);
 		if (rt == NULL)
diff --git a/src/ipv6.h b/src/ipv6.h
index 7dbf4fe6..92db49c2 100644
--- a/src/ipv6.h
+++ b/src/ipv6.h
@@ -273,7 +273,7 @@ int ipv6_handleifa_addrs(int, struct ipv6_addrhead *, const struct ipv6_addr *,
 struct ipv6_addr *ipv6_iffindaddr(struct interface *,
     const struct in6_addr *, int);
 int ipv6_hasaddr(const struct interface *);
-struct ipv6_addr *ipv6_ifanyglobal(struct interface *);
+struct ipv6_addr *ipv6_anyglobal(struct dhcpcd_ctx *);
 int ipv6_findaddrmatch(const struct ipv6_addr *, const struct in6_addr *,
     unsigned int);
 struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
diff --git a/src/ipv6nd.c b/src/ipv6nd.c
index affc9117..d307a698 100644
--- a/src/ipv6nd.c
+++ b/src/ipv6nd.c
@@ -1290,7 +1290,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
 		}
 	}
 
-	if (new_data && !has_address && rap->lifetime && !ipv6_ifanyglobal(ifp))
+	if (new_data && !has_address &&
+	    rap->lifetime && !ipv6_anyglobal(ifp->ctx))
 		logwarnx("%s: no global addresses for default route",
 		    ifp->name);
 

Follow-Ups:
Re: 8.0.4 stopped setting ipv6 default route on FreeBSD 12.0Athan Papadimitriou
References:
8.0.4 stopped setting ipv6 default route on FreeBSD 12.0Athan Papadimitriou
Archive administrator: postmaster@marples.name