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);
Archive administrator: postmaster@marples.name