From c3c927d1d13d6b2a5bfc9732370dbe6bc4fbebdb Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 29 Sep 2014 17:58:44 +0200 Subject: [PATCH] platform: refresh link cache when IPv6 tokenized identifier changes (cherry picked from commit 954a4b69b83bf71397cbb27dc742b0244e478bca) --- src/platform/nm-linux-platform.c | 35 ++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 98cd7cc953..22e5102f67 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -44,9 +44,9 @@ #include #include -#if HAVE_LIBNL_INET6_ADDR_GEN_MODE +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE || HAVE_LIBNL_INET6_TOKEN #include -#if HAVE_KERNEL_INET6_ADDR_GEN_MODE +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE && HAVE_KERNEL_INET6_ADDR_GEN_MODE #include #else #define IN6_ADDR_GEN_MODE_EUI64 0 @@ -1905,6 +1905,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;