File nm-fix-dhcp-client-timeout.patch of Package NetworkManager.openSUSE_Leap_42.3_Update
Index: NetworkManager-1.0.12/src/dhcp-manager/nm-dhcp-client.c
===================================================================
--- NetworkManager-1.0.12.orig/src/dhcp-manager/nm-dhcp-client.c
+++ NetworkManager-1.0.12/src/dhcp-manager/nm-dhcp-client.c
@@ -52,7 +52,6 @@ typedef struct {
NMDhcpState state;
pid_t pid;
- guint timeout_id;
guint watch_id;
gboolean info_only;
@@ -227,17 +226,6 @@ reason_to_state (const char *iface, cons
/********************************************/
static void
-timeout_cleanup (NMDhcpClient *self)
-{
- NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
-
- if (priv->timeout_id) {
- g_source_remove (priv->timeout_id);
- priv->timeout_id = 0;
- }
-}
-
-static void
watch_cleanup (NMDhcpClient *self)
{
NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
@@ -287,8 +275,6 @@ nm_dhcp_client_set_state (NMDhcpClient *
NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
gs_free char *event_id = NULL;
- if (new_state >= NM_DHCP_STATE_BOUND)
- timeout_cleanup (self);
if (new_state >= NM_DHCP_STATE_TIMEOUT)
watch_cleanup (self);
@@ -297,9 +283,6 @@ nm_dhcp_client_set_state (NMDhcpClient *
|| (!priv->ipv6 && NM_IS_IP4_CONFIG (ip_config)));
g_assert (options);
g_assert_cmpint (g_hash_table_size (options), >, 0);
- } else {
- g_assert (ip_config == NULL);
- g_assert (options == NULL);
}
/* The client may send same-state transitions for RENEW/REBIND events and
@@ -307,7 +290,7 @@ nm_dhcp_client_set_state (NMDhcpClient *
* BOUND state. Ignore same-state transitions for other events since
* the lease won't have changed and the state was already handled.
*/
- if ((priv->state == new_state) && (new_state != NM_DHCP_STATE_BOUND))
+ if ((priv->state == new_state) && (new_state != NM_DHCP_STATE_BOUND) && (new_state != NM_DHCP_STATE_TIMEOUT))
return;
if (priv->ipv6 && new_state == NM_DHCP_STATE_BOUND) {
@@ -336,21 +319,6 @@ nm_dhcp_client_set_state (NMDhcpClient *
event_id);
}
-static gboolean
-daemon_timeout (gpointer user_data)
-{
- NMDhcpClient *self = NM_DHCP_CLIENT (user_data);
- NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
-
- priv->timeout_id = 0;
- nm_log_warn (priv->ipv6 ? LOGD_DHCP6 : LOGD_DHCP4,
- "(%s): DHCPv%c request timed out.",
- priv->iface,
- priv->ipv6 ? '6' : '4');
- nm_dhcp_client_set_state (self, NM_DHCP_STATE_TIMEOUT, NULL, NULL);
- return G_SOURCE_REMOVE;
-}
-
static void
daemon_watch_cb (GPid pid, gint status, gpointer user_data)
{
@@ -396,11 +364,6 @@ nm_dhcp_client_watch_child (NMDhcpClient
g_return_if_fail (priv->pid == -1);
priv->pid = pid;
- /* Set up a timeout on the transaction to kill it after the timeout */
- g_assert (priv->timeout_id == 0);
- priv->timeout_id = g_timeout_add_seconds (priv->timeout,
- daemon_timeout,
- self);
g_assert (priv->watch_id == 0);
priv->watch_id = g_child_watch_add (pid, daemon_watch_cb, self);
}
@@ -772,7 +735,7 @@ nm_dhcp_client_handle_event (gpointer un
nm_log_dbg (LOGD_DHCP, "(%s): DHCP reason '%s' -> state '%s'",
iface, reason, state_to_string (new_state));
- if (new_state == NM_DHCP_STATE_BOUND) {
+ if (new_state == NM_DHCP_STATE_BOUND || new_state == NM_DHCP_STATE_TIMEOUT) {
/* Copy options */
str_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
g_hash_table_foreach (options, (GHFunc) copy_option, str_options);
@@ -856,7 +819,7 @@ set_property (GObject *object, guint pro
const GValue *value, GParamSpec *pspec)
{
NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (object);
-
+
switch (prop_id) {
case PROP_IFACE:
/* construct-only */
@@ -904,7 +867,6 @@ dispose (GObject *object)
*/
watch_cleanup (self);
- timeout_cleanup (self);
g_clear_pointer (&priv->iface, g_free);
g_clear_pointer (&priv->hostname, g_free);
Index: NetworkManager-1.0.12/src/devices/nm-device.c
===================================================================
--- NetworkManager-1.0.12.orig/src/devices/nm-device.c
+++ NetworkManager-1.0.12/src/devices/nm-device.c
@@ -3593,7 +3593,21 @@ dhcp4_state_changed (NMDhcpClient *clien
}
break;
case NM_DHCP_STATE_TIMEOUT:
- dhcp4_fail (self, TRUE);
+ /* If got valid ip config from recorded lease file */
+ if (!ip4_config) {
+ _LOGI (LOGD_DHCP4, "DHCP timed out and no valid lease file is available.");
+ dhcp4_fail (self, TRUE);
+ } else {
+ _LOGI (LOGD_DHCP4, "DHCP timed out, but valid lease file exists.");
+ dhcp4_update_config (self, priv->dhcp4_config, options);
+
+ if (priv->ip4_state == IP_CONF)
+ nm_device_activate_schedule_ip4_config_result (self, ip4_config);
+ else if (priv->ip4_state == IP_DONE) {
+ dhcp4_lease_change (self, ip4_config);
+ nm_device_update_metered (self);
+ }
+ }
break;
case NM_DHCP_STATE_EXPIRE:
/* Ignore expiry before we even have a lease (NAK, old lease, etc) */
@@ -4314,7 +4328,22 @@ dhcp6_state_changed (NMDhcpClient *clien
dhcp6_lease_change (self);
break;
case NM_DHCP_STATE_TIMEOUT:
- dhcp6_timeout (self, client);
+ if (ip6_config) {
+ priv->dhcp6_ip6_config = g_object_ref (ip6_config);
+ dhcp6_update_config (self, priv->dhcp6_config, options);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG);
+
+ if (priv->ip6_state == IP_CONF) {
+ if (priv->dhcp6_ip6_config == NULL) {
+ /* FIXME: Initial DHCP failed; should we fail IPv6 entirely then? */
+ nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
+ break;
+ }
+ nm_device_activate_schedule_ip6_config_result (self);
+ } else if (priv->ip6_state == IP_DONE)
+ dhcp6_lease_change (self);
+ } else
+ dhcp6_timeout (self, client);
break;
case NM_DHCP_STATE_EXPIRE:
/* Ignore expiry before we even have a lease (NAK, old lease, etc) */