diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2014-09-29 17:58:44 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2015-01-26 13:05:06 +0100 |
commit | 954a4b69b83bf71397cbb27dc742b0244e478bca (patch) | |
tree | 244c79180d9db321f6855cdc1cb8d8243e609862 | |
parent | b47d55b5004c4028b27b9153eb4e3bab1b8b82b5 (diff) | |
download | NetworkManager-954a4b69b83bf71397cbb27dc742b0244e478bca.tar.gz |
platform: refresh link cache when IPv6 tokenized identifier changes
-rw-r--r-- | src/platform/nm-linux-platform.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index a03abbebb3..fa7919b003 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -44,9 +44,9 @@ #include <netlink/route/route.h> #include <gudev/gudev.h> -#if HAVE_LIBNL_INET6_ADDR_GEN_MODE +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE || HAVE_LIBNL_INET6_TOKEN #include <netlink/route/link/inet6.h> -#if HAVE_KERNEL_INET6_ADDR_GEN_MODE +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE && HAVE_KERNEL_INET6_ADDR_GEN_MODE #include <linux/if_link.h> #else #define IN6_ADDR_GEN_MODE_EUI64 0 @@ -1900,6 +1900,37 @@ nm_nl_object_diff (ObjectType type, struct nl_object *_a, struct nl_object *_b) return TRUE; } +#if HAVE_LIBNL_INET6_TOKEN + /* libnl ignores PROTINFO changes in object without AF assigned */ + if (type == OBJECT_TYPE_LINK) { + struct rtnl_addr *a = (struct rtnl_addr *) _a; + struct rtnl_addr *b = (struct rtnl_addr *) _b; + auto_nl_addr struct nl_addr *token_a = NULL; + auto_nl_addr struct nl_addr *token_b = NULL; + + if (rtnl_link_inet6_get_token ((struct rtnl_link *) a, &token_a) != 0) + token_a = NULL; + if (rtnl_link_inet6_get_token ((struct rtnl_link *) b, &token_b) != 0) + token_b = NULL; + + if (token_a && token_b) { + if (nl_addr_get_family (token_a) == AF_INET6 && + nl_addr_get_family (token_b) == AF_INET6 && + nl_addr_get_len (token_a) == sizeof (struct in6_addr) && + nl_addr_get_len (token_b) == sizeof (struct in6_addr) && + memcmp (nl_addr_get_binary_addr (token_a), + nl_addr_get_binary_addr (token_b), + sizeof (struct in6_addr))) { + /* Token changed */ + return TRUE; + } + } else if (token_a != token_b) { + /* Token added or removed (?). */ + return TRUE; + } + } +#endif + if (type == OBJECT_TYPE_IP4_ADDRESS || type == OBJECT_TYPE_IP6_ADDRESS) { struct rtnl_addr *a = (struct rtnl_addr *) _a; struct rtnl_addr *b = (struct rtnl_addr *) _b; |