summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2014-09-29 17:58:44 +0200
committerLubomir Rintel <lkundrak@v3.sk>2015-01-26 13:05:06 +0100
commit954a4b69b83bf71397cbb27dc742b0244e478bca (patch)
tree244c79180d9db321f6855cdc1cb8d8243e609862
parentb47d55b5004c4028b27b9153eb4e3bab1b8b82b5 (diff)
downloadNetworkManager-954a4b69b83bf71397cbb27dc742b0244e478bca.tar.gz
platform: refresh link cache when IPv6 tokenized identifier changes
-rw-r--r--src/platform/nm-linux-platform.c35
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;