summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-05-30 11:37:09 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2018-05-30 17:59:57 +0200
commit851d89dc6ab59cd19de03fc842893fabe8c33036 (patch)
treefb29dadac00b2686f1c460697e231f6938da3f6c
parent54356ac8c7ee922a51c0a5428839d31b58d7ea92 (diff)
downloadNetworkManager-851d89dc6ab59cd19de03fc842893fabe8c33036.tar.gz
platform: sort known IPv6 addresses by scope before a sync
The order we want to enforce is only among addresses with the same scope, as the kernel always keeps addresses sorted by scope. Therefore, apply the same sorting to known addresses, so that we don't try to unnecessary change the order of addresses with different scopes. https://bugzilla.redhat.com/show_bug.cgi?id=1578668
-rw-r--r--src/platform/nm-platform.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 727e064bd5..1a94ce282a 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -3595,6 +3595,25 @@ delete_and_next2:
return TRUE;
}
+static guint
+ip6_address_scope_priority (const struct in6_addr *addr)
+{
+ if (IN6_IS_ADDR_LINKLOCAL (addr))
+ return 1;
+ if (IN6_IS_ADDR_SITELOCAL (addr))
+ return 2;
+ return 3;
+}
+
+static gint
+ip6_address_scope_cmp (gconstpointer a, gconstpointer b)
+{
+ const NMPlatformIP6Address *x = NMP_OBJECT_CAST_IP6_ADDRESS (*(const void **) a);
+ const NMPlatformIP6Address *y = NMP_OBJECT_CAST_IP6_ADDRESS (*(const void **) b);
+
+ return ip6_address_scope_priority (&x->address) - ip6_address_scope_priority (&y->address);
+}
+
/**
* nm_platform_ip6_address_sync:
* @self: platform instance
@@ -3628,6 +3647,13 @@ nm_platform_ip6_address_sync (NMPlatform *self,
NMPLookup lookup;
guint32 ifa_flags;
+ /* The order we want to enforce is only among addresses with the same
+ * scope, as the kernel keeps addresses sorted by scope. Therefore,
+ * apply the same sorting to known addresses, so that we don't try to
+ * unnecessary change the order of addresses with different scopes. */
+ if (known_addresses)
+ g_ptr_array_sort (known_addresses, ip6_address_scope_cmp);
+
if (!_addr_array_clean_expired (AF_INET6, ifindex, known_addresses, now, &known_addresses_idx))
known_addresses = NULL;