]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
prefix delegation: Remove deleted addresses from consideration
authorRoy Marples <roy@marples.name>
Mon, 24 Apr 2017 20:08:31 +0000 (21:08 +0100)
committerRoy Marples <roy@marples.name>
Wed, 26 Apr 2017 20:07:03 +0000 (21:07 +0100)
Summary:
Currently dhcpcd does not free addresses generated from stale
Prefix Delegation leases which then expire. As the address
isn't likely to come back anytime soon it should be freed.

Related to T114.

Test Plan:
Configure your DHCPv6 server to lease a Prefix from Pool A.
Configure dhcpcd to request a Prefix Delegation and assign to
a downstream interface.
Start dhcpcd.
Configure your DHCPv6 server to lease a Prefix from Pool B.
Observe dhcpcd debug logs - it should detect the kernel
removing the deleted address and not re-add it when the prefix
changes.

Reviewers: Harri

Reviewed By: Harri

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

src/ipv6.c

index d57354f3effb7ba46ae54afe013b864e4711dfb4..1ac191ef92fbd7f33083ffb52bab9372185c1768 100644 (file)
@@ -578,6 +578,18 @@ ipv6_checkaddrflags(void *arg)
 }
 #endif
 
+static void
+ipv6_deletedaddr(struct ipv6_addr *ia)
+{
+
+       /* NOREJECT is set if we delegated exactly the prefix to another
+        * address.
+        * This can only be one address, so just clear the flag.
+        * This should ensure the reject route will be restored. */
+       if (ia->delegating_prefix != NULL)
+               ia->delegating_prefix->flags &= ~IPV6_AF_NOREJECT;
+}
+
 static void
 ipv6_deleteaddr(struct ipv6_addr *ia)
 {
@@ -590,12 +602,7 @@ ipv6_deleteaddr(struct ipv6_addr *ia)
            errno != ENXIO && errno != ENODEV)
                logerr(__func__);
 
-       /* NOREJECT is set if we delegated exactly the prefix to another
-        * address.
-        * This can only be one address, so just clear the flag.
-        * This should ensure the reject route will be restored. */
-       if (ia->delegating_prefix != NULL)
-               ia->delegating_prefix->flags &= ~IPV6_AF_NOREJECT;
+       ipv6_deletedaddr(ia);
 
        state = IPV6_STATE(ia->iface);
        TAILQ_FOREACH(ap, &state->addrs, next) {
@@ -1676,6 +1683,11 @@ ipv6_handleifa_addrs(int cmd,
                                    ia->iface->name, ia->saddr);
                                ia->flags &= ~IPV6_AF_ADDED;
                        }
+                       if (ia->flags & IPV6_AF_DELEGATED) {
+                               TAILQ_REMOVE(addrs, ia, next);
+                               ipv6_deletedaddr(ia);
+                               ipv6_freeaddr(ia);
+                       }
                        break;
                case RTM_NEWADDR:
                        /* Safety - ignore tentative announcements */