From 8336bd2a83a8a941bd0793a6a8e009e9241d0b64 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 24 Jun 2015 12:00:22 +0200 Subject: [PATCH] platform: properly consider address lifetimes in nm_platform_ip4_address_sync() When checking whether an address from platform should be deleted, we compare the address with our list of @known_addresses. For that we must also check for expired lifetimes, because @known_addresses might contain expired addresses. --- src/platform/nm-platform.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 666226468a..ab0aa03c33 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -39,6 +39,8 @@ #include "nm-enum-types.h" #include "nm-core-internal.h" +#define ADDRESS_LIFETIME_PADDING 5 + G_STATIC_ASSERT (sizeof ( ((NMPlatformLink *) NULL)->addr.data ) == NM_UTILS_HWADDR_LEN_MAX); #define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) @@ -1954,7 +1956,7 @@ nm_platform_ip6_address_exists (NMPlatform *self, int ifindex, struct in6_addr a } static gboolean -array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address *address) +array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address *address, gint64 now, guint32 padding) { guint len = addresses ? addresses->len : 0; guint i; @@ -1962,15 +1964,20 @@ array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address for (i = 0; i < len; i++) { NMPlatformIP4Address *candidate = &g_array_index (addresses, NMPlatformIP4Address, i); - if (candidate->address == address->address && candidate->plen == address->plen) - return TRUE; + if (candidate->address == address->address && candidate->plen == address->plen) { + guint32 lifetime, preferred; + + if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred, + now, padding, &lifetime, &preferred)) + return TRUE; + } } return FALSE; } static gboolean -array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address *address) +array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address *address, gint64 now, guint32 padding) { guint len = addresses ? addresses->len : 0; guint i; @@ -1978,8 +1985,13 @@ array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address for (i = 0; i < len; i++) { NMPlatformIP6Address *candidate = &g_array_index (addresses, NMPlatformIP6Address, i); - if (IN6_ARE_ADDR_EQUAL (&candidate->address, &address->address) && candidate->plen == address->plen) - return TRUE; + if (IN6_ARE_ADDR_EQUAL (&candidate->address, &address->address) && candidate->plen == address->plen) { + guint32 lifetime, preferred; + + if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred, + now, padding, &lifetime, &preferred)) + return TRUE; + } } return FALSE; @@ -2033,7 +2045,7 @@ nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known for (i = 0; i < addresses->len; i++) { address = &g_array_index (addresses, NMPlatformIP4Address, i); - if (!array_contains_ip4_address (known_addresses, address)) + if (!array_contains_ip4_address (known_addresses, address, now, ADDRESS_LIFETIME_PADDING)) nm_platform_ip4_address_delete (self, ifindex, address->address, address->plen, address->peer_address); } g_array_free (addresses, TRUE); @@ -2048,9 +2060,8 @@ nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known guint32 network; gboolean reinstall_device_route = FALSE; - /* add a padding of 5 seconds to avoid potential races. */ if (!nmp_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, 5, &lifetime, &preferred)) + now, ADDRESS_LIFETIME_PADDING, &lifetime, &preferred)) continue; if (nm_platform_ip4_check_reinstall_device_route (self, ifindex, known_address, device_route_metric)) @@ -2109,7 +2120,7 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known if (keep_link_local && IN6_IS_ADDR_LINKLOCAL (&address->address)) continue; - if (!array_contains_ip6_address (known_addresses, address)) + if (!array_contains_ip6_address (known_addresses, address, now, ADDRESS_LIFETIME_PADDING)) nm_platform_ip6_address_delete (self, ifindex, address->address, address->plen); } g_array_free (addresses, TRUE); @@ -2122,9 +2133,8 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known const NMPlatformIP6Address *known_address = &g_array_index (known_addresses, NMPlatformIP6Address, i); guint32 lifetime, preferred; - /* add a padding of 5 seconds to avoid potential races. */ if (!nmp_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, 5, &lifetime, &preferred)) + now, ADDRESS_LIFETIME_PADDING, &lifetime, &preferred)) continue; if (!nm_platform_ip6_address_add (self, ifindex, known_address->address,