summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-04-03 12:24:32 +0200
committerThomas Haller <thaller@redhat.com>2014-05-03 03:44:23 +0200
commit78b8af6651ddbaca4633b3a275df5c5c13f89695 (patch)
tree08e51c36e3585a2bc781ec96f22950ff3eea50db
parent9cd7b40a047bb4bbc2e9470158470c43badcc109 (diff)
downloadNetworkManager-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.c28
-rw-r--r--src/nm-ip6-config.c23
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;
}
}