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
This commit is contained in:
Beniamino Galvani 2016-04-07 13:48:34 +02:00
parent c0d322720a
commit b84768581e
4 changed files with 122 additions and 61 deletions

View file

@ -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);
}

View file

@ -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, ...) \

View file

@ -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)
{

View file

@ -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 */