]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
inet6: Fix default route not being installed
authorRoy Marples <roy@marples.name>
Thu, 5 Sep 2019 09:03:13 +0000 (10:03 +0100)
committerRoy Marples <roy@marples.name>
Thu, 5 Sep 2019 09:03:13 +0000 (10:03 +0100)
We need to check for global addresses on any forwarding interface,
not just the interface we received the RA on.
Otherwise this breaks routers who get a default route only
from the RA and IPv6 addresses only by prefix delegation to
other interfaces.

src/ipv6.c
src/ipv6.h
src/ipv6nd.c

index ca54dab91a1240b71a0004fec5e2426b4f41148c..99f6a8a423256b44c55e7633b738fcc354e781ed 100644 (file)
@@ -1065,28 +1065,31 @@ ipv6_getstate(struct interface *ifp)
 }
 
 struct ipv6_addr *
-ipv6_ifanyglobal(struct interface *ifp)
+ipv6_anyglobal(struct interface *sifp)
 {
+       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, sifp->ctx->ifaces, next) {
+               if (ifp != sifp && ip6_forwarding(ifp->name) != 1)
+                       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) != 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) != 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(rap->iface) == NULL)
                        continue;
                rt = inet6_makerouter(rap);
                if (rt == NULL)
index 7dbf4fe69248cfbc9cd055d199032afeb1eed2ea..547957eb15dcaca3f8a69c760c41b233bf4e5b83 100644 (file)
@@ -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 interface *);
 int ipv6_findaddrmatch(const struct ipv6_addr *, const struct in6_addr *,
     unsigned int);
 struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
index affc911708b325c801137ac1e497caa965e68569..929b071d090bd1fab3ed7b73572988a54f305a17 100644 (file)
@@ -1290,7 +1290,7 @@ 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))
                logwarnx("%s: no global addresses for default route",
                    ifp->name);