]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
DHCPv6: deprecate addresses on stale leases.
authorRoy Marples <roy@marples.name>
Mon, 24 Apr 2017 19:50:45 +0000 (20:50 +0100)
committerRoy Marples <roy@marples.name>
Fri, 5 May 2017 13:26:46 +0000 (14:26 +0100)
Summary:
When a DHCPv6 Address or Prefix Delegation is leased, it may not be renewed as a
different one could be assigned. In this situation, we should
prompt the kernel to prefer this new one by deprecating the old
one. This is achieved by setting it's pltime to zero.

Related to T114.

Test Plan:
Configure your DHCPv6 server to assign a delegation from Pool A.
Configure dhcpcd to lease a Prefix delegation and assign it
to a downstream interface.
Start dhcpcd.
Configure your DHCPv6 server to asssign a delegation from Pool B.
Down/Up the link dhcpcd is using.
dhcpcd should assign the new delegation and depreate the old
by marking it's pltime as zero.

Reviewers: sthen, Harri

Reviewed By: Harri

Differential Revision: https://dev.marples.name/D108

src/dhcp6.c

index ee38fb0544f0583a1339bb1f99fa3f60e237d351..264779ece04bd54ff5e33d49865f5675ea7c029e 100644 (file)
@@ -2163,15 +2163,25 @@ dhcp6_findia(struct interface *ifp, struct dhcp6_message *m, size_t l,
        }
 
        TAILQ_FOREACH_SAFE(ap, &state->addrs, next, nap) {
-               if (ap->flags & IPV6_AF_STALE) {
-                       eloop_q_timeout_delete(ifp->ctx->eloop, 0, NULL, ap);
-                       if (ap->flags & IPV6_AF_REQUEST) {
-                               ap->prefix_vltime = ap->prefix_pltime = 0;
-                       } else {
-                               TAILQ_REMOVE(&state->addrs, ap, next);
-                               free(ap);
+               if (!(ap->flags & IPV6_AF_STALE))
+                       continue;
+               if (ap->flags & IPV6_AF_REQUEST) {
+                       ap->prefix_vltime = ap->prefix_pltime = 0;
+                       eloop_q_timeout_delete(ifp->ctx->eloop,
+                           0, NULL, ap);
+                       continue;
+               }
+               TAILQ_REMOVE(&state->addrs, ap, next);
+               if (ap->flags & IPV6_AF_DELEGATEDPFX) {
+                       struct ipv6_addr *da;
+
+                       /* Deprecate delegated addresses. */
+                       TAILQ_FOREACH(da, &ap->pd_pfxs, pd_next) {
+                               da->prefix_pltime = 0;
                        }
+                       ipv6_addaddrs(&ap->pd_pfxs);
                }
+               ipv6_freeaddr(ap);
        }
        if (i == 0 && e)
                return -1;