diff options
author | Thomas Haller <thaller@redhat.com> | 2014-04-14 17:57:56 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-05-01 22:06:52 +0200 |
commit | 516d66210fbcc9897f60dc9145a477e91ff8bad5 (patch) | |
tree | 8f0ae504278bc6ae7cbfa48b6a48b354fbe68602 | |
parent | a16faa3985042dadb34600cb0df2eefc61360340 (diff) | |
download | NetworkManager-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.in | 7 | ||||
-rw-r--r-- | src/devices/nm-device.c | 28 |
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); |