From 99d77596cdc0a5d3861aebc03485d8cf9c02dd1e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 29 Mar 2022 22:45:56 +0200 Subject: [PATCH] platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get() nmp_utils_lifetime_get() calculates the lifetime of addresses, and it bases the result on a "now" timestamp. If you have two addresses and calculate their expiry, then we want to base it on top of the same "now" timestamp, meaning, we should only call nm_utils_get_monotonic_timestamp_sec() once. This is also a performance optimization. But much more importantly, when we make a comparison at a certain moment, we need that all sides have the same understanding of the current timestamp. But nmp_utils_lifetime_get() does not always require the now timestamp. And the caller doesn't know, whether it will need it (short of knowing how nmp_utils_lifetime_get() is implemented). So, make the now parameter an in/out argument. If we pass in an already valid now timestamp, use that. Otherwise, fetch the current time and also return it. (cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712) (cherry picked from commit 9e40474c715e995c000b29db030b4a4990cc6e51) --- src/core/ndisc/nm-ndisc.c | 3 ++- src/libnm-platform/nm-platform-utils.c | 12 +++++++----- src/libnm-platform/nm-platform-utils.h | 2 +- src/libnm-platform/nm-platform.c | 13 +++++++------ 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c index 969eacfaba..04b673e51d 100644 --- a/src/core/ndisc/nm-ndisc.c +++ b/src/core/ndisc/nm-ndisc.c @@ -996,6 +996,7 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd) const NMPObject *obj; guint len; guint i; + gint32 fake_now = NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000; nm_assert(NM_IS_NDISC(ndisc)); nm_assert(nm_ndisc_get_node_type(ndisc) == NM_NDISC_NODE_TYPE_ROUTER); @@ -1018,7 +1019,7 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd) lifetime = nmp_utils_lifetime_get(addr->timestamp, addr->lifetime, addr->preferred, - NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, + &fake_now, &preferred); if (!lifetime) continue; diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c index 9ad030df76..bebc53a851 100644 --- a/src/libnm-platform/nm-platform-utils.c +++ b/src/libnm-platform/nm-platform-utils.c @@ -2132,12 +2132,15 @@ guint32 nmp_utils_lifetime_get(guint32 timestamp, guint32 lifetime, guint32 preferred, - gint32 now, + gint32 *cached_now, guint32 *out_preferred) { - guint32 t_lifetime, t_preferred; + guint32 t_lifetime; + guint32 t_preferred; + gint32 now; - nm_assert(now >= 0); + nm_assert(cached_now); + nm_assert(*cached_now >= 0); if (timestamp == 0 && lifetime == 0) { /* We treat lifetime==0 && timestamp==0 addresses as permanent addresses to allow easy @@ -2150,8 +2153,7 @@ nmp_utils_lifetime_get(guint32 timestamp, return NM_PLATFORM_LIFETIME_PERMANENT; } - if (now <= 0) - now = nm_utils_get_monotonic_timestamp_sec(); + now = nm_utils_get_monotonic_timestamp_sec_cached(cached_now); t_lifetime = nmp_utils_lifetime_rebase_relative_time_on_now(timestamp, lifetime, now); if (!t_lifetime) { diff --git a/src/libnm-platform/nm-platform-utils.h b/src/libnm-platform/nm-platform-utils.h index a9ccebb3e2..9f17da4886 100644 --- a/src/libnm-platform/nm-platform-utils.h +++ b/src/libnm-platform/nm-platform-utils.h @@ -86,7 +86,7 @@ nmp_utils_lifetime_rebase_relative_time_on_now(guint32 timestamp, guint32 durati guint32 nmp_utils_lifetime_get(guint32 timestamp, guint32 lifetime, guint32 preferred, - gint32 now, + gint32 *cached_now, guint32 *out_preferred); int nmp_utils_modprobe(GError **error, gboolean suppress_error_logging, const char *arg1, ...) diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 00a3fb2a0a..ea7aad9398 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -3632,7 +3632,7 @@ static gboolean _addr_array_clean_expired(int addr_family, int ifindex, GPtrArray *array, - guint32 now, + gint32 *cached_now, GHashTable **idx) { guint i; @@ -3640,7 +3640,8 @@ _addr_array_clean_expired(int addr_family, nm_assert_addr_family(addr_family); nm_assert(ifindex > 0); - nm_assert(now > 0); + nm_assert(cached_now); + nm_assert(*cached_now >= 0); if (!array) return FALSE; @@ -3674,7 +3675,7 @@ _addr_array_clean_expired(int addr_family, goto clear_and_next; } - if (!nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, now, NULL)) + if (!nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, cached_now, NULL)) goto clear_and_next; if (idx) { @@ -3920,7 +3921,7 @@ nm_platform_ip_address_sync(NMPlatform *self, GPtrArray *known_addresses, GPtrArray *addresses_prune) { - const gint32 now = nm_utils_get_monotonic_timestamp_sec(); + gint32 now = 0; const int IS_IPv4 = NM_IS_IPv4(addr_family); NMPLookup lookup; gs_unref_hashtable GHashTable *known_addresses_idx = NULL; @@ -3950,7 +3951,7 @@ nm_platform_ip_address_sync(NMPlatform *self, if (!_addr_array_clean_expired(addr_family, ifindex, known_addresses, - now, + &now, &known_addresses_idx)) known_addresses = NULL; @@ -4218,7 +4219,7 @@ next_plat:; lifetime = nmp_utils_lifetime_get(known_address->ax.timestamp, known_address->ax.lifetime, known_address->ax.preferred, - now, + &now, &preferred); nm_assert(lifetime > 0);