diff options
author | Thomas Haller <thaller@redhat.com> | 2014-06-09 10:03:01 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-06-19 22:26:10 +0200 |
commit | c29496125f32211e3337db3250aacc5a89e13325 (patch) | |
tree | c492dcca85cead01f5817761afa639ffb9387106 | |
parent | a2791f54da771cf7354dfdc4a420aaf772a8c6ee (diff) | |
download | NetworkManager-c29496125f32211e3337db3250aacc5a89e13325.tar.gz |
platform: handle unset address timestamp as *now* in to_string()
When printing an address in nm_platform_ip4_address_to_string()
and nm_platform_ip6_address_to_string() treat an unset @timestamp
as counting from @now.
This is useful, if you just have the remaining lifetime at hand
and want to print an address. In general it is not a good idea to
leave the timestamp not anchored to an absolute @timestamp.
Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r-- | src/platform/nm-platform.c | 28 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 21 |
2 files changed, 39 insertions, 10 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 71c60ca5bf..17f452c547 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1436,6 +1436,7 @@ nm_platform_ip4_address_add (int ifindex, addr.address = address; addr.peer_address = peer_address; addr.plen = plen; + addr.timestamp = 0; /* set it at zero, which to_string will treat as *now* */ addr.lifetime = lifetime; addr.preferred = preferred; if (label) @@ -1470,6 +1471,7 @@ nm_platform_ip6_address_add (int ifindex, addr.address = address; addr.peer_address = peer_address; addr.plen = plen; + addr.timestamp = 0; /* set it to zero, which to_string will treat as *now* */ addr.lifetime = lifetime; addr.preferred = preferred; addr.flags = flags; @@ -1571,6 +1573,17 @@ _rebase_relative_time_on_now (guint32 timestamp, guint32 duration, guint32 now, if (duration == NM_PLATFORM_LIFETIME_PERMANENT) return NM_PLATFORM_LIFETIME_PERMANENT; + if (timestamp == 0) { + /* if the @timestamp is zero, assume it was just left unset and that the relative + * @duration starts counting from @now. This is convenient to construct an address + * and print it in nm_platform_ip4_address_to_string(). + * + * In general it does not make sense to set the @duration without anchoring at + * @timestamp because you don't know the absolute expiration time when looking + * at the address at a later moment. */ + timestamp = now; + } + /* For timestamp > now, just accept it and calculate the expected(?) result. */ t = (gint64) timestamp + (gint64) duration - (gint64) now; @@ -1597,13 +1610,18 @@ _address_get_lifetime (const NMPlatformIPAddress *address, guint32 now, guint32 if (!lifetime) return FALSE; preferred = _rebase_relative_time_on_now (address->timestamp, address->preferred, now, padding); - if (preferred > lifetime) { - g_warn_if_reached (); - preferred = lifetime; - } *out_lifetime = lifetime; - *out_preferred = preferred; + *out_preferred = MIN (preferred, lifetime); + + /* Assert that non-permanent addresses have a (positive) @timestamp. _rebase_relative_time_on_now() + * treats addresses with timestamp 0 as *now*. Addresses passed to _address_get_lifetime() always + * should have a valid @timestamp, otherwise on every re-sync, their lifetime will be extended anew. + */ + g_return_val_if_fail ( address->timestamp != 0 + || ( address->lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && address->preferred == NM_PLATFORM_LIFETIME_PERMANENT), TRUE); + g_return_val_if_fail (preferred <= lifetime, TRUE); } return TRUE; } diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 7dc0127648..96b6cfabbd 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -167,11 +167,22 @@ typedef struct { NMPlatformSource source; \ \ /* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*(). - * This value is mainly used to anchor the relative lifetime and preferred values. - * For addresses originating from DHCP it might be set to nm_utils_get_monotonic_timestamp_s() - * of when the lease was received. For addresses from platform/kernel it might be set to - * when the address was last modified. For permanent addresses it is mostly set to 0. - * For non-permanent addresses it should not be 0 (because 0 is not a valid timestamp). + * + * The rules are: + * 1 @lifetime==0: @timestamp and @preferred is irrelevant (but mostly set to 0 too). Such addresses + * are permanent. This rule is so that unset addresses (calloc) are permanent by default. + * 2 @lifetime==@preferred==NM_PLATFORM_LIFETIME_PERMANENT: @timestamp is irrelevant (but mostly + * set to 0). Such addresses are permanent. + * 3 Non permanent addreses should (almost) always have @timestamp > 0. 0 is not a valid timestamp + * and never returned by nm_utils_get_monotonic_timestamp_s(). In this case @valid/@preferred + * is anchored at @timestamp. + * 4 Non permanent addresses with @timestamp == 0 are implicitely anchored at *now*, thus the time + * moves as time goes by. This is usually not useful, except e.g. nm_platform_ip[46]_address_add(). + * + * Non permanent addresses from DHCP/RA might have the @timestamp set to the moment of when the + * lease was received. Addresses from kernel might have the @timestamp based on the last modification + * time of the addresses. But don't rely on this behaviour, the @timestamp is only defined for anchoring + * @lifetime and @preferred. */ \ guint32 timestamp; \ guint32 lifetime; /* seconds since timestamp */ \ |