Blame SOURCES/0026-dhcp-fix-lease-renewal-rh1503587.patch

013a0d
From 2d98ce90188fdf4d21c2b597ba848d249a2d4e09 Mon Sep 17 00:00:00 2001
013a0d
From: Francesco Giudici <fgiudici@redhat.com>
013a0d
Date: Mon, 15 Jan 2018 12:49:33 +0100
013a0d
Subject: [PATCH 1/3] device: always consider both ip families when deciding to
013a0d
 fail
013a0d
013a0d
Example: when dhcpv4 lease renewal fails, if ipv4.may-fail was "yes",
013a0d
check also if we have a successful ipv6 conf: if not fail.
013a0d
Previously we just ignored the other ip family status.
013a0d
013a0d
(cherry picked from commit da0fee4d9f16d0de6323ea709e459b79b5158dad)
013a0d
---
013a0d
 src/devices/nm-device.c | 53 ++++++++++++++++++++++++++++---------------------
013a0d
 1 file changed, 30 insertions(+), 23 deletions(-)
013a0d
013a0d
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
013a0d
index f8651e2e1..345034185 100644
013a0d
--- a/src/devices/nm-device.c
013a0d
+++ b/src/devices/nm-device.c
013a0d
@@ -3774,21 +3774,24 @@ get_ip_config_may_fail (NMDevice *self, int addr_family)
013a0d
 /*
013a0d
  * check_ip_state
013a0d
  *
013a0d
- * Transition the device from IP_CONFIG to the next state according to the
013a0d
- * outcome of IPv4 and IPv6 configuration. @may_fail indicates that we are
013a0d
- * called just after the initial configuration and thus IPv4/IPv6 are allowed to
013a0d
- * fail if the ipvx.may-fail properties say so, because the IP methods couldn't
013a0d
- * even be started.
013a0d
+ * When @full_state_update is TRUE, transition the device from IP_CONFIG to the
013a0d
+ * next state according to the outcome of IPv4 and IPv6 configuration. @may_fail
013a0d
+ * indicates that we are called just after the initial configuration and thus
013a0d
+ * IPv4/IPv6 are allowed to fail if the ipvx.may-fail properties say so, because
013a0d
+ * the IP methods couldn't even be started.
013a0d
+ * If @full_state_update is FALSE, just check if the connection should be failed
013a0d
+ * due to the state of both ip families and the ipvx.may-fail settings.
013a0d
  */
013a0d
 static void
013a0d
-check_ip_state (NMDevice *self, gboolean may_fail)
013a0d
+check_ip_state (NMDevice *self, gboolean may_fail, gboolean full_state_update)
013a0d
 {
013a0d
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
013a0d
 	gboolean ip4_disabled = FALSE, ip6_ignore = FALSE;
013a0d
 	NMSettingIPConfig *s_ip4, *s_ip6;
013a0d
 	NMDeviceState state;
013a0d
 
013a0d
-	if (nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG)
013a0d
+	if (   full_state_update
013a0d
+	    && nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG)
013a0d
 		return;
013a0d
 
013a0d
 	/* Don't progress into IP_CHECK or SECONDARIES if we're waiting for the
013a0d
@@ -3835,9 +3838,12 @@ check_ip_state (NMDevice *self, gboolean may_fail)
013a0d
 			state = NM_DEVICE_STATE_FAILED;
013a0d
 		}
013a0d
 
013a0d
-		nm_device_state_changed (self,
013a0d
-		                         state,
013a0d
-		                         NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
013a0d
+		if (   full_state_update
013a0d
+		    || state == NM_DEVICE_STATE_FAILED) {
013a0d
+			nm_device_state_changed (self,
013a0d
+			                         state,
013a0d
+			                         NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
013a0d
+		}
013a0d
 		return;
013a0d
 	}
013a0d
 
013a0d
@@ -3850,7 +3856,8 @@ check_ip_state (NMDevice *self, gboolean may_fail)
013a0d
 	/* If at least a method has completed, proceed with activation */
013a0d
 	if (   (priv->ip4_state == IP_DONE && !ip4_disabled)
013a0d
 	    || (priv->ip6_state == IP_DONE && !ip6_ignore)) {
013a0d
-		nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
013a0d
+		if (full_state_update)
013a0d
+			nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
013a0d
 		return;
013a0d
 	}
013a0d
 }
013a0d
@@ -3892,7 +3899,7 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
013a0d
 
013a0d
 	if (activating) {
013a0d
 		if (success)
013a0d
-			check_ip_state (self, FALSE);
013a0d
+			check_ip_state (self, FALSE, TRUE);
013a0d
 		else
013a0d
 			nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
013a0d
 	} else
013a0d
@@ -5268,7 +5275,7 @@ nm_device_ip_method_failed (NMDevice *self,
013a0d
 	_set_ip_state (self, addr_family, IP_FAIL);
013a0d
 
013a0d
 	if (get_ip_config_may_fail (self, addr_family))
013a0d
-		check_ip_state (self, FALSE);
013a0d
+		check_ip_state (self, FALSE, (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG));
013a0d
 	else
013a0d
 		nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
013a0d
 }
013a0d
@@ -7997,7 +8004,7 @@ nm_device_activate_stage3_ip4_start (NMDevice *self)
013a0d
 
013a0d
 	if (nm_device_sys_iface_state_is_external (self)) {
013a0d
 		_set_ip_state (self, AF_INET, IP_DONE);
013a0d
-		check_ip_state (self, FALSE);
013a0d
+		check_ip_state (self, FALSE, TRUE);
013a0d
 		return TRUE;
013a0d
 	}
013a0d
 
013a0d
@@ -8010,7 +8017,7 @@ nm_device_activate_stage3_ip4_start (NMDevice *self)
013a0d
 		g_object_unref (ip4_config);
013a0d
 	} else if (ret == NM_ACT_STAGE_RETURN_IP_DONE) {
013a0d
 		_set_ip_state (self, AF_INET, IP_DONE);
013a0d
-		check_ip_state (self, FALSE);
013a0d
+		check_ip_state (self, FALSE, TRUE);
013a0d
 	} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
013a0d
 		nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason);
013a0d
 		return FALSE;
013a0d
@@ -8044,7 +8051,7 @@ nm_device_activate_stage3_ip6_start (NMDevice *self)
013a0d
 
013a0d
 	if (nm_device_sys_iface_state_is_external (self)) {
013a0d
 		_set_ip_state (self, AF_INET6, IP_DONE);
013a0d
-		check_ip_state (self, FALSE);
013a0d
+		check_ip_state (self, FALSE, TRUE);
013a0d
 		return TRUE;
013a0d
 	}
013a0d
 
013a0d
@@ -8061,7 +8068,7 @@ nm_device_activate_stage3_ip6_start (NMDevice *self)
013a0d
 		nm_device_activate_schedule_ip6_config_result (self);
013a0d
 	} else if (ret == NM_ACT_STAGE_RETURN_IP_DONE) {
013a0d
 		_set_ip_state (self, AF_INET6, IP_DONE);
013a0d
-		check_ip_state (self, FALSE);
013a0d
+		check_ip_state (self, FALSE, TRUE);
013a0d
 	} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
013a0d
 		nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason);
013a0d
 		return FALSE;
013a0d
@@ -8111,7 +8118,7 @@ activate_stage3_ip_config_start (NMDevice *self)
013a0d
 	/* Proxy */
013a0d
 	nm_device_set_proxy_config (self, NULL);
013a0d
 
013a0d
-	check_ip_state (self, TRUE);
013a0d
+	check_ip_state (self, TRUE, TRUE);
013a0d
 }
013a0d
 
013a0d
 static void
013a0d
@@ -8250,7 +8257,7 @@ activate_stage4_ip4_config_timeout (NMDevice *self)
013a0d
 
013a0d
 	_set_ip_state (self, AF_INET, IP_FAIL);
013a0d
 
013a0d
-	check_ip_state (self, FALSE);
013a0d
+	check_ip_state (self, FALSE, TRUE);
013a0d
 }
013a0d
 
013a0d
 /*
013a0d
@@ -8306,7 +8313,7 @@ activate_stage4_ip6_config_timeout (NMDevice *self)
013a0d
 
013a0d
 	_set_ip_state (self, AF_INET6, IP_FAIL);
013a0d
 
013a0d
-	check_ip_state (self, FALSE);
013a0d
+	check_ip_state (self, FALSE, TRUE);
013a0d
 }
013a0d
 
013a0d
 /*
013a0d
@@ -8554,7 +8561,7 @@ activate_stage5_ip4_config_result (NMDevice *self)
013a0d
 
013a0d
 	/* Enter the IP_CHECK state if this is the first method to complete */
013a0d
 	_set_ip_state (self, AF_INET, IP_DONE);
013a0d
-	check_ip_state (self, FALSE);
013a0d
+	check_ip_state (self, FALSE, TRUE);
013a0d
 }
013a0d
 
013a0d
 void
013a0d
@@ -8709,7 +8716,7 @@ activate_stage5_ip6_config_commit (NMDevice *self)
013a0d
 				_LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD: awaiting termination");
013a0d
 			} else {
013a0d
 				_set_ip_state (self, AF_INET6, IP_DONE);
013a0d
-				check_ip_state (self, FALSE);
013a0d
+				check_ip_state (self, FALSE, TRUE);
013a0d
 			}
013a0d
 		}
013a0d
 	} else {
013a0d
@@ -11195,7 +11202,7 @@ queued_ip6_config_change (gpointer user_data)
013a0d
 			_LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated");
013a0d
 			g_clear_object (&priv->dad6_ip6_config);
013a0d
 			_set_ip_state (self, AF_INET6, IP_DONE);
013a0d
-			check_ip_state (self, FALSE);
013a0d
+			check_ip_state (self, FALSE, TRUE);
013a0d
 			if (priv->rt6_temporary_not_available)
013a0d
 				nm_device_activate_schedule_ip6_config_result (self);
013a0d
 		}
013a0d
-- 
013a0d
2.14.3
013a0d
013a0d
013a0d
From 56353bfb82e6d744b64f117f346b25b18526bf2d Mon Sep 17 00:00:00 2001
013a0d
From: Francesco Giudici <fgiudici@redhat.com>
013a0d
Date: Mon, 15 Jan 2018 12:17:54 +0100
013a0d
Subject: [PATCH 2/3] device: never stop trying renewing the lease
013a0d
013a0d
Always reschedule a lease renewal attempt: just clear the scheduled
013a0d
renewal if the connection is really deactivated.
013a0d
013a0d
(cherry picked from commit 1a20ff86d585b826d1769d0aa0adeca3aa1a183a)
013a0d
---
013a0d
 src/devices/nm-device.c | 36 ++++++++++++++++++++++++++++++++----
013a0d
 1 file changed, 32 insertions(+), 4 deletions(-)
013a0d
013a0d
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
013a0d
index 345034185..f6d3f4c04 100644
013a0d
--- a/src/devices/nm-device.c
013a0d
+++ b/src/devices/nm-device.c
013a0d
@@ -5900,15 +5900,23 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
013a0d
 	    && (timeout || (priv->ip4_state == IP_CONF))
013a0d
 	    && !priv->dhcp4.was_active)
013a0d
 		nm_device_activate_schedule_ip4_config_timeout (self);
013a0d
-	else if (priv->ip4_state == IP_DONE || priv->dhcp4.was_active) {
013a0d
+	else if (   priv->dhcp4.num_tries_left < DHCP_NUM_TRIES_MAX
013a0d
+	         || priv->ip4_state == IP_DONE
013a0d
+	         || priv->dhcp4.was_active) {
013a0d
 		/* Don't fail immediately when the lease expires but try to
013a0d
 		 * restart DHCP for a predefined number of times.
013a0d
 		 */
013a0d
 		if (priv->dhcp4.num_tries_left) {
013a0d
 			priv->dhcp4.num_tries_left--;
013a0d
 			dhcp_schedule_restart (self, AF_INET, "lease expired");
013a0d
-		} else
013a0d
+		} else {
013a0d
 			nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
013a0d
+			/* We failed the ipv4 method but schedule again the retries if the ipv6 method is
013a0d
+			 * configured, keeping the connection up.
013a0d
+			 */
013a0d
+			if (nm_device_get_state (self) != NM_DEVICE_STATE_FAILED)
013a0d
+				dhcp_schedule_restart (self, AF_INET, "renewal failed");
013a0d
+		}
013a0d
 	} else
013a0d
 		g_warn_if_reached ();
013a0d
 }
013a0d
@@ -5950,6 +5958,12 @@ dhcp4_state_changed (NMDhcpClient *client,
013a0d
 			break;
013a0d
 		}
013a0d
 
013a0d
+		/* After some failures, we have been able to renew the lease:
013a0d
+		 * update the ip state
013a0d
+		 */
013a0d
+		if (priv->ip4_state == IP_FAIL)
013a0d
+			_set_ip_state (self, AF_INET, IP_CONF);
013a0d
+
013a0d
 		g_free (priv->dhcp4.pac_url);
013a0d
 		priv->dhcp4.pac_url = g_strdup (g_hash_table_lookup (options, "wpad"));
013a0d
 		nm_device_set_proxy_config (self, priv->dhcp4.pac_url);
013a0d
@@ -6640,15 +6654,23 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
013a0d
 		    && (timeout || (priv->ip6_state == IP_CONF))
013a0d
 		    && !priv->dhcp6.was_active)
013a0d
 			nm_device_activate_schedule_ip6_config_timeout (self);
013a0d
-		else if (priv->ip6_state == IP_DONE || priv->dhcp6.was_active) {
013a0d
+		else if (   priv->dhcp6.num_tries_left < DHCP_NUM_TRIES_MAX
013a0d
+		         || priv->ip6_state == IP_DONE
013a0d
+		         || priv->dhcp6.was_active) {
013a0d
 			/* Don't fail immediately when the lease expires but try to
013a0d
 			 * restart DHCP for a predefined number of times.
013a0d
 			 */
013a0d
 			if (priv->dhcp6.num_tries_left) {
013a0d
 				priv->dhcp6.num_tries_left--;
013a0d
 				dhcp_schedule_restart (self, AF_INET6, "lease expired");
013a0d
-			} else
013a0d
+			} else {
013a0d
 				nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
013a0d
+				/* We failed the ipv6 method but schedule again the retries if the ipv4 method is
013a0d
+				 * configured, keeping the connection up.
013a0d
+				 */
013a0d
+				if (nm_device_get_state (self) != NM_DEVICE_STATE_FAILED)
013a0d
+					dhcp_schedule_restart (self, AF_INET6, "renewal failed");
013a0d
+			}
013a0d
 		} else
013a0d
 			g_warn_if_reached ();
013a0d
 	} else {
013a0d
@@ -6715,6 +6737,12 @@ dhcp6_state_changed (NMDhcpClient *client,
013a0d
 			}
013a0d
 		}
013a0d
 
013a0d
+		/* After long time we have been able to renew the lease:
013a0d
+		 * update the ip state
013a0d
+		 */
013a0d
+		if (priv->ip6_state == IP_FAIL)
013a0d
+			_set_ip_state (self, AF_INET6, IP_CONF);
013a0d
+
013a0d
 		priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX;
013a0d
 
013a0d
 		if (priv->ip6_state == IP_CONF) {
013a0d
-- 
013a0d
2.14.3
013a0d
013a0d
013a0d
From b6d2ad3312eea21effbd8d6d5fe32056ccf89cb8 Mon Sep 17 00:00:00 2001
013a0d
From: Francesco Giudici <fgiudici@redhat.com>
013a0d
Date: Thu, 8 Feb 2018 18:28:10 +0100
013a0d
Subject: [PATCH 3/3] device: enable DHCPv6 retries on lease renewal failure
013a0d
013a0d
https://bugzilla.gnome.org/show_bug.cgi?id=792745
013a0d
(cherry picked from commit 1289450146e2b212cabca500cb8009f910651661)
013a0d
---
013a0d
 src/devices/nm-device.c | 4 +++-
013a0d
 1 file changed, 3 insertions(+), 1 deletion(-)
013a0d
013a0d
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
013a0d
index f6d3f4c04..eb91dc257 100644
013a0d
--- a/src/devices/nm-device.c
013a0d
+++ b/src/devices/nm-device.c
013a0d
@@ -6633,13 +6633,15 @@ static void
013a0d
 dhcp6_fail (NMDevice *self, gboolean timeout)
013a0d
 {
013a0d
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
013a0d
+	gboolean is_dhcp_managed;
013a0d
 
013a0d
 	_LOGD (LOGD_DHCP6, "DHCPv6 failed: timeout %d, num tries left %u",
013a0d
            timeout, priv->dhcp6.num_tries_left);
013a0d
 
013a0d
+	is_dhcp_managed = (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED);
013a0d
 	dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE);
013a0d
 
013a0d
-	if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) {
013a0d
+	if (is_dhcp_managed || priv->dhcp6.num_tries_left < DHCP_NUM_TRIES_MAX) {
013a0d
 		/* Don't fail if there are static addresses configured on
013a0d
 		 * the device, instead retry after some time.
013a0d
 		 */
013a0d
-- 
013a0d
2.14.3
013a0d