summaryrefslogtreecommitdiffstats
path: root/src/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-09-05 10:03:13 +0100
committerRoy Marples <roy@marples.name>2019-09-05 10:03:13 +0100
commit2489dc550bc0fdae4d2a038e11060b1b9dd87f70 (patch)
treef1269173d44f998307ad580c5805ada7119cca38 /src/ipv6.c
parent93d62baa841b77feb06dd3d6bc73b469609c4f89 (diff)
downloaddhcpcd-2489dc550bc0fdae4d2a038e11060b1b9dd87f70.tar.xz
inet6: Fix default route not being installed
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.
Diffstat (limited to 'src/ipv6.c')
-rw-r--r--src/ipv6.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/src/ipv6.c b/src/ipv6.c
index ca54dab9..99f6a8a4 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 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)