From: Roy Marples Date: Tue, 23 May 2023 21:14:57 +0000 (+0100) Subject: Linux: Improve learning IPv6 address flags X-Git-Tag: v10.0.2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45e441ada6d3ea4355d623cf12d9a559a5c2afde;p=thirdparty%2Fdhcpcd.git Linux: Improve learning IPv6 address flags Rather than matching addresses during netlink message processing, extract the local, address and flag parts. Once done, then match local and address to the address we are looking for and if equal apply the flags. Fixes #201 and maybe #149. --- diff --git a/src/if-linux.c b/src/if-linux.c index f2f609ed..212ed5df 100644 --- a/src/if-linux.c +++ b/src/if-linux.c @@ -1996,7 +1996,8 @@ _if_addrflags6(__unused struct dhcpcd_ctx *ctx, size_t len; struct rtattr *rta; struct ifaddrmsg *ifa; - bool matches_addr = false; + struct in6_addr *local = NULL, *address = NULL; + uint32_t *flags = NULL; ifa = NLMSG_DATA(nlm); if (ifa->ifa_index != ia->ifa_ifindex || ifa->ifa_family != AF_INET6) @@ -2007,17 +2008,26 @@ _if_addrflags6(__unused struct dhcpcd_ctx *ctx, for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) { switch (rta->rta_type) { case IFA_ADDRESS: - if (IN6_ARE_ADDR_EQUAL(&ia->ifa_addr, (struct in6_addr *)RTA_DATA(rta))) - ia->ifa_found = matches_addr = true; - else - matches_addr = false; + address = (struct in6_addr *)RTA_DATA(rta); + break; + case IFA_LOCAL: + local = (struct in6_addr *)RTA_DATA(rta); break; case IFA_FLAGS: - if (matches_addr) - memcpy(&ia->ifa_flags, RTA_DATA(rta), sizeof(ia->ifa_flags)); + flags = (uint32_t *)RTA_DATA(rta); break; } } + + if (local) { + if (IN6_ARE_ADDR_EQUAL(&ia->ifa_addr, local)) + ia->ifa_found = true; + } else if (address) { + if (IN6_ARE_ADDR_EQUAL(&ia->ifa_addr, address)) + ia->ifa_found = true; + } + if (flags && ia->ifa_found) + memcpy(&ia->ifa_flags, flags, sizeof(ia->ifa_flags)); return 0; }