summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-04-14 17:57:56 +0200
committerThomas Haller <thaller@redhat.com>2014-05-01 22:06:52 +0200
commit516d66210fbcc9897f60dc9145a477e91ff8bad5 (patch)
tree8f0ae504278bc6ae7cbfa48b6a48b354fbe68602
parenta16faa3985042dadb34600cb0df2eefc61360340 (diff)
downloadNetworkManager-516d66210fbcc9897f60dc9145a477e91ff8bad5.tar.gz
core: wait with "startup complete" for both IPv4 and IPv6 dynamic configuration
In case of DHCP4, DHCP6 and/or SLAAC, delay "startup complete" until both IPv4 and IPv6 are ready. This especially has an effect on nm-online/NetworkManager-wait-online.service, which blocks until configuration of both IPv4 and IPv6 is ready. We queue a pending_action when automatic configuration starts and remove it again, when we receive an address. Before, "startup complete" was reached when either one of the two IP protocols was configured. https://bugzilla.redhat.com/show_bug.cgi?id=1086906 Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--man/nm-online.1.in7
-rw-r--r--src/devices/nm-device.c28
2 files changed, 34 insertions, 1 deletions
diff --git a/man/nm-online.1.in b/man/nm-online.1.in
index ddb2b17f79..9546a2d4a0 100644
--- a/man/nm-online.1.in
+++ b/man/nm-online.1.in
@@ -35,7 +35,12 @@ is a utility to find out whether we are online. It is done by asking
NetworkManager about its status. When run, \fInm\-online\fP waits until
NetworkManager reports an active connection, or specified timeout expires. On
exit, the returned status code should be checked (see the return codes bellow).
-
+.P
+By default NetworkManager waits for IPv4 dynamic addressing to complete but does
+not wait for the "auto" IPv6 dynamic addressing. To wait for IPv6 addressing to
+complete, either (1) change the network connection's IPv6 "may-fail" setting to "no",
+and/or (2) change the IPv6 addressing method to "manual" or "dhcp", to indicate that
+IPv6 connectivity is expected.
.SH OPTIONS
.TP
.B \-t, \-\-timeout <timeout_value>
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 86ce054886..384460ecd7 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -156,6 +156,10 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMDevice, nm_device, G_TYPE_OBJECT,
#define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
+#define PENDING_ACTION_DHCP4 "dhcp4"
+#define PENDING_ACTION_DHCP6 "dhcp6"
+#define PENDING_ACTION_AUTOCONF6 "autoconf6"
+
typedef enum {
IP_NONE = 0,
IP_WAIT,
@@ -2815,6 +2819,8 @@ dhcp4_start (NMDevice *self,
G_CALLBACK (dhcp4_timeout),
self);
+ nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE);
+
/* DHCP devices will be notified by the DHCP manager when stuff happens */
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -3200,6 +3206,7 @@ dhcp6_start (NMDevice *self,
guint32 dhcp_opt,
NMDeviceStateReason *reason)
{
+ NMSettingIP6Config *s_ip6;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
GByteArray *tmp = NULL;
@@ -3248,6 +3255,11 @@ dhcp6_start (NMDevice *self,
G_CALLBACK (dhcp6_timeout),
self);
+ s_ip6 = nm_connection_get_setting_ip6_config (connection);
+ if (!nm_setting_ip6_config_get_may_fail (s_ip6) ||
+ !strcmp (nm_setting_ip6_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP))
+ nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE);
+
/* DHCP devices will be notified by the DHCP manager when stuff happens */
ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else {
@@ -3614,6 +3626,9 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
priv->rdisc_use_tempaddr = use_tempaddr;
print_support_extended_ifa_flags (use_tempaddr);
+ if (!nm_setting_ip6_config_get_may_fail (nm_connection_get_setting_ip6_config (connection)))
+ nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE);
+
/* ensure link local is ready... */
ret = linklocal6_start (self);
if (ret == NM_ACT_STAGE_RETURN_SUCCESS)
@@ -3657,6 +3672,8 @@ addrconf6_cleanup (NMDevice *self)
priv->rdisc_config_changed_sigid = 0;
}
+ nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
+
g_clear_object (&priv->ac_ip6_config);
g_clear_object (&priv->rdisc);
}
@@ -4489,6 +4506,9 @@ nm_device_activate_ip4_config_commit (gpointer user_data)
/* Enter the IP_CHECK state if this is the first method to complete */
priv->ip4_state = IP_DONE;
+
+ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
@@ -4564,6 +4584,10 @@ nm_device_activate_ip6_config_commit (gpointer user_data)
if (ip6_config_merge_and_apply (self, TRUE, &reason)) {
/* Enter the IP_CHECK state if this is the first method to complete */
priv->ip6_state = IP_DONE;
+
+ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
+ nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
+
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
} else {
@@ -4649,6 +4673,8 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release)
priv->dhcp4_timeout_sigid = 0;
}
+ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+
if (stop)
nm_dhcp_client_stop (priv->dhcp4_client, release);
@@ -4686,6 +4712,8 @@ dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release)
priv->dhcp6_timeout_sigid = 0;
}
+ nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
+
if (stop)
nm_dhcp_client_stop (priv->dhcp6_client, release);