Re: Not getting IPv6 link local address when link carrier goes up -> down -> up
Roy Marples
Mon Oct 21 10:31:32 2019
On 20/10/2019 23:04, Floris Bos wrote:
Played a bit with adding a couple more debug logging statements to the
code.
The problem seems to be that after the link local address is added, the
kernel eventually sends you a RTM_NEWADDR event.
Upon receipt of the event you add the IPv6 address to your state->addrs
list.
After it gets removed the kernel eventually sends a RTM_DELADDR and you
remove it again from the list.
The problem is that those events arrive delayed, and we are hitting a
situation in which the RTM_NEWADDR event is not delivered until after
the address has been deleted. And RTM_DELADDR is even lagging further
behind.
Since state->addr still has the address in the list,
ipv6_tryaddlinklocal() thinks there is already a link local address, so
does no attempt to add one.
Does this patch help at all?
Roy
diff --git a/src/ipv6.c b/src/ipv6.c
index 8a77a401..ef3e899f 100644
--- a/src/ipv6.c
+++ b/src/ipv6.c
@@ -1146,6 +1146,10 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
switch (cmd) {
case RTM_DELADDR:
if (ia != NULL) {
+ if (if_getlifetime6(ia) != -1 || errno != ENOTSUP) {
+ /* Address still exists. */
+ return;
+ }
TAILQ_REMOVE(&state->addrs, ia, next);
#ifdef ND6_ADVERTISE
/* Advertise the address if it exists on
@@ -1162,14 +1166,21 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
strlcpy(ia->alias, ifname, sizeof(ia->alias));
#endif
if (if_getlifetime6(ia) == -1) {
- /* No support or address vanished.
- * Either way, just set a deprecated
- * infinite time lifetime and continue.
+ if (errno != ENOTSUP) {
+ /* Address no longer exists. */
+ ipv6_freeaddr(ia);
+ return;
+ }
+ /*
+ * No support for address lifetimes in kernel.
+ * Hust set a deprecated infinite time lifetime
+ * and continue.
* This is fine because we only want
* to know this when trying to extend
* temporary addresses.
* As we can't extend infinite, we'll
- * create a new temporary address. */
+ * create a new temporary address.
+ */
ia->prefix_pltime = 0;
ia->prefix_vltime =
ND6_INFINITE_LIFETIME;
Archive administrator: postmaster@marples.name