]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
ipv6nd: drop DHCPv6 when RA fully expires
authorRoy Marples <roy@marples.name>
Fri, 2 Mar 2018 15:00:07 +0000 (15:00 +0000)
committerRoy Marples <roy@marples.name>
Fri, 2 Mar 2018 15:00:07 +0000 (15:00 +0000)
Fixes an error where RA addresses would expire but the DHCPv6
lease still persisted.

src/dhcp6.c
src/ipv6nd.c

index b05a90d262f148194a1c19a78e68edb153dc89b6..06d6732763201ccdd0d1baf67bca95ca1b1dbe26 100644 (file)
@@ -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
index 0f4542edb7696a81b6c8457cb49a235bf62522fb..bbd02cb6089f856434ea7838247add81bf4b271a 100644 (file)
@@ -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, &lt, &expire);
@@ -1375,6 +1378,7 @@ ipv6nd_expirera(void *arg)
                                if (!timespecisset(&next) ||
                                    timespeccmp(&next, &lt, >))
                                        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);
 }