diff options
author | Thomas Haller <thaller@redhat.com> | 2014-04-03 12:24:32 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-05-03 03:44:23 +0200 |
commit | 78b8af6651ddbaca4633b3a275df5c5c13f89695 (patch) | |
tree | 08e51c36e3585a2bc781ec96f22950ff3eea50db | |
parent | 9cd7b40a047bb4bbc2e9470158470c43badcc109 (diff) | |
download | NetworkManager-78b8af6651ddbaca4633b3a275df5c5c13f89695.tar.gz |
core: preserve later expiry in nm_ip[46]_config_add_address()
When adding the same addresses from different sources, we want to
preserve the times with the later expiry . If the new address comes
from the kernel itself, we treat it specially and prefer the times
from other sources.
Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r-- | src/nm-ip4-config.c | 28 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 23 |
2 files changed, 43 insertions, 8 deletions
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 505bc851ff..12aac78519 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1018,7 +1018,7 @@ void nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - NMPlatformSource old_source; + NMPlatformIP4Address item_old; int i; g_return_if_fail (new != NULL); @@ -1029,10 +1029,28 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) if (addresses_are_duplicate (item, new, FALSE)) { if (nm_platform_ip4_address_cmp (item, new) == 0) return; - old_source = item->source; - memcpy (item, new, sizeof (*item)); - /* Restore highest priority source */ - item->source = MAX (old_source, new->source); + + /* remember the old values. */ + item_old = *item; + /* Copy over old item to get new lifetime, timestamp, preferred */ + *item = *new; + + /* But restore highest priority source */ + item->source = MAX (item_old.source, new->source); + + /* for addresses that we read from the kernel, we keep the timestamps as defined + * by the previous source (item_old). The reason is, that the other source configured the lifetimes + * with "what should be" and the kernel values are "what turned out after configuring it". + * + * For other sources, the longer lifetime wins. */ + if ( (new->source == NM_PLATFORM_SOURCE_KERNEL && new->source != item_old.source) + || nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) { + item->timestamp = item_old.timestamp; + item->lifetime = item_old.lifetime; + item->preferred = item_old.preferred; + } + if (nm_platform_ip4_address_cmp (&item_old, item) == 0) + return; goto NOTIFY; } } diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 0a7cf26a3b..fd791a5f90 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -1021,7 +1021,7 @@ void nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); - NMPlatformSource old_source; + NMPlatformIP6Address item_old; int i; g_return_if_fail (new != NULL); @@ -1032,11 +1032,28 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { if (nm_platform_ip6_address_cmp (item, new) == 0) return; - old_source = item->source; + + /* remember the old values. */ + item_old = *item; /* Copy over old item to get new lifetime, timestamp, preferred */ *item = *new; + /* But restore highest priority source */ - item->source = MAX (old_source, new->source); + item->source = MAX (item_old.source, new->source); + + /* for addresses that we read from the kernel, we keep the timestamps as defined + * by the previous source (item_old). The reason is, that the other source configured the lifetimes + * with "what should be" and the kernel values are "what turned out after configuring it". + * + * For other sources, the longer lifetime wins. */ + if ( (new->source == NM_PLATFORM_SOURCE_KERNEL && new->source != item_old.source) + || nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) { + item->timestamp = item_old.timestamp; + item->lifetime = item_old.lifetime; + item->preferred = item_old.preferred; + } + if (nm_platform_ip6_address_cmp (&item_old, item) == 0) + return; goto NOTIFY; } } |