core: allow selective failure of IP configuration (rh #567978)
As long as at least one IP config method completes, and as long as methods that the user required to complete do complete, allow the connection to complete.
This commit is contained in:
@@ -275,10 +275,16 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
|
||||
case NM_DEVICE_STATE_PREPARE:
|
||||
case NM_DEVICE_STATE_CONFIG:
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
||||
break;
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
if (nm_device_ip_config_should_fail (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -72,10 +72,16 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
|
||||
case NM_DEVICE_STATE_PREPARE:
|
||||
case NM_DEVICE_STATE_CONFIG:
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
||||
break;
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
if (nm_device_ip_config_should_fail (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -40,4 +40,6 @@ void nm_device_handle_autoip4_event (NMDevice *self,
|
||||
const char *event,
|
||||
const char *address);
|
||||
|
||||
gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6);
|
||||
|
||||
#endif /* NM_DEVICE_PRIVATE_H */
|
||||
|
@@ -2676,7 +2676,11 @@ handle_auth_or_fail (NMDeviceWifi *self,
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
if (!req) {
|
||||
req = nm_device_get_act_request (NM_DEVICE (self));
|
||||
g_assert (req);
|
||||
}
|
||||
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
@@ -3187,21 +3191,19 @@ real_act_stage4_get_ip4_config (NMDevice *dev,
|
||||
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
NMIP4Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
handle_ip_config_timeout (NMDeviceWifi *self,
|
||||
NMConnection *connection,
|
||||
gboolean may_fail,
|
||||
gboolean *chain_up,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
|
||||
NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self);
|
||||
NMAccessPoint *ap;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMIP4Config *real_config = NULL;
|
||||
NMActRequest *req = nm_device_get_act_request (dev);
|
||||
NMConnection *connection;
|
||||
gboolean auth_enforced = FALSE, encrypted = FALSE;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
g_assert (ap);
|
||||
|
||||
/* If nothing checks the security authentication information (as in
|
||||
@@ -3209,9 +3211,8 @@ real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
* the encryption key is likely wrong. Ask the user for a new one.
|
||||
* Otherwise the failure likely happened after a successful authentication.
|
||||
*/
|
||||
connection = nm_act_request_get_connection (req);
|
||||
auth_enforced = ap_auth_enforced (connection, ap, &encrypted);
|
||||
if (encrypted && !auth_enforced) {
|
||||
if (encrypted && !auth_enforced && !may_fail) {
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
||||
@@ -3220,39 +3221,83 @@ real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless): could not get IP configuration for "
|
||||
"connection '%s'.",
|
||||
nm_device_get_iface (dev), nm_setting_connection_get_id (s_con));
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_setting_connection_get_id (s_con));
|
||||
|
||||
ret = handle_auth_or_fail (self, req, TRUE);
|
||||
ret = handle_auth_or_fail (self, NULL, TRUE);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless): asking for new secrets",
|
||||
nm_device_get_iface (dev));
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
} else {
|
||||
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
|
||||
}
|
||||
} else if (nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) {
|
||||
NMDeviceWifiClass *klass;
|
||||
NMDeviceClass * parent_class;
|
||||
|
||||
/* For Ad-Hoc networks, chain up to parent to get a Zeroconf IP */
|
||||
klass = NM_DEVICE_WIFI_GET_CLASS (self);
|
||||
parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass));
|
||||
ret = parent_class->act_stage4_ip4_config_timeout (dev, &real_config, reason);
|
||||
} else {
|
||||
/* Non-encrypted network or authentication is enforced by some
|
||||
* entity (AP, RADIUS server, etc), but IP configure failed. Alert
|
||||
* the user.
|
||||
* entity (AP, RADIUS server, etc), but IP configure failed. Let the
|
||||
* superclass handle it.
|
||||
*/
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
*chain_up = TRUE;
|
||||
}
|
||||
|
||||
*config = real_config;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
NMIP4Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
gboolean may_fail = FALSE, chain_up = FALSE;
|
||||
NMActStageReturn ret;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (s_ip4)
|
||||
may_fail = nm_setting_ip4_config_get_may_fail (s_ip4);
|
||||
|
||||
ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason);
|
||||
if (chain_up)
|
||||
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (dev, config, reason);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip6_config_timeout (NMDevice *dev,
|
||||
NMIP6Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean may_fail = FALSE, chain_up = FALSE;
|
||||
NMActStageReturn ret;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6)
|
||||
may_fail = nm_setting_ip6_config_get_may_fail (s_ip6);
|
||||
|
||||
ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason);
|
||||
if (chain_up)
|
||||
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (dev, config, reason);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
activation_success_handler (NMDevice *dev)
|
||||
{
|
||||
@@ -3725,6 +3770,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
||||
parent_class->act_stage2_config = real_act_stage2_config;
|
||||
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
|
||||
parent_class->act_stage4_ip4_config_timeout = real_act_stage4_ip4_config_timeout;
|
||||
parent_class->act_stage4_ip6_config_timeout = real_act_stage4_ip6_config_timeout;
|
||||
parent_class->deactivate = real_deactivate;
|
||||
parent_class->deactivate_quickly = real_deactivate_quickly;
|
||||
parent_class->can_interrupt_activation = real_can_interrupt_activation;
|
||||
|
@@ -177,6 +177,11 @@ static NMActStageReturn dhcp6_start (NMDevice *self,
|
||||
guint32 dhcp_opt,
|
||||
NMDeviceStateReason *reason);
|
||||
|
||||
static void addrconf6_cleanup (NMDevice *self);
|
||||
static void dhcp6_cleanup (NMDevice *self, gboolean stop);
|
||||
static void dhcp4_cleanup (NMDevice *self, gboolean stop);
|
||||
|
||||
|
||||
static void
|
||||
device_interface_init (NMDeviceInterface *device_interface_class)
|
||||
{
|
||||
@@ -574,6 +579,35 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family)
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
|
||||
g_return_val_if_fail (self != NULL, TRUE);
|
||||
|
||||
req = nm_device_get_act_request (self);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
/* Fail the connection if the failed IP method is required to complete */
|
||||
if (ip6) {
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6 && !nm_setting_ip6_config_get_may_fail (s_ip6))
|
||||
return TRUE;
|
||||
} else {
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (s_ip4 && !nm_setting_ip4_config_get_may_fail (s_ip4))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
||||
int ifindex,
|
||||
@@ -1318,9 +1352,12 @@ dhcp_state_changed (NMDHCPClient *client,
|
||||
nm_dhcp4_config_reset (priv->dhcp4_config);
|
||||
|
||||
/* dhclient quit and can't get/renew a lease; so kill the connection */
|
||||
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
||||
else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
|
||||
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
|
||||
if (ipv6)
|
||||
nm_device_activate_schedule_stage4_ip6_config_timeout (device);
|
||||
else
|
||||
nm_device_activate_schedule_stage4_ip4_config_timeout (device);
|
||||
} else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
||||
break;
|
||||
case DHC_STOP:
|
||||
@@ -1797,8 +1834,7 @@ nm_device_activate_stage4_ip4_config_get (gpointer user_data)
|
||||
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, &ip4_config, &reason);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
goto out;
|
||||
else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE))
|
||||
{
|
||||
else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
@@ -1852,9 +1888,12 @@ real_act_stage4_ip4_config_timeout (NMDevice *self,
|
||||
/* Notify of invalid DHCP4 config object */
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG);
|
||||
|
||||
/* DHCP failed; connection must fail */
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
if (nm_device_ip_config_should_fail (self, FALSE)) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1882,17 +1921,18 @@ nm_device_activate_stage4_ip4_config_timeout (gpointer user_data)
|
||||
iface);
|
||||
|
||||
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &ip4_config, &reason);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
goto out;
|
||||
} else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) {
|
||||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
||||
g_assert (ip4_config);
|
||||
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP4_CONFIG, ip4_config);
|
||||
if (ip4_config) {
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP4_CONFIG, ip4_config);
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET);
|
||||
|
||||
@@ -2125,11 +2165,15 @@ real_act_stage4_ip6_config_timeout (NMDevice *self,
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
/* Notify of invalid DHCP6 config object */
|
||||
/* Notify of invalid DHCP4 config object */
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG);
|
||||
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
if (nm_device_ip_config_should_fail (self, TRUE)) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -2157,17 +2201,18 @@ nm_device_activate_stage4_ip6_config_timeout (gpointer user_data)
|
||||
iface);
|
||||
|
||||
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &ip6_config, &reason);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
goto out;
|
||||
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
||||
g_assert (ip6_config);
|
||||
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP6_CONFIG, ip6_config);
|
||||
if (ip6_config) {
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP6_CONFIG, ip6_config);
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET6);
|
||||
|
||||
|
Reference in New Issue
Block a user