summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-04-07 13:48:34 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-05-02 18:21:18 +0200
commitb84768581ec456390466f8779e16935754200673 (patch)
tree031b6720f0e304d07d10285963a92f519099e5f2 /src
parentc0d322720a3956a40831c09f78a1dfbaf6fd9294 (diff)
downloadNetworkManager-b84768581ec456390466f8779e16935754200673.tar.gz
device: fail activation immediately only when may-fail=no
Introduce the nm_device_ip_method_failed() function to check if the failure of an IP method should cause the activation to fail, and use it where appropriate. http://bugzilla.gnome.org/show_bug.cgi?id=741347
Diffstat (limited to 'src')
-rw-r--r--src/devices/bluetooth/nm-device-bt.c19
-rw-r--r--src/devices/nm-device-private.h4
-rw-r--r--src/devices/nm-device.c127
-rw-r--r--src/devices/wwan/nm-device-modem.c33
4 files changed, 122 insertions, 61 deletions
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index eef4ed0a1b..8f3772c69b 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -362,6 +362,7 @@ static void
ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceBt *self = NM_DEVICE_BT (user_data);
switch (nm_device_get_state (device)) {
case NM_DEVICE_STATE_PREPARE:
@@ -375,7 +376,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
case NM_DEVICE_STATE_ACTIVATED:
if (nm_device_activate_ip4_state_in_conf (device))
nm_device_activate_schedule_ip4_config_timeout (device);
- else {
+ else if (nm_device_activate_ip6_state_in_conf (device))
+ nm_device_activate_schedule_ip6_config_timeout (device);
+ else if (nm_device_activate_ip4_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else if (nm_device_activate_ip6_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else {
+ _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device));
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
@@ -502,8 +514,9 @@ modem_ip4_config_result (NMModem *modem,
_LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT,
"retrieving IP4 configuration failed: %s",
error->message);
-
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
} else
nm_device_activate_schedule_ip4_config_result (device, config);
}
diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h
index 602c2c8575..1f81ed0eab 100644
--- a/src/devices/nm-device-private.h
+++ b/src/devices/nm-device-private.h
@@ -70,9 +70,11 @@ void nm_device_activate_schedule_ip6_config_timeout (NMDevice *device);
gboolean nm_device_activate_ip4_state_in_conf (NMDevice *device);
gboolean nm_device_activate_ip4_state_in_wait (NMDevice *device);
+gboolean nm_device_activate_ip4_state_done (NMDevice *device);
gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device);
gboolean nm_device_activate_ip6_state_in_wait (NMDevice *device);
+gboolean nm_device_activate_ip6_state_done (NMDevice *device);
void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout);
void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr);
@@ -103,6 +105,8 @@ void nm_device_queue_recheck_available (NMDevice *device,
void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config);
void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config);
+void nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason);
+
gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value);
#define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index a01e94841a..b3d922c260 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -3307,7 +3307,7 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us
switch (status) {
case NM_DNSMASQ_STATUS_DEAD:
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
break;
default:
break;
@@ -3771,6 +3771,26 @@ check_ip_failed (NMDevice *self, gboolean may_fail)
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
}
+void
+nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason reason)
+{
+ NMDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE (self));
+ g_return_if_fail (family == AF_INET || family == AF_INET6);
+ priv = NM_DEVICE_GET_PRIVATE (self);
+
+ if (family == AF_INET)
+ priv->ip4_state = IP_FAIL;
+ else
+ priv->ip6_state = IP_FAIL;
+
+ if (get_ip_config_may_fail (self, family))
+ check_ip_failed (self, FALSE);
+ else
+ nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
+}
+
/*
* check_ip_done
*
@@ -4050,23 +4070,20 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
r = sd_ipv4ll_get_address (ll, &address);
if (r < 0) {
_LOGE (LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r);
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED);
return;
}
if ((address.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
_LOGE (LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr);
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
return;
}
config = ipv4ll_get_ip4_config (self, address.s_addr);
if (config == NULL) {
_LOGE (LOGD_AUTOIP4, "failed to get IPv4LL config");
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
return;
}
@@ -4076,8 +4093,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
} else if (priv->ip4_state == IP_DONE) {
if (!ip4_config_merge_and_apply (self, config, TRUE, NULL)) {
_LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change.");
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
}
} else
g_assert_not_reached ();
@@ -4086,8 +4102,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data)
break;
default:
_LOGW (LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event);
- priv->ip4_state = IP_FAIL;
- check_ip_failed (self, FALSE);
+ nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
}
}
@@ -4496,26 +4511,28 @@ END_ADD_DEFAULT_ROUTE:
return success;
}
-static void
+static gboolean
dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
{
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
- g_return_if_fail (config != NULL);
+ g_return_val_if_fail (config != NULL, FALSE);
if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) {
_LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change.");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
- } else {
- /* Notify dispatcher scripts of new DHCP4 config */
- nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
- nm_device_get_settings_connection (self),
- nm_device_get_applied_connection (self),
- self,
- NULL,
- NULL,
- NULL);
+ return FALSE;
}
+
+ /* Notify dispatcher scripts of new DHCP4 config */
+ nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
+ nm_device_get_settings_connection (self),
+ nm_device_get_applied_connection (self),
+ self,
+ NULL,
+ NULL,
+ NULL);
+
+ return TRUE;
}
static gboolean
@@ -4607,9 +4624,7 @@ dhcp4_state_changed (NMDhcpClient *client,
case NM_DHCP_STATE_BOUND:
if (!ip4_config) {
_LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event.");
- nm_device_state_changed (self,
- NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ dhcp4_fail (self, FALSE);
break;
}
@@ -4631,8 +4646,10 @@ dhcp4_state_changed (NMDhcpClient *client,
ipv4_dad_start (self, configs, dhcp4_dad_cb);
} else if (priv->ip4_state == IP_DONE) {
- dhcp4_lease_change (self, ip4_config);
- nm_device_update_metered (self);
+ if (dhcp4_lease_change (self, ip4_config))
+ nm_device_update_metered (self);
+ else
+ dhcp4_fail (self, FALSE);
}
break;
case NM_DHCP_STATE_TIMEOUT:
@@ -5227,7 +5244,7 @@ END_ADD_DEFAULT_ROUTE:
return success;
}
-static void
+static gboolean
dhcp6_lease_change (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@@ -5236,8 +5253,7 @@ dhcp6_lease_change (NMDevice *self)
if (priv->dhcp6_ip6_config == NULL) {
_LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
- return;
+ return FALSE;
}
g_assert (priv->dhcp6_client); /* sanity check */
@@ -5246,16 +5262,18 @@ dhcp6_lease_change (NMDevice *self)
g_assert (settings_connection);
/* Apply the updated config */
- if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) {
- _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event.");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
- } else {
- /* Notify dispatcher scripts of new DHCPv6 config */
- nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
- settings_connection,
- nm_device_get_applied_connection (self),
- self, NULL, NULL, NULL);
+ if (!ip6_config_merge_and_apply (self, TRUE, &reason)) {
+ _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event");
+ return FALSE;
}
+
+ /* Notify dispatcher scripts of new DHCPv6 config */
+ nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
+ settings_connection,
+ nm_device_get_applied_connection (self),
+ self, NULL, NULL, NULL);
+
+ return TRUE;
}
static gboolean
@@ -5377,13 +5395,13 @@ dhcp6_state_changed (NMDhcpClient *client,
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);
+ nm_device_ip_method_failed (self, AF_INET6, 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);
+ if (!dhcp6_lease_change (self))
+ dhcp6_fail (self, FALSE);
break;
case NM_DHCP_STATE_TIMEOUT:
dhcp6_timeout (self, client);
@@ -6560,7 +6578,6 @@ act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
return NM_ACT_STAGE_RETURN_SUCCESS;
}
-
/*
* nm_device_activate_stage4_ip4_config_timeout
*
@@ -6588,7 +6605,6 @@ activate_stage4_ip4_config_timeout (NMDevice *self)
check_ip_failed (self, FALSE);
}
-
/*
* nm_device_activate_schedule_ip4_config_timeout
*
@@ -6608,7 +6624,6 @@ nm_device_activate_schedule_ip4_config_timeout (NMDevice *self)
activation_source_schedule (self, activate_stage4_ip4_config_timeout, AF_INET);
}
-
static NMActStageReturn
act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
{
@@ -6620,7 +6635,6 @@ act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason)
return NM_ACT_STAGE_RETURN_SUCCESS;
}
-
/*
* activate_stage4_ip6_config_timeout
*
@@ -6648,7 +6662,6 @@ activate_stage4_ip6_config_timeout (NMDevice *self)
check_ip_failed (self, FALSE);
}
-
/*
* nm_device_activate_schedule_ip6_config_timeout
*
@@ -6855,7 +6868,7 @@ activate_stage5_ip4_config_commit (NMDevice *self)
/* NULL to use the existing priv->dev_ip4_config */
if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) {
_LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
+ nm_device_ip_method_failed (self, AF_INET, reason);
return;
}
@@ -6949,6 +6962,13 @@ nm_device_activate_ip4_state_in_wait (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT;
}
+gboolean
+nm_device_activate_ip4_state_done (NMDevice *self)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ return NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_DONE;
+}
+
static void
activate_stage5_ip6_config_commit (NMDevice *self)
{
@@ -6999,7 +7019,7 @@ activate_stage5_ip6_config_commit (NMDevice *self)
check_ip_done (self);
} else {
_LOGW (LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed");
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
+ nm_device_ip_method_failed (self, AF_INET6, reason);
}
}
@@ -7033,6 +7053,13 @@ nm_device_activate_ip6_state_in_wait (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT;
}
+gboolean
+nm_device_activate_ip6_state_done (NMDevice *self)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ return NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_DONE;
+}
+
static void
clear_act_request (NMDevice *self)
{
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index a8361c4976..0f96dafbfc 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -60,6 +60,7 @@ static void
ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
switch (nm_device_get_state (device)) {
case NM_DEVICE_STATE_PREPARE:
@@ -73,7 +74,18 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
case NM_DEVICE_STATE_ACTIVATED:
if (nm_device_activate_ip4_state_in_conf (device))
nm_device_activate_schedule_ip4_config_timeout (device);
- else {
+ else if (nm_device_activate_ip6_state_in_conf (device))
+ nm_device_activate_schedule_ip6_config_timeout (device);
+ else if (nm_device_activate_ip4_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else if (nm_device_activate_ip6_state_done (device)) {
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ } else {
+ _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device));
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
@@ -159,8 +171,9 @@ modem_ip4_config_result (NMModem *modem,
if (error) {
_LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s",
error->message);
-
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ nm_device_ip_method_failed (device,
+ AF_INET,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
} else {
nm_device_set_wwan_ip4_config (device, config);
nm_device_activate_schedule_ip4_config_result (device, NULL);
@@ -184,9 +197,11 @@ modem_ip6_config_result (NMModem *modem,
g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE);
if (error) {
- _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message);
-
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s",
+ error->message);
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
return;
}
@@ -201,7 +216,9 @@ modem_ip6_config_result (NMModem *modem,
nm_device_activate_schedule_ip6_config_result (device);
else {
_LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses");
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ nm_device_ip_method_failed (device,
+ AF_INET6,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
}
return;
}
@@ -211,7 +228,7 @@ modem_ip6_config_result (NMModem *modem,
g_assert (ignored == NULL);
switch (ret) {
case NM_ACT_STAGE_RETURN_FAILURE:
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
+ nm_device_ip_method_failed (device, AF_INET6, reason);
break;
case NM_ACT_STAGE_RETURN_STOP:
/* all done */