dhcpcd-discuss

Re: Not getting IPv6 link local address when link carrier goes up -> down -> up

Roy Marples

Tue Oct 22 07:54:02 2019

On 21/10/2019 21:56, Floris Bos wrote:
On 21/10/2019 12:33, Roy Marples wrote:
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?


No difference.

OK ..... try this one instead :)
Remove the prior one please first.

Roy
diff --git a/src/if-linux.c b/src/if-linux.c
index fd472785..520e4f7d 100644
--- a/src/if-linux.c
+++ b/src/if-linux.c
@@ -626,6 +626,7 @@ link_addr(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm)
 #endif
 #ifdef INET6
 	struct in6_addr addr6;
+	int flags;
 #endif
 
 	if (nlm->nlmsg_type != RTM_DELADDR && nlm->nlmsg_type != RTM_NEWADDR)
@@ -674,6 +675,8 @@ link_addr(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm)
 			}
 			rta = RTA_NEXT(rta, len);
 		}
+
+		/* XXX how to validate command for address? */
 		ipv4_handleifa(ctx, nlm->nlmsg_type, NULL, ifp->name,
 		    &addr, &net, &brd, ifa->ifa_flags, (pid_t)nlm->nlmsg_pid);
 		break;
@@ -690,6 +693,18 @@ link_addr(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm)
 			}
 			rta = RTA_NEXT(rta, len);
 		}
+
+		/* Validate RTM_DELADDR really means address deleted
+		 * and anything else really means address exists. */
+		flags = if_addrflags6(ifp, &addr6, NULL);
+		if (nlm->nlmsg_type == RTM_DELADDR) {
+			if (flags != -1)
+				break;
+		} else {
+			if (flags == -1)
+				break;
+		}
+
 		ipv6_handleifa(ctx, nlm->nlmsg_type, NULL, ifp->name,
 		    &addr6, ifa->ifa_prefixlen, ifa->ifa_flags,
 		    (pid_t)nlm->nlmsg_pid);

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
Re: Not getting IPv6 link local address when link carrier goes up -> down -> upRoy Marples
Re: Not getting IPv6 link local address when link carrier goes up -> down -> upFloris Bos
Archive administrator: postmaster@marples.name