From: Roy Marples Date: Fri, 2 Mar 2018 15:00:07 +0000 (+0000) Subject: ipv6nd: drop DHCPv6 when RA fully expires X-Git-Tag: v7.0.2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=680ed015bbdeae655121b908b9cffe0c18946287;p=thirdparty%2Fdhcpcd.git ipv6nd: drop DHCPv6 when RA fully expires Fixes an error where RA addresses would expire but the DHCPv6 lease still persisted. --- diff --git a/src/dhcp6.c b/src/dhcp6.c index b05a90d2..06d67327 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -3860,9 +3860,14 @@ dhcp6_dropnondelegates(struct interface *ifp) { #ifndef SMALL - if (dhcp6_hasprefixdelegation(ifp) == 0) + if (dhcp6_hasprefixdelegation(ifp)) + return; #endif - dhcp6_drop(ifp, "EXPIRE6"); + if (D6_CSTATE(ifp) == NULL) + return; + + loginfox("%s: dropping DHCPv6 due to no valid routers", ifp->name); + dhcp6_drop(ifp, "EXPIRE6"); } void diff --git a/src/ipv6nd.c b/src/ipv6nd.c index 0f4542ed..bbd02cb6 100644 --- a/src/ipv6nd.c +++ b/src/ipv6nd.c @@ -1313,7 +1313,7 @@ ipv6nd_expirera(void *arg) struct interface *ifp; struct ra *rap, *ran; struct timespec now, lt, expire, next; - uint8_t expired, valid, validone; + uint8_t expired, anyvalid, valid, validone; struct ipv6_addr *ia; ifp = arg; @@ -1321,11 +1321,11 @@ ipv6nd_expirera(void *arg) expired = 0; timespecclear(&next); - validone = 0; + anyvalid = 0; TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) { if (rap->iface != ifp) continue; - valid = 0; + valid = validone = 0; if (rap->lifetime) { lt.tv_sec = (time_t)rap->lifetime; lt.tv_nsec = 0; @@ -1351,9 +1351,12 @@ ipv6nd_expirera(void *arg) * the kernel can expire, so we need to handle it ourself. * Also, some OS don't support address lifetimes (Solaris). */ TAILQ_FOREACH(ia, &rap->addrs, next) { - if (ia->prefix_vltime == ND6_INFINITE_LIFETIME || - ia->prefix_vltime == 0) + if (ia->prefix_vltime == 0) continue; + if (ia->prefix_vltime == ND6_INFINITE_LIFETIME) { + validone = 1; + continue; + } lt.tv_sec = (time_t)ia->prefix_vltime; lt.tv_nsec = 0; timespecadd(&ia->acquired, <, &expire); @@ -1375,6 +1378,7 @@ ipv6nd_expirera(void *arg) if (!timespecisset(&next) || timespeccmp(&next, <, >)) next = lt; + validone = 1; } } @@ -1385,10 +1389,10 @@ ipv6nd_expirera(void *arg) /* No valid lifetimes are left on the RA, so we might * as well punt it. */ - if (!valid && TAILQ_FIRST(&rap->addrs) == NULL) + if (!valid && !validone) ipv6nd_free_ra(rap); else - validone = 1; + anyvalid = 1; } if (timespecisset(&next)) @@ -1400,7 +1404,7 @@ ipv6nd_expirera(void *arg) } /* No valid routers? Kill any DHCPv6. */ - if (!validone) + if (!anyvalid) dhcp6_dropnondelegates(ifp); }