summaryrefslogtreecommitdiff
path: root/src/devices/nm-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/nm-device.c')
-rw-r--r--src/devices/nm-device.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 265cf938e2..7edd2a7310 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -270,7 +270,8 @@ typedef struct {
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
NMRDisc * rdisc;
- gulong rdisc_config_changed_sigid;
+ gulong rdisc_changed_id;
+ gulong rdisc_timeout_id;
NMSettingIP6ConfigPrivacy rdisc_use_tempaddr;
/* IP6 config from autoconf */
NMIP6Config * ac_ip6_config;
@@ -3591,6 +3592,21 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
nm_device_activate_schedule_ip6_config_result (self);
}
+static void
+rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+ /* We don't want to stop listening for router advertisements completely,
+ * but instead let device activation continue activating. If an RA
+ * shows up later, we'll use it as long as the device is not disconnected.
+ */
+
+ _LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement");
+ if (priv->ip6_state == IP_CONF)
+ nm_device_activate_schedule_ip6_config_timeout (self);
+}
+
static gboolean
addrconf6_start_with_link_ready (NMDevice *self)
{
@@ -3610,8 +3626,14 @@ addrconf6_start_with_link_ready (NMDevice *self)
nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0");
nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0");
- priv->rdisc_config_changed_sigid = g_signal_connect (priv->rdisc, NM_RDISC_CONFIG_CHANGED,
- G_CALLBACK (rdisc_config_changed), self);
+ priv->rdisc_changed_id = g_signal_connect (priv->rdisc,
+ NM_RDISC_CONFIG_CHANGED,
+ G_CALLBACK (rdisc_config_changed),
+ self);
+ priv->rdisc_timeout_id = g_signal_connect (priv->rdisc,
+ NM_RDISC_RA_TIMEOUT,
+ G_CALLBACK (rdisc_ra_timeout),
+ self);
nm_rdisc_start (priv->rdisc);
return TRUE;
}
@@ -3662,10 +3684,14 @@ addrconf6_cleanup (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- if (priv->rdisc_config_changed_sigid) {
- g_signal_handler_disconnect (priv->rdisc,
- priv->rdisc_config_changed_sigid);
- priv->rdisc_config_changed_sigid = 0;
+ if (priv->rdisc_changed_id) {
+ g_signal_handler_disconnect (priv->rdisc, priv->rdisc_changed_id);
+ priv->rdisc_changed_id = 0;
+ }
+
+ if (priv->rdisc_timeout_id) {
+ g_signal_handler_disconnect (priv->rdisc, priv->rdisc_timeout_id);
+ priv->rdisc_timeout_id = 0;
}
nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
@@ -4647,6 +4673,12 @@ nm_device_activate_schedule_ip6_config_result (NMDevice *self)
g_return_if_fail (NM_IS_DEVICE (self));
+ /* If IP had previously failed, move it back to IP_CONF since we
+ * clearly now have configuration.
+ */
+ if (priv->ip6_state == IP_FAIL)
+ priv->ip6_state = IP_CONF;
+
activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6);
_LOG (level, LOGD_DEVICE | LOGD_IP6,