63 lines
1.9 KiB
Diff
63 lines
1.9 KiB
Diff
|
From 45e441ada6d3ea4355d623cf12d9a559a5c2afde Mon Sep 17 00:00:00 2001
|
||
|
From: Roy Marples <roy@marples.name>
|
||
|
Date: Tue, 23 May 2023 22:14:57 +0100
|
||
|
Subject: [PATCH] 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.
|
||
|
---
|
||
|
src/if-linux.c | 24 +++++++++++++++++-------
|
||
|
1 file changed, 17 insertions(+), 7 deletions(-)
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|