summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-04-28 22:48:39 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-04-29 17:28:37 +0200
commit71270b829533e9162fc15ea937b206eff036fd08 (patch)
tree710c0c4cb3baa04c79900e35f8a05eaf708dbcc0 /src
parent389102ad7eea0371d6ea3f5b02c4160a3540317f (diff)
downloadNetworkManager-71270b829533e9162fc15ea937b206eff036fd08.tar.gz
device: postpone updates of IP configuration when a commit is pending
When a new dynamic configuration is received, it is stored in a member of private structure (e.g. @dhcp6_ip6_config) and a commit is scheduled. Before the commit is executed, an update_ipx_config() could be called and it would change the configuration before it is committed. This race condition causes failures in assigning the addresses received through DHCPv6 when the internal client is used (but potentially other clients and methods are affected). To fix it, postpone updates of IP configurations when a commit is already pending. (cherry picked from commit a47c13a7a2cd66644adf2459690f9c3bb96235ab)
Diffstat (limited to 'src')
-rw-r--r--src/devices/nm-device.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index dcdb027d69..692ffa7ba4 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -3382,6 +3382,15 @@ activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int famil
act_data->id = new_id;
}
+static gboolean
+activation_source_is_scheduled (NMDevice *self, ActivationHandleFunc func, int family)
+{
+ ActivationHandleData *act_data;
+
+ act_data = activation_source_get_by_family (self, family, NULL);
+ return act_data->func == func;
+}
+
/*****************************************************************************/
static gboolean
@@ -8779,6 +8788,18 @@ update_ip4_config (NMDevice *self, gboolean initial)
gboolean capture_resolv_conf;
NMDnsManagerResolvConfMode resolv_conf_mode;
+ /* If a commit is scheduled, this function would potentially interfere with
+ * it changing IP configurations before they are applied. Postpone the
+ * update in such case.
+ */
+ if (activation_source_is_scheduled (self,
+ activate_stage5_ip4_config_commit,
+ AF_INET)) {
+ priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
+ _LOGT (LOGD_DEVICE, "IP4 update was postponed");
+ return;
+ }
+
ifindex = nm_device_get_ip_ifindex (self);
if (!ifindex)
return;
@@ -8857,6 +8878,18 @@ update_ip6_config (NMDevice *self, gboolean initial)
gboolean capture_resolv_conf;
NMDnsManagerResolvConfMode resolv_conf_mode;
+ /* If a commit is scheduled, this function would potentially interfere with
+ * it changing IP configurations before they are applied. Postpone the
+ * update in such case.
+ */
+ if (activation_source_is_scheduled (self,
+ activate_stage5_ip6_config_commit,
+ AF_INET6)) {
+ priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
+ _LOGT (LOGD_DEVICE, "IP6 update was postponed");
+ return;
+ }
+
ifindex = nm_device_get_ip_ifindex (self);
if (!ifindex)
return;