dhcpcd-discuss

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;

Follow-Ups:
Re: Not getting IPv6 link local address when link carrier goes up -> down -> upFloris Bos
References:
Not getting IPv6 link local address when link carrier goes up -> down -> upFloris Bos
Re: Not getting IPv6 link local address when link carrier goes up -> down -> upFloris Bos
Archive administrator: postmaster@marples.name