diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-04-07 13:48:34 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-02 18:21:18 +0200 |
commit | b84768581ec456390466f8779e16935754200673 (patch) | |
tree | 031b6720f0e304d07d10285963a92f519099e5f2 /src | |
parent | c0d322720a3956a40831c09f78a1dfbaf6fd9294 (diff) | |
download | NetworkManager-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.c | 19 | ||||
-rw-r--r-- | src/devices/nm-device-private.h | 4 | ||||
-rw-r--r-- | src/devices/nm-device.c | 127 | ||||
-rw-r--r-- | src/devices/wwan/nm-device-modem.c | 33 |
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 */ |