summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-04-07 15:09:54 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-04-28 10:46:30 +0200
commit8e10bfc67d6753b88d82b507088fb51b76c5a4c4 (patch)
tree7df9db71dabe6f0fbc71adfae4c747e8e72b9dee
parent9ddc64dd536b9b782f5f4c700072d16bf83eacae (diff)
downloadNetworkManager-8e10bfc67d6753b88d82b507088fb51b76c5a4c4.tar.gz
device: retry DHCPv6 when a lease expires
Make DHCPv6 more robust WRT temporary failures of servers by retrying DHCP for a predefined number of times at regular intervals when the lease expires. https://bugzilla.gnome.org/show_bug.cgi?id=741347
-rw-r--r--src/devices/nm-device.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 0f00a78232..e5d2006c1f 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -356,6 +356,7 @@ typedef struct _NMDevicePrivate {
/* Event ID of the current IP6 config from DHCP */
char * event_id;
guint restart_id;
+ guint num_tries_left;
} dhcp6;
/* allow autoconnect feature */
@@ -5307,8 +5308,10 @@ dhcp6_restart_cb (gpointer user_data)
priv = NM_DEVICE_GET_PRIVATE (self);
priv->dhcp6.restart_id = 0;
- if (!dhcp6_start (self, FALSE, &reason))
- priv->dhcp6.restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
+ if (!dhcp6_start (self, FALSE, &reason)) {
+ priv->dhcp6.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT,
+ dhcp6_restart_cb, self);
+ }
return FALSE;
}
@@ -5318,6 +5321,9 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ _LOGD (LOGD_DHCP6, "DHCPv6 failed: timeout %d, num tries left %u",
+ timeout, priv->dhcp6.num_tries_left);
+
dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
@@ -5328,7 +5334,8 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
&& priv->con_ip6_config
&& nm_ip6_config_get_num_addresses (priv->con_ip6_config)) {
_LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because device has IP addresses");
- priv->dhcp6.restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
+ priv->dhcp6.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT,
+ dhcp6_restart_cb, self);
return;
}
@@ -5338,15 +5345,27 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
*/
if (nm_device_uses_assumed_connection (self)) {
_LOGI (LOGD_DHCP6, "Scheduling DHCPv6 restart because the connection is assumed");
- priv->dhcp6.restart_id = g_timeout_add_seconds (120, dhcp6_restart_cb, self);
+ priv->dhcp6.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT,
+ dhcp6_restart_cb, self);
return;
}
- if (timeout || (priv->ip6_state == IP_CONF))
+ if ( priv->dhcp6.num_tries_left == DHCP_NUM_TRIES_MAX
+ && (timeout || (priv->ip6_state == IP_CONF)))
nm_device_activate_schedule_ip6_config_timeout (self);
- else if (priv->ip6_state == IP_DONE)
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
- else
+ else if (priv->ip6_state == IP_DONE) {
+ /* Don't fail immediately when the lease expires but try to
+ * restart DHCP for a predefined number of times.
+ */
+ if (priv->dhcp6.num_tries_left) {
+ _LOGI (LOGD_DHCP6, "restarting DHCPv6 in %d seconds (%u tries left)",
+ DHCP_RESTART_TIMEOUT, priv->dhcp6.num_tries_left);
+ priv->dhcp6.restart_id = g_timeout_add_seconds (DHCP_RESTART_TIMEOUT,
+ dhcp6_restart_cb, self);
+ priv->dhcp6.num_tries_left--;
+ } else
+ nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
+ } else
g_warn_if_reached ();
} else {
/* not a hard failure; just live with the RA info */
@@ -5412,6 +5431,8 @@ dhcp6_state_changed (NMDhcpClient *client,
}
}
+ priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX;
+
if (priv->ip6_state == IP_CONF) {
if (priv->dhcp6.ip6_config == NULL) {
nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_DHCP_FAILED);
@@ -6273,6 +6294,7 @@ act_stage3_ip6_config_start (NMDevice *self,
}
priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE;
+ priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX;
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);