diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2018-05-30 11:37:09 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-05-30 17:59:57 +0200 |
commit | 851d89dc6ab59cd19de03fc842893fabe8c33036 (patch) | |
tree | fb29dadac00b2686f1c460697e231f6938da3f6c | |
parent | 54356ac8c7ee922a51c0a5428839d31b58d7ea92 (diff) | |
download | NetworkManager-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.c | 26 |
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; |