diff options
author | Thomas Haller <thaller@redhat.com> | 2018-02-07 22:21:31 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-02-09 17:40:01 +0100 |
commit | 7f223cb82720cb04f7cd0de9d3759d0b76d4aa53 (patch) | |
tree | 25aa2ae895485f77eabcf4da28da47f010521702 | |
parent | 7459548f2351a11f00f19c26fa98dc19e88258cd (diff) | |
download | NetworkManager-7f223cb82720cb04f7cd0de9d3759d0b76d4aa53.tar.gz |
platform: refactor initial cleanup of know-addresses list in nm_platform_ip4_address_sync()
We do a pre-run that constructs an index of all addresses and drops
addresses that are already expired.
Move this code to a separate function, it will be reused for IPv6.
Also, note that nm_platform_ip4_address_sync() has only 2 callers. Both
callers make sure to not pass duplicate known addresses, because the
addresses also come from a cache. Make that a requirement and assert
against unique addresses. If we would allow duplicate addresses, we would
have to handle them in a defined way (like, dropping the ones with lower
priority). That would be more complicated, and since no caller is
supposed to provide duplicate addresses, don't bother but assert.
-rw-r--r-- | src/platform/nm-platform.c | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index c475d07a11..8a53f7c6a4 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -3125,6 +3125,60 @@ nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr addr return NMP_OBJECT_CAST_IP6_ADDRESS (obj); } +static gboolean +_addr_array_clean_expired (int addr_family, int ifindex, GPtrArray *array, guint32 now, GHashTable **idx) +{ + guint i; + gboolean any_addrs = FALSE; + + nm_assert_addr_family (addr_family); + nm_assert (ifindex > 0); + nm_assert (now > 0); + + if (!array) + return FALSE; + + /* remove all addresses that are already expired. */ + for (i = 0; i < array->len; i++) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS (array->pdata[i]); + +#if NM_MORE_ASSERTS > 10 + nm_assert (a); + nm_assert (a->ifindex == ifindex); + { + const NMPObject *o = NMP_OBJECT_UP_CAST (a); + guint j; + + nm_assert (NMP_OBJECT_GET_CLASS (o)->addr_family == addr_family); + for (j = i + 1; j < array->len; j++) { + const NMPObject *o2 = array->pdata[j]; + + nm_assert (NMP_OBJECT_GET_TYPE (o) == NMP_OBJECT_GET_TYPE (o2)); + nm_assert (!nmp_object_id_equal (o, o2)); + } + } +#endif + + if (nm_utils_lifetime_get (a->timestamp, a->lifetime, a->preferred, + now, NULL)) { + if (idx) { + if (G_UNLIKELY (!*idx)) { + *idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal); + } + if (!g_hash_table_add (*idx, (gpointer) NMP_OBJECT_UP_CAST (a))) + nm_assert_not_reached (); + } + any_addrs = TRUE; + continue; + } + + nmp_object_unref (g_steal_pointer (&array->pdata[i])); + } + + return any_addrs; +} + static int array_ip6_address_position (const GPtrArray *addresses, const NMPlatformIP6Address *address, @@ -3336,39 +3390,8 @@ nm_platform_ip4_address_sync (NMPlatform *self, _CHECK_SELF (self, klass, FALSE); - if (known_addresses) { - /* remove all addresses that are already expired. */ - for (i = 0; i < known_addresses->len; i++) { - const NMPObject *o; - - o = known_addresses->pdata[i]; - nm_assert (o); - - known_address = NMP_OBJECT_CAST_IP4_ADDRESS (known_addresses->pdata[i]); - - if (!nm_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, NULL)) - goto delete_and_next; - - if (G_UNLIKELY (!known_addresses_idx)) { - known_addresses_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); - } - if (!g_hash_table_insert (known_addresses_idx, (gpointer) o, (gpointer) o)) { - /* duplicate? Keep only the first instance. */ - goto delete_and_next; - } - - continue; -delete_and_next: - nmp_object_unref (o); - known_addresses->pdata[i] = NULL; - } - - if ( !known_addresses_idx - || g_hash_table_size (known_addresses_idx) == 0) - known_addresses = NULL; - } + if (!_addr_array_clean_expired (AF_INET, ifindex, known_addresses, now, &known_addresses_idx)) + known_addresses = NULL; plat_addresses = nm_platform_lookup_clone (self, nmp_lookup_init_object (&lookup, |