From: Roy Marples Date: Mon, 24 Apr 2017 20:08:31 +0000 (+0100) Subject: prefix delegation: Remove deleted addresses from consideration X-Git-Tag: v7.0.0-rc1~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=621b634849b4f79291b257e2dd04749fded7e64d;p=thirdparty%2Fdhcpcd.git prefix delegation: Remove deleted addresses from consideration 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 --- diff --git a/src/ipv6.c b/src/ipv6.c index d57354f3..1ac191ef 100644 --- a/src/ipv6.c +++ b/src/ipv6.c @@ -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 */