core: merge branch 'th/autoconnect-rh1401515' (part 1)

Some cleanup of handling autoconnect behavior.

The introduction of NMSetting8021x:auth-retries property,
changes behavior in that password retries are no longer
controlled by NMSettingConnection:autoconnect-retries property.

https://bugzilla.redhat.com/show_bug.cgi?id=1401515
This commit is contained in:
Thomas Haller 2017-10-31 19:38:43 +01:00
commit b84f63265f
20 changed files with 298 additions and 204 deletions

View file

@ -4691,6 +4691,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_AUTH_TIMEOUT, PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_AUTH_TIMEOUT,
.property_type = &_pt_gobject_int, .property_type = &_pt_gobject_int,
), ),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_AUTH_RETRIES,
.property_type = &_pt_gobject_int,
),
NULL NULL
}; };

View file

@ -43,6 +43,7 @@
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WPS_METHOD N_("Flags indicating which mode of WPS is to be used if any. There's little point in changing the default setting as NetworkManager will automatically determine whether it's feasible to start WPS enrollment from the Access Point capabilities. WPS can be disabled by setting this property to a value of 1.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_WPS_METHOD N_("Flags indicating which mode of WPS is to be used if any. There's little point in changing the default setting as NetworkManager will automatically determine whether it's feasible to start WPS enrollment from the Access Point capabilities. WPS can be disabled by setting this property to a value of 1.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_ALTSUBJECT_MATCHES N_("List of strings to be matched against the altSubjectName of the certificate presented by the authentication server. If the list is empty, no verification of the server certificate's altSubjectName is performed.") #define DESCRIBE_DOC_NM_SETTING_802_1X_ALTSUBJECT_MATCHES N_("List of strings to be matched against the altSubjectName of the certificate presented by the authentication server. If the list is empty, no verification of the server certificate's altSubjectName is performed.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_ANONYMOUS_IDENTITY N_("Anonymous identity string for EAP authentication methods. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP-TTLS.") #define DESCRIBE_DOC_NM_SETTING_802_1X_ANONYMOUS_IDENTITY N_("Anonymous identity string for EAP authentication methods. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP-TTLS.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_AUTH_RETRIES N_("The number of retries for the authentication. Zero means to try indefinitely; -1 means to use a global default. If the global default is not set, the authentication retries for 3 times before failing the connection.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_AUTH_TIMEOUT N_("A timeout for the authentication. Zero means the global default; if the global default is not set, the authentication timeout is 25 seconds.") #define DESCRIBE_DOC_NM_SETTING_802_1X_AUTH_TIMEOUT N_("A timeout for the authentication. Zero means the global default; if the global default is not set, the authentication timeout is 25 seconds.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT N_("Contains the CA certificate if used by the EAP method specified in the \"eap\" property. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.") #define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT N_("Contains the CA certificate if used by the EAP method specified in the \"eap\" property. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT_PASSWORD N_("The password used to access the CA certificate stored in \"ca-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.") #define DESCRIBE_DOC_NM_SETTING_802_1X_CA_CERT_PASSWORD N_("The password used to access the CA certificate stored in \"ca-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.")
@ -136,7 +137,7 @@
#define DESCRIBE_DOC_NM_SETTING_CDMA_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.") #define DESCRIBE_DOC_NM_SETTING_CDMA_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT N_("Whether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT N_("Whether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY N_("The autoconnect priority. If the connection is set to autoconnect, connections with higher priority will be preferred. Defaults to 0. The higher number means higher priority.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY N_("The autoconnect priority. If the connection is set to autoconnect, connections with higher priority will be preferred. Defaults to 0. The higher number means higher priority.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES N_("The number of times a connection should be tried when autoactivating before giving up. Zero means forever, -1 means the global default (4 times if not overridden). Setting this to 1 means to try activation once and never retry.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES N_("The number of times a connection should be tried when autoactivating before giving up. Zero means forever, -1 means the global default (4 times if not overridden). Setting this to 1 means to try activation only once before blocking autoconnect. Note that after a timeout, NetworkManager will try to autoconnect again.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES N_("Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES N_("Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT N_("If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT N_("If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_ID N_("A human readable unique identifier for the connection, like \"Work Wi-Fi\" or \"T-Mobile 3G\".") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_ID N_("A human readable unique identifier for the connection, like \"Work Wi-Fi\" or \"T-Mobile 3G\".")

View file

@ -116,6 +116,7 @@ typedef struct {
NMSettingSecretFlags phase2_private_key_password_flags; NMSettingSecretFlags phase2_private_key_password_flags;
gboolean system_ca_certs; gboolean system_ca_certs;
gint auth_timeout; gint auth_timeout;
gint auth_retries;
} NMSetting8021xPrivate; } NMSetting8021xPrivate;
enum { enum {
@ -164,6 +165,7 @@ enum {
PROP_PIN_FLAGS, PROP_PIN_FLAGS,
PROP_SYSTEM_CA_CERTS, PROP_SYSTEM_CA_CERTS,
PROP_AUTH_TIMEOUT, PROP_AUTH_TIMEOUT,
PROP_AUTH_RETRIES,
LAST_PROP LAST_PROP
}; };
@ -2745,6 +2747,25 @@ nm_setting_802_1x_get_auth_timeout (NMSetting8021x *setting)
return NM_SETTING_802_1X_GET_PRIVATE (setting)->auth_timeout; return NM_SETTING_802_1X_GET_PRIVATE (setting)->auth_timeout;
} }
/**
* nm_setting_802_1x_get_auth_retries:
* @setting: the #NMSetting8021x
*
* Returns the value contained in the #NMSetting8021x:auth-retries property.
*
* Returns: the configured authentication retries in seconds. Zero means
* infinity and -1 means a global default value.
*
* Since: 1.10
**/
gint
nm_setting_802_1x_get_auth_retries (NMSetting8021x *setting)
{
g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), -1);
return NM_SETTING_802_1X_GET_PRIVATE (setting)->auth_retries;
}
static void static void
need_secrets_password (NMSetting8021x *self, need_secrets_password (NMSetting8021x *self,
GPtrArray *secrets, GPtrArray *secrets,
@ -3623,6 +3644,9 @@ set_property (GObject *object, guint prop_id,
case PROP_AUTH_TIMEOUT: case PROP_AUTH_TIMEOUT:
priv->auth_timeout = g_value_get_int (value); priv->auth_timeout = g_value_get_int (value);
break; break;
case PROP_AUTH_RETRIES:
priv->auth_retries = g_value_get_int (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -3769,6 +3793,9 @@ get_property (GObject *object, guint prop_id,
case PROP_AUTH_TIMEOUT: case PROP_AUTH_TIMEOUT:
g_value_set_int (value, priv->auth_timeout); g_value_set_int (value, priv->auth_timeout);
break; break;
case PROP_AUTH_RETRIES:
g_value_set_int (value, priv->auth_retries);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -4825,4 +4852,29 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
/**
* NMSetting8021x:auth-retries:
*
* The number of retries for the authentication. Zero means to try indefinitely; -1 means
* to use a global default. If the global default is not set, the authentication
* retries for 3 times before failing the connection.
*
* Since: 1.10
**/
/* ---ifcfg-rh---
* property: auth-retries
* variable: IEEE_8021X_AUTH_RETRIES(+)
* default: 0
* description: Number of retries for the 802.1X authentication.
* ---end---
*/
g_object_class_install_property
(object_class, PROP_AUTH_RETRIES,
g_param_spec_int (NM_SETTING_802_1X_AUTH_RETRIES, "", "",
-1, G_MAXINT32, -1,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_STATIC_STRINGS));
} }

View file

@ -151,6 +151,7 @@ typedef enum { /*< underscore_name=nm_setting_802_1x_auth_flags >*/
#define NM_SETTING_802_1X_PIN_FLAGS "pin-flags" #define NM_SETTING_802_1X_PIN_FLAGS "pin-flags"
#define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs"
#define NM_SETTING_802_1X_AUTH_TIMEOUT "auth-timeout" #define NM_SETTING_802_1X_AUTH_TIMEOUT "auth-timeout"
#define NM_SETTING_802_1X_AUTH_RETRIES "auth-retries"
/* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties /* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties
* using the "blob" scheme, the data must be passed in PKCS#12 binary format. * using the "blob" scheme, the data must be passed in PKCS#12 binary format.
@ -361,6 +362,8 @@ NM_AVAILABLE_IN_1_8
NMSetting8021xAuthFlags nm_setting_802_1x_get_phase1_auth_flags (NMSetting8021x *setting); NMSetting8021xAuthFlags nm_setting_802_1x_get_phase1_auth_flags (NMSetting8021x *setting);
NM_AVAILABLE_IN_1_8 NM_AVAILABLE_IN_1_8
gint nm_setting_802_1x_get_auth_timeout (NMSetting8021x *setting); gint nm_setting_802_1x_get_auth_timeout (NMSetting8021x *setting);
NM_AVAILABLE_IN_1_10
gint nm_setting_802_1x_get_auth_retries (NMSetting8021x *setting);
G_END_DECLS G_END_DECLS

View file

@ -1665,7 +1665,9 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
* *
* The number of times a connection should be tried when autoactivating before * The number of times a connection should be tried when autoactivating before
* giving up. Zero means forever, -1 means the global default (4 times if not * giving up. Zero means forever, -1 means the global default (4 times if not
* overridden). Setting this to 1 means to try activation once and never retry. * overridden). Setting this to 1 means to try activation only once before
* blocking autoconnect. Note that after a timeout, NetworkManager will try
* to autoconnect again.
*/ */
/* ---ifcfg-rh--- /* ---ifcfg-rh---
* property: autoconnect-retries * property: autoconnect-retries

View file

@ -742,6 +742,11 @@ ipv6.ip6-privacy=0
<listitem><para>If left unspecified, the default value <listitem><para>If left unspecified, the default value
"<literal>optional</literal>" will be used.</para></listitem> "<literal>optional</literal>" will be used.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>802-1x.auth-retries</varname></term>
<listitem><para>If left unspecified, the default value is 3 tries before failing the connection.
</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
</refsect2> </refsect2>

View file

@ -115,6 +115,8 @@ typedef struct _NMDeviceEthernetPrivate {
DcbWait dcb_wait; DcbWait dcb_wait;
guint dcb_timeout_id; guint dcb_timeout_id;
int auth_retries;
bool dcb_handle_carrier_changes:1; bool dcb_handle_carrier_changes:1;
} NMDeviceEthernetPrivate; } NMDeviceEthernetPrivate;
@ -254,36 +256,24 @@ _update_s390_subchannels (NMDeviceEthernet *self)
_notify (self, PROP_S390_SUBCHANNELS); _notify (self, PROP_S390_SUBCHANNELS);
} }
static void
reset_8021x_autoconnect_retries (NMDevice *device)
{
NMActRequest *req;
NMSettingsConnection *connection;
req = nm_device_get_act_request (device);
if ( req
&& nm_device_get_applied_setting (device, NM_TYPE_SETTING_802_1X)) {
connection = nm_act_request_get_settings_connection (req);
g_return_if_fail (connection);
/* Reset autoconnect retries on success, failure, or when deactivating */
nm_settings_connection_reset_autoconnect_retries (connection);
}
}
static void static void
device_state_changed (NMDevice *device, device_state_changed (NMDevice *device,
NMDeviceState new_state, NMDeviceState new_state,
NMDeviceState old_state, NMDeviceState old_state,
NMDeviceStateReason reason) NMDeviceStateReason reason)
{ {
NMDeviceEthernetPrivate *priv;
if (new_state > NM_DEVICE_STATE_ACTIVATED) if (new_state > NM_DEVICE_STATE_ACTIVATED)
wired_secrets_cancel (NM_DEVICE_ETHERNET (device)); wired_secrets_cancel (NM_DEVICE_ETHERNET (device));
if (NM_IN_SET (new_state, if (NM_IN_SET (new_state,
NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_ACTIVATED,
NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_DISCONNECTED)) NM_DEVICE_STATE_DISCONNECTED)) {
reset_8021x_autoconnect_retries (device); priv = NM_DEVICE_ETHERNET_GET_PRIVATE (NM_DEVICE_ETHERNET (device));
priv->auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_UNSET;
}
} }
static void static void
@ -294,6 +284,7 @@ nm_device_ethernet_init (NMDeviceEthernet *self)
priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate);
self->_priv = priv; self->_priv = priv;
priv->auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_UNSET;
priv->s390_options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); priv->s390_options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
} }
@ -680,24 +671,21 @@ handle_auth_or_fail (NMDeviceEthernet *self,
NMActRequest *req, NMActRequest *req,
gboolean new_secrets) gboolean new_secrets)
{ {
NMDeviceEthernetPrivate *priv;
const char *setting_name; const char *setting_name;
NMConnection *applied_connection; NMConnection *applied_connection;
NMSettingsConnection *settings_connection;
int tries_left;
applied_connection = nm_act_request_get_applied_connection (req); priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
settings_connection = nm_act_request_get_settings_connection (req);
tries_left = nm_settings_connection_get_autoconnect_retries (settings_connection); if (!nm_device_802_1x_auth_retries_try_next (NM_DEVICE (self),
if (tries_left == 0) &priv->auth_retries))
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
if (tries_left > 0)
nm_settings_connection_set_autoconnect_retries (settings_connection, tries_left - 1);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req)); nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req));
applied_connection = nm_act_request_get_applied_connection (req);
setting_name = nm_connection_need_secrets (applied_connection, NULL); setting_name = nm_connection_need_secrets (applied_connection, NULL);
if (setting_name) { if (setting_name) {
wired_secrets_get_secrets (self, setting_name, wired_secrets_get_secrets (self, setting_name,
@ -1356,7 +1344,7 @@ deactivate (NMDevice *device)
GError *error = NULL; GError *error = NULL;
/* Clear wired secrets tries when deactivating */ /* Clear wired secrets tries when deactivating */
reset_8021x_autoconnect_retries (device); priv->auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_UNSET;
nm_clear_g_source (&priv->pppoe_wait_id); nm_clear_g_source (&priv->pppoe_wait_id);

View file

@ -72,6 +72,7 @@ typedef struct {
Supplicant supplicant; Supplicant supplicant;
guint supplicant_timeout_id; guint supplicant_timeout_id;
NMActRequestGetSecretsCallId macsec_secrets_id; NMActRequestGetSecretsCallId macsec_secrets_id;
int auth_retries;
} NMDeviceMacsecPrivate; } NMDeviceMacsecPrivate;
struct _NMDeviceMacsec { struct _NMDeviceMacsec {
@ -477,24 +478,21 @@ handle_auth_or_fail (NMDeviceMacsec *self,
NMActRequest *req, NMActRequest *req,
gboolean new_secrets) gboolean new_secrets)
{ {
NMDeviceMacsecPrivate *priv;
const char *setting_name; const char *setting_name;
int tries_left;
NMConnection *applied_connection; NMConnection *applied_connection;
NMSettingsConnection *settings_connection;
applied_connection = nm_act_request_get_applied_connection (req); priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
settings_connection = nm_act_request_get_settings_connection (req);
tries_left = nm_settings_connection_get_autoconnect_retries (settings_connection); if (!nm_device_802_1x_auth_retries_try_next (NM_DEVICE (self),
if (tries_left == 0) &priv->auth_retries))
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
if (tries_left > 0)
nm_settings_connection_set_autoconnect_retries (settings_connection, tries_left - 1);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req)); nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req));
applied_connection = nm_act_request_get_applied_connection (req);
setting_name = nm_connection_need_secrets (applied_connection, NULL); setting_name = nm_connection_need_secrets (applied_connection, NULL);
if (setting_name) { if (setting_name) {
macsec_secrets_get_secrets (self, setting_name, macsec_secrets_get_secrets (self, setting_name,
@ -737,34 +735,23 @@ link_changed (NMDevice *device,
} }
static void
reset_autoconnect_retries (NMDevice *device)
{
NMActRequest *req;
NMSettingsConnection *connection;
req = nm_device_get_act_request (device);
if (req) {
connection = nm_act_request_get_settings_connection (req);
g_return_if_fail (connection);
/* Reset autoconnect retries on success, failure, or when deactivating */
nm_settings_connection_reset_autoconnect_retries (connection);
}
}
static void static void
device_state_changed (NMDevice *device, device_state_changed (NMDevice *device,
NMDeviceState new_state, NMDeviceState new_state,
NMDeviceState old_state, NMDeviceState old_state,
NMDeviceStateReason reason) NMDeviceStateReason reason)
{ {
NMDeviceMacsecPrivate *priv;
if (new_state > NM_DEVICE_STATE_ACTIVATED) if (new_state > NM_DEVICE_STATE_ACTIVATED)
macsec_secrets_cancel (NM_DEVICE_MACSEC (device)); macsec_secrets_cancel (NM_DEVICE_MACSEC (device));
if ( new_state == NM_DEVICE_STATE_ACTIVATED if (NM_IN_SET (new_state, NM_DEVICE_STATE_ACTIVATED,
|| new_state == NM_DEVICE_STATE_FAILED NM_DEVICE_STATE_FAILED,
|| new_state == NM_DEVICE_STATE_DISCONNECTED) NM_DEVICE_STATE_DISCONNECTED)) {
reset_autoconnect_retries (device); priv = NM_DEVICE_MACSEC_GET_PRIVATE (NM_DEVICE_MACSEC (device));
priv->auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_UNSET;
}
} }
/******************************************************************/ /******************************************************************/
@ -821,8 +808,11 @@ get_property (GObject *object, guint prop_id,
} }
static void static void
nm_device_macsec_init (NMDeviceMacsec * self) nm_device_macsec_init (NMDeviceMacsec *self)
{ {
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self);
priv->auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_UNSET;
} }
static void static void

View file

@ -14023,6 +14023,52 @@ nm_device_get_supplicant_timeout (NMDevice *self)
SUPPLICANT_DEFAULT_TIMEOUT); SUPPLICANT_DEFAULT_TIMEOUT);
} }
gboolean
nm_device_802_1x_auth_retries_try_next (NMDevice *self, int *p_auth_retries)
{
NMConnection *applied_connection;
NMSetting8021x *security;
int auth_retries = *p_auth_retries;
if (G_UNLIKELY (auth_retries == NM_DEVICE_802_1X_AUTH_RETRIES_UNSET)) {
auth_retries = -1;
applied_connection = nm_device_get_applied_connection (NM_DEVICE (self));
if (applied_connection) {
security = nm_connection_get_setting_802_1x (applied_connection);
if (security)
auth_retries = nm_setting_802_1x_get_auth_retries (security);
}
if (auth_retries == -1) {
gs_free char *value = NULL;
value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"802-1x.auth-retries",
self);
auth_retries = _nm_utils_ascii_str_to_int64 (value, 10, -1, G_MAXINT32, -1);
}
if (auth_retries == 0)
auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_INFINITY;
else if (auth_retries == -1)
auth_retries = NM_DEVICE_802_1X_AUTH_RETRIES_DEFAULT;
else
nm_assert (auth_retries > 0);
*p_auth_retries = auth_retries;
}
if (auth_retries == NM_DEVICE_802_1X_AUTH_RETRIES_INFINITY)
return TRUE;
if (auth_retries <= 0) {
nm_assert (auth_retries == 0);
return FALSE;
}
(*p_auth_retries)--;
return TRUE;
}
/*****************************************************************************/ /*****************************************************************************/
static const char * static const char *

View file

@ -735,6 +735,13 @@ void nm_device_update_initial_hw_address (NMDevice *self);
void nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze); void nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze);
void nm_device_update_dynamic_ip_setup (NMDevice *self); void nm_device_update_dynamic_ip_setup (NMDevice *self);
guint nm_device_get_supplicant_timeout (NMDevice *self); guint nm_device_get_supplicant_timeout (NMDevice *self);
#define NM_DEVICE_802_1X_AUTH_RETRIES_UNSET -1
#define NM_DEVICE_802_1X_AUTH_RETRIES_INFINITY -2
#define NM_DEVICE_802_1X_AUTH_RETRIES_DEFAULT 3
gboolean nm_device_802_1x_auth_retries_try_next (NMDevice *self, int *p_auth_retry);
gboolean nm_device_hw_addr_get_cloned (NMDevice *self, gboolean nm_device_hw_addr_get_cloned (NMDevice *self,
NMConnection *connection, NMConnection *connection,
gboolean is_wifi, gboolean is_wifi,

View file

@ -364,9 +364,8 @@ device_state_changed (NMDevice *device,
{ {
NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModem *self = NM_DEVICE_MODEM (device);
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
NMSettingsConnection *connection = nm_device_get_settings_connection (device);
g_assert (priv->modem); g_return_if_fail (priv->modem);
if (new_state == NM_DEVICE_STATE_UNAVAILABLE && if (new_state == NM_DEVICE_STATE_UNAVAILABLE &&
old_state < NM_DEVICE_STATE_UNAVAILABLE) { old_state < NM_DEVICE_STATE_UNAVAILABLE) {
@ -374,30 +373,7 @@ device_state_changed (NMDevice *device,
_LOGI (LOGD_MB, "modem state '%s'", _LOGI (LOGD_MB, "modem state '%s'",
nm_modem_state_to_string (nm_modem_get_state (priv->modem))); nm_modem_state_to_string (nm_modem_get_state (priv->modem)));
} }
nm_modem_device_state_changed (priv->modem, new_state, old_state); nm_modem_device_state_changed (priv->modem, new_state, old_state);
switch (nm_device_state_reason_check (reason)) {
case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED:
case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING:
case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED:
case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED:
case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED:
case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG:
case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT:
case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
case NM_DEVICE_STATE_REASON_GSM_APN_FAILED:
/* Block autoconnect of the just-failed connection for situations
* where a retry attempt would just fail again.
*/
if (connection) {
nm_settings_connection_set_autoconnect_blocked_reason (connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED);
}
break;
default:
break;
}
} }
static NMDeviceCapabilities static NMDeviceCapabilities

View file

@ -357,11 +357,15 @@ main (int argc, char *argv[])
/* Set up unix signal handling - before creating threads, but after daemonizing! */ /* Set up unix signal handling - before creating threads, but after daemonizing! */
nm_main_utils_setup_signals (main_loop); nm_main_utils_setup_signals (main_loop);
nm_logging_syslog_openlog (nm_config_data_get_value_cached (NM_CONFIG_GET_DATA_ORIG, {
NM_CONFIG_KEYFILE_GROUP_LOGGING, gs_free char *v = NULL;
NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY), v = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
nm_config_get_is_debug (config)); NM_CONFIG_KEYFILE_GROUP_LOGGING,
NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
nm_logging_syslog_openlog (v, nm_config_get_is_debug (config));
}
nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting... (%s)", nm_log_info (LOGD_CORE, "NetworkManager (version " NM_DIST_VERSION ") is starting... (%s)",
nm_config_get_first_start (config) ? "for the first time" : "after a restart"); nm_config_get_first_start (config) ? "for the first time" : "after a restart");

View file

@ -108,9 +108,6 @@ typedef struct {
char *rc_manager; char *rc_manager;
NMGlobalDnsConfig *global_dns; NMGlobalDnsConfig *global_dns;
/* mutable field */
char *value_cached;
} NMConfigDataPrivate; } NMConfigDataPrivate;
struct _NMConfigData { struct _NMConfigData {
@ -171,22 +168,6 @@ nm_config_data_get_value (const NMConfigData *self, const char *group, const cha
return nm_config_keyfile_get_value (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, flags); return nm_config_keyfile_get_value (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, flags);
} }
const char *nm_config_data_get_value_cached (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags)
{
const NMConfigDataPrivate *priv;
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), NULL);
g_return_val_if_fail (group && *group, NULL);
g_return_val_if_fail (key && *key, NULL);
priv = NM_CONFIG_DATA_GET_PRIVATE (self);
/* we modify @value_cached. In C++ jargon, the field is mutable. */
g_free (((NMConfigDataPrivate *) priv)->value_cached);
((NMConfigDataPrivate *) priv)->value_cached = nm_config_keyfile_get_value (priv->keyfile, group, key, flags);
return priv->value_cached;
}
gboolean gboolean
nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags) nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags)
{ {
@ -211,7 +192,7 @@ nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, c
g_return_val_if_fail (key && *key, default_value); g_return_val_if_fail (key && *key, default_value);
/* when parsing the boolean, base it on the raw value from g_key_file_get_value(). */ /* when parsing the boolean, base it on the raw value from g_key_file_get_value(). */
str = g_key_file_get_value (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, NULL); str = nm_config_keyfile_get_value (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, NM_CONFIG_GET_VALUE_RAW);
if (str) { if (str) {
value = nm_config_parse_boolean (str, default_value); value = nm_config_parse_boolean (str, default_value);
g_free (str); g_free (str);
@ -219,6 +200,28 @@ nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, c
return value; return value;
} }
gint64
nm_config_data_get_value_int64 (const NMConfigData *self, const char *group, const char *key, guint base, gint64 min, gint64 max, gint64 fallback)
{
int errsv;
gint64 val;
char *str;
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), fallback);
g_return_val_if_fail (group && *group, fallback);
g_return_val_if_fail (key && *key, fallback);
str = nm_config_keyfile_get_value (NM_CONFIG_DATA_GET_PRIVATE (self)->keyfile, group, key, NM_CONFIG_GET_VALUE_NONE);
val = _nm_utils_ascii_str_to_int64 (str, base, min, max, fallback);
if (str) {
/* preserve errno from the parsing. */
errsv = errno;
g_free (str);
errno = errsv;
}
return val;
}
char ** char **
nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default) nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default)
{ {
@ -1636,8 +1639,6 @@ finalize (GObject *gobject)
g_key_file_unref (priv->keyfile_intern); g_key_file_unref (priv->keyfile_intern);
G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject); G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject);
g_free (priv->value_cached);
} }
static void static void

View file

@ -156,8 +156,8 @@ const char *nm_config_data_get_config_description (const NMConfigData *config_da
gboolean nm_config_data_has_group (const NMConfigData *self, const char *group); gboolean nm_config_data_has_group (const NMConfigData *self, const char *group);
gboolean nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags); gboolean nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags);
char *nm_config_data_get_value (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags); char *nm_config_data_get_value (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags);
const char *nm_config_data_get_value_cached (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags);
gint nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, gint default_value); gint nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, gint default_value);
gint64 nm_config_data_get_value_int64 (const NMConfigData *self, const char *group, const char *key, guint base, gint64 min, gint64 max, gint64 fallback);
char **nm_config_data_get_plugins (const NMConfigData *config_data, gboolean allow_default); char **nm_config_data_get_plugins (const NMConfigData *config_data, gboolean allow_default);
gboolean nm_config_data_get_connectivity_enabled (const NMConfigData *config_data); gboolean nm_config_data_get_connectivity_enabled (const NMConfigData *config_data);

View file

@ -2548,13 +2548,13 @@ platform_query_devices (NMManager *self)
gs_unref_ptrarray GPtrArray *links = NULL; gs_unref_ptrarray GPtrArray *links = NULL;
int i; int i;
gboolean guess_assume; gboolean guess_assume;
const char *order; gs_free char *order = NULL;
guess_assume = nm_config_get_first_start (nm_config_get ()); guess_assume = nm_config_get_first_start (nm_config_get ());
order = nm_config_data_get_value_cached (NM_CONFIG_GET_DATA, order = nm_config_data_get_value (NM_CONFIG_GET_DATA,
NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_GROUP_MAIN,
NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER, NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER,
NM_CONFIG_GET_VALUE_STRIP); NM_CONFIG_GET_VALUE_STRIP);
links = nm_platform_link_get_all (priv->platform, !nm_streq0 (order, "index")); links = nm_platform_link_get_all (priv->platform, !nm_streq0 (order, "index"));
if (!links) if (!links)
return; return;
@ -3139,14 +3139,15 @@ autoconnect_slaves (NMManager *self,
if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) { if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
gs_free SlaveConnectionInfo *slaves = NULL; gs_free SlaveConnectionInfo *slaves = NULL;
guint i, n_slaves = 0; guint i, n_slaves = 0;
const char *value;
slaves = find_slaves (self, master_connection, master_device, &n_slaves); slaves = find_slaves (self, master_connection, master_device, &n_slaves);
if (n_slaves > 1) { if (n_slaves > 1) {
value = nm_config_data_get_value_cached (NM_CONFIG_GET_DATA, gs_free char *value = NULL;
NM_CONFIG_KEYFILE_GROUP_MAIN,
NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER, value = nm_config_data_get_value (NM_CONFIG_GET_DATA,
NM_CONFIG_GET_VALUE_STRIP); NM_CONFIG_KEYFILE_GROUP_MAIN,
NM_CONFIG_KEYFILE_KEY_MAIN_SLAVES_ORDER,
NM_CONFIG_GET_VALUE_STRIP);
g_qsort_with_data (slaves, n_slaves, sizeof (slaves[0]), g_qsort_with_data (slaves, n_slaves, sizeof (slaves[0]),
compare_slaves, compare_slaves,
GINT_TO_POINTER (!nm_streq0 (value, "index"))); GINT_TO_POINTER (!nm_streq0 (value, "index")));

View file

@ -1193,7 +1193,7 @@ pending_ac_state_changed (NMActiveConnection *ac, guint state, guint reason, NMP
* loop. * loop.
*/ */
con = nm_active_connection_get_settings_connection (ac); con = nm_active_connection_get_settings_connection (ac);
nm_settings_connection_set_autoconnect_blocked_reason (con, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED); nm_settings_connection_autoconnect_blocked_reason_set (con, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED);
schedule_activate_check (self, nm_active_connection_get_device (ac)); schedule_activate_check (self, nm_active_connection_get_device (ac));
/* Cleanup */ /* Cleanup */
@ -1235,9 +1235,23 @@ auto_activate_device (NMPolicy *self,
best_connection = NULL; best_connection = NULL;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]); NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]);
NMSettingConnection *s_con;
const char *permission;
if (!nm_settings_connection_can_autoconnect (candidate)) if ( !nm_settings_connection_is_visible (candidate)
|| nm_settings_connection_autoconnect_retries_get (candidate) == 0
|| nm_settings_connection_autoconnect_blocked_reason_get (candidate) != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
continue; continue;
s_con = nm_connection_get_setting_connection (NM_CONNECTION (candidate));
if (!nm_setting_connection_get_autoconnect (s_con))
continue;
permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (candidate));
if ( permission
&& !nm_settings_connection_check_permission (candidate, permission))
continue;
if (nm_device_can_auto_connect (device, (NMConnection *) candidate, &specific_object)) { if (nm_device_can_auto_connect (device, (NMConnection *) candidate, &specific_object)) {
best_connection = candidate; best_connection = candidate;
break; break;
@ -1266,7 +1280,7 @@ auto_activate_device (NMPolicy *self,
error->code, error->code,
error->message); error->message);
g_error_free (error); g_error_free (error);
nm_settings_connection_set_autoconnect_blocked_reason (best_connection, nm_settings_connection_autoconnect_blocked_reason_set (best_connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED); NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED);
schedule_activate_check (self, device); schedule_activate_check (self, device);
return; return;
@ -1424,8 +1438,8 @@ reset_autoconnect_all (NMPolicy *self, NMDevice *device)
NMSettingsConnection *connection = connections[i]; NMSettingsConnection *connection = connections[i];
if (!device || nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) { if (!device || nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) {
nm_settings_connection_reset_autoconnect_retries (connection); nm_settings_connection_autoconnect_retries_reset (connection);
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE); nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE);
} }
} }
} }
@ -1443,9 +1457,9 @@ reset_autoconnect_for_failed_secrets (NMPolicy *self)
for (i = 0; connections[i]; i++) { for (i = 0; connections[i]; i++) {
NMSettingsConnection *connection = connections[i]; NMSettingsConnection *connection = connections[i];
if (nm_settings_connection_get_autoconnect_blocked_reason (connection) == NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS) { if (nm_settings_connection_autoconnect_blocked_reason_get (connection) == NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS) {
nm_settings_connection_reset_autoconnect_retries (connection); nm_settings_connection_autoconnect_retries_reset (connection);
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE); nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE);
} }
} }
} }
@ -1472,7 +1486,7 @@ block_autoconnect_for_device (NMPolicy *self, NMDevice *device)
NMSettingsConnection *connection = connections[i]; NMSettingsConnection *connection = connections[i];
if (nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) { if (nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) {
nm_settings_connection_set_autoconnect_blocked_reason (connection, nm_settings_connection_autoconnect_blocked_reason_set (connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST); NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST);
} }
} }
@ -1556,12 +1570,12 @@ reset_connections_retries (gpointer user_data)
for (i = 0; connections[i]; i++) { for (i = 0; connections[i]; i++) {
NMSettingsConnection *connection = connections[i]; NMSettingsConnection *connection = connections[i];
con_stamp = nm_settings_connection_get_autoconnect_retry_time (connection); con_stamp = nm_settings_connection_autoconnect_blocked_until_get (connection);
if (con_stamp == 0) if (con_stamp == 0)
continue; continue;
if (con_stamp <= now) { if (con_stamp <= now) {
nm_settings_connection_reset_autoconnect_retries (connection); nm_settings_connection_autoconnect_retries_reset (connection);
changed = TRUE; changed = TRUE;
} else if (min_stamp == 0 || min_stamp > con_stamp) } else if (min_stamp == 0 || min_stamp > con_stamp)
min_stamp = con_stamp; min_stamp = con_stamp;
@ -1631,12 +1645,12 @@ activate_slave_connections (NMPolicy *self, NMDevice *device)
NMSettingsAutoconnectBlockedReason reason; NMSettingsAutoconnectBlockedReason reason;
if (!internal_activation) if (!internal_activation)
nm_settings_connection_reset_autoconnect_retries (settings); nm_settings_connection_autoconnect_retries_reset (settings);
reason = nm_settings_connection_get_autoconnect_blocked_reason (settings); reason = nm_settings_connection_autoconnect_blocked_reason_get (settings);
if (reason == NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED) { if (reason == NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED) {
reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE; reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE;
nm_settings_connection_set_autoconnect_blocked_reason (settings, reason); nm_settings_connection_autoconnect_blocked_reason_set (settings, reason);
} }
} }
} }
@ -1734,6 +1748,28 @@ device_state_changed (NMDevice *device,
NMIP6Config *ip6_config; NMIP6Config *ip6_config;
NMSettingConnection *s_con = NULL; NMSettingConnection *s_con = NULL;
switch (nm_device_state_reason_check (reason)) {
case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED:
case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING:
case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED:
case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED:
case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED:
case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG:
case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT:
case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
case NM_DEVICE_STATE_REASON_GSM_APN_FAILED:
/* Block autoconnect of the just-failed connection for situations
* where a retry attempt would just fail again.
*/
if (connection) {
nm_settings_connection_autoconnect_blocked_reason_set (connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED);
}
break;
default:
break;
}
switch (new_state) { switch (new_state) {
case NM_DEVICE_STATE_FAILED: case NM_DEVICE_STATE_FAILED:
/* Mark the connection invalid if it failed during activation so that /* Mark the connection invalid if it failed during activation so that
@ -1744,29 +1780,29 @@ device_state_changed (NMDevice *device,
&& old_state <= NM_DEVICE_STATE_ACTIVATED) { && old_state <= NM_DEVICE_STATE_ACTIVATED) {
int tries; int tries;
tries = nm_settings_connection_get_autoconnect_retries (connection); tries = nm_settings_connection_autoconnect_retries_get (connection);
if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) { if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) {
_LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets", _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets",
nm_settings_connection_get_id (connection)); nm_settings_connection_get_id (connection));
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS); nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS);
} else if (tries != 0) { } else if (tries != 0) {
if (tries > 0) { if (tries > 0) {
_LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left", _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left",
nm_settings_connection_get_id (connection), tries); nm_settings_connection_get_id (connection), tries);
nm_settings_connection_set_autoconnect_retries (connection, --tries); nm_settings_connection_autoconnect_retries_set (connection, --tries);
} else { } else {
_LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; infinite tries left", _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; infinite tries left",
nm_settings_connection_get_id (connection)); nm_settings_connection_get_id (connection));
} }
} }
if (nm_settings_connection_get_autoconnect_retries (connection) == 0) { if (nm_settings_connection_autoconnect_retries_get (connection) == 0) {
_LOGI (LOGD_DEVICE, "disabling autoconnect for connection '%s'.", _LOGI (LOGD_DEVICE, "disabling autoconnect for connection '%s'.",
nm_settings_connection_get_id (connection)); nm_settings_connection_get_id (connection));
/* Schedule a handler to reset retries count */ /* Schedule a handler to reset retries count */
if (!priv->reset_retries_id) { if (!priv->reset_retries_id) {
gint32 retry_time = nm_settings_connection_get_autoconnect_retry_time (connection); gint32 retry_time = nm_settings_connection_autoconnect_blocked_until_get (connection);
g_warn_if_fail (retry_time != 0); g_warn_if_fail (retry_time != 0);
priv->reset_retries_id = g_timeout_add_seconds (MAX (0, retry_time - nm_utils_get_monotonic_timestamp_s ()), reset_connections_retries, self); priv->reset_retries_id = g_timeout_add_seconds (MAX (0, retry_time - nm_utils_get_monotonic_timestamp_s ()), reset_connections_retries, self);
@ -1778,7 +1814,7 @@ device_state_changed (NMDevice *device,
case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_ACTIVATED:
if (connection) { if (connection) {
/* Reset auto retries back to default since connection was successful */ /* Reset auto retries back to default since connection was successful */
nm_settings_connection_reset_autoconnect_retries (connection); nm_settings_connection_autoconnect_retries_reset (connection);
/* And clear secrets so they will always be requested from the /* And clear secrets so they will always be requested from the
* settings service when the next connection is made. * settings service when the next connection is made.
@ -1817,7 +1853,7 @@ device_state_changed (NMDevice *device,
/* The connection was deactivated, so block just this connection */ /* The connection was deactivated, so block just this connection */
_LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s' by user request", _LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s' by user request",
nm_settings_connection_get_id (connection)); nm_settings_connection_get_id (connection));
nm_settings_connection_set_autoconnect_blocked_reason (connection, nm_settings_connection_autoconnect_blocked_reason_set (connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST); NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST);
} }
} }
@ -1856,7 +1892,7 @@ device_state_changed (NMDevice *device,
case NM_DEVICE_STATE_IP_CONFIG: case NM_DEVICE_STATE_IP_CONFIG:
/* We must have secrets if we got here. */ /* We must have secrets if we got here. */
if (connection) if (connection)
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE); nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE);
break; break;
case NM_DEVICE_STATE_SECONDARIES: case NM_DEVICE_STATE_SECONDARIES:
if (connection) if (connection)
@ -2309,7 +2345,7 @@ connection_updated (NMSettings *settings,
nm_device_reapply_settings_immediately (device); nm_device_reapply_settings_immediately (device);
/* Reset auto retries back to default since connection was updated */ /* Reset auto retries back to default since connection was updated */
nm_settings_connection_reset_autoconnect_retries (connection); nm_settings_connection_autoconnect_retries_reset (connection);
} }
schedule_activate_all (self); schedule_activate_all (self);

View file

@ -109,7 +109,7 @@ typedef struct _NMSettingsConnectionPrivate {
GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */ GHashTable *seen_bssids; /* Up-to-date BSSIDs that's been seen for the connection */
int autoconnect_retries; int autoconnect_retries;
gint32 autoconnect_retry_time; gint32 autoconnect_blocked_until;
char *filename; char *filename;
} NMSettingsConnectionPrivate; } NMSettingsConnectionPrivate;
@ -2531,8 +2531,10 @@ nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *self)
} }
} }
/*****************************************************************************/
/** /**
* nm_settings_connection_get_autoconnect_retries: * nm_settings_connection_autoconnect_retries_get:
* @self: the settings connection * @self: the settings connection
* *
* Returns the number of autoconnect retries left. If the value is * Returns the number of autoconnect retries left. If the value is
@ -2540,14 +2542,13 @@ nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *self)
* with the global default. * with the global default.
*/ */
int int
nm_settings_connection_get_autoconnect_retries (NMSettingsConnection *self) nm_settings_connection_autoconnect_retries_get (NMSettingsConnection *self)
{ {
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
if (G_UNLIKELY (priv->autoconnect_retries == AUTOCONNECT_RETRIES_UNSET)) { if (G_UNLIKELY (priv->autoconnect_retries == AUTOCONNECT_RETRIES_UNSET)) {
NMSettingConnection *s_con; NMSettingConnection *s_con;
int retries = -1; int retries = -1;
const char *value;
s_con = nm_connection_get_setting_connection ((NMConnection *) self); s_con = nm_connection_get_setting_connection ((NMConnection *) self);
if (s_con) if (s_con)
@ -2555,14 +2556,11 @@ nm_settings_connection_get_autoconnect_retries (NMSettingsConnection *self)
/* -1 means 'default' */ /* -1 means 'default' */
if (retries == -1) { if (retries == -1) {
value = nm_config_data_get_value_cached (NM_CONFIG_GET_DATA, retries = nm_config_data_get_value_int64 (NM_CONFIG_GET_DATA,
NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_GROUP_MAIN,
"autoconnect-retries-default", "autoconnect-retries-default",
NM_CONFIG_GET_VALUE_STRIP); 10, 0, G_MAXINT32,
AUTOCONNECT_RETRIES_DEFAULT);
retries = _nm_utils_ascii_str_to_int64 (value,
10, 0, G_MAXINT32,
AUTOCONNECT_RETRIES_DEFAULT);
} }
/* 0 means 'forever', which is translated to a retry count of -1 */ /* 0 means 'forever', which is translated to a retry count of -1 */
@ -2577,43 +2575,46 @@ nm_settings_connection_get_autoconnect_retries (NMSettingsConnection *self)
} }
void void
nm_settings_connection_set_autoconnect_retries (NMSettingsConnection *self, nm_settings_connection_autoconnect_retries_set (NMSettingsConnection *self,
int retries) int retries)
{ {
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionPrivate *priv;
g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
nm_assert (retries == AUTOCONNECT_RETRIES_UNSET || retries >= 0); nm_assert (retries == AUTOCONNECT_RETRIES_UNSET || retries >= 0);
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
if (priv->autoconnect_retries != retries) { if (priv->autoconnect_retries != retries) {
_LOGT ("autoconnect-retries: set %d", retries); _LOGT ("autoconnect-retries: set %d", retries);
priv->autoconnect_retries = retries; priv->autoconnect_retries = retries;
} }
if (retries) if (retries)
priv->autoconnect_retry_time = 0; priv->autoconnect_blocked_until = 0;
else else
priv->autoconnect_retry_time = nm_utils_get_monotonic_timestamp_s () + AUTOCONNECT_RESET_RETRIES_TIMER; priv->autoconnect_blocked_until = nm_utils_get_monotonic_timestamp_s () + AUTOCONNECT_RESET_RETRIES_TIMER;
} }
void void
nm_settings_connection_reset_autoconnect_retries (NMSettingsConnection *self) nm_settings_connection_autoconnect_retries_reset (NMSettingsConnection *self)
{ {
nm_settings_connection_set_autoconnect_retries (self, AUTOCONNECT_RETRIES_UNSET); nm_settings_connection_autoconnect_retries_set (self, AUTOCONNECT_RETRIES_UNSET);
} }
gint32 gint32
nm_settings_connection_get_autoconnect_retry_time (NMSettingsConnection *self) nm_settings_connection_autoconnect_blocked_until_get (NMSettingsConnection *self)
{ {
return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_retry_time; return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_until;
} }
NMSettingsAutoconnectBlockedReason NMSettingsAutoconnectBlockedReason
nm_settings_connection_get_autoconnect_blocked_reason (NMSettingsConnection *self) nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self)
{ {
return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason; return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason;
} }
void void
nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection *self, nm_settings_connection_autoconnect_blocked_reason_set (NMSettingsConnection *self,
NMSettingsAutoconnectBlockedReason reason) NMSettingsAutoconnectBlockedReason reason)
{ {
g_return_if_fail (NM_IN_SET (reason, g_return_if_fail (NM_IN_SET (reason,
@ -2624,30 +2625,7 @@ nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection *sel
NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason = reason; NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->autoconnect_blocked_reason = reason;
} }
gboolean /*****************************************************************************/
nm_settings_connection_can_autoconnect (NMSettingsConnection *self)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMSettingConnection *s_con;
const char *permission;
if ( !priv->visible
|| nm_settings_connection_get_autoconnect_retries (self) == 0
|| priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
return FALSE;
s_con = nm_connection_get_setting_connection (NM_CONNECTION (self));
if (!nm_setting_connection_get_autoconnect (s_con))
return FALSE;
permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (self));
if (permission) {
if (nm_settings_connection_check_permission (self, permission) == FALSE)
return FALSE;
}
return TRUE;
}
/** /**
* nm_settings_connection_get_nm_generated: * nm_settings_connection_get_nm_generated:

View file

@ -213,19 +213,17 @@ void nm_settings_connection_add_seen_bssid (NMSettingsConnection *self,
void nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *self); void nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *self);
int nm_settings_connection_get_autoconnect_retries (NMSettingsConnection *self); int nm_settings_connection_autoconnect_retries_get (NMSettingsConnection *self);
void nm_settings_connection_set_autoconnect_retries (NMSettingsConnection *self, void nm_settings_connection_autoconnect_retries_set (NMSettingsConnection *self,
int retries); int retries);
void nm_settings_connection_reset_autoconnect_retries (NMSettingsConnection *self); void nm_settings_connection_autoconnect_retries_reset (NMSettingsConnection *self);
gint32 nm_settings_connection_get_autoconnect_retry_time (NMSettingsConnection *self); gint32 nm_settings_connection_autoconnect_blocked_until_get (NMSettingsConnection *self);
NMSettingsAutoconnectBlockedReason nm_settings_connection_get_autoconnect_blocked_reason (NMSettingsConnection *self); NMSettingsAutoconnectBlockedReason nm_settings_connection_autoconnect_blocked_reason_get (NMSettingsConnection *self);
void nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection *self, void nm_settings_connection_autoconnect_blocked_reason_set (NMSettingsConnection *self,
NMSettingsAutoconnectBlockedReason reason); NMSettingsAutoconnectBlockedReason reason);
gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *self);
gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *self); gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *self);
gboolean nm_settings_connection_get_volatile (NMSettingsConnection *self); gboolean nm_settings_connection_get_volatile (NMSettingsConnection *self);

View file

@ -3356,7 +3356,10 @@ next:
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, v, NULL); g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, v, NULL);
timeout = svGetValueInt64 (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", 10, 0, G_MAXINT32, 0); timeout = svGetValueInt64 (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", 10, 0, G_MAXINT32, 0);
g_object_set (s_8021x, NM_SETTING_802_1X_AUTH_TIMEOUT, (gint32) timeout, NULL); g_object_set (s_8021x, NM_SETTING_802_1X_AUTH_TIMEOUT, (gint) timeout, NULL);
timeout = svGetValueInt64 (ifcfg, "IEEE_8021X_AUTH_RETRIES", 10, -1, G_MAXINT32, -1);
g_object_set (s_8021x, NM_SETTING_802_1X_AUTH_RETRIES, (gint) timeout, NULL);
return g_steal_pointer (&s_8021x); return g_steal_pointer (&s_8021x);
} }

View file

@ -409,8 +409,8 @@ write_8021x_setting (NMConnection *connection,
GString *phase2_auth; GString *phase2_auth;
GString *str; GString *str;
guint32 i, num; guint32 i, num;
gint timeout;
gsize size; gsize size;
int vint;
s_8021x = nm_connection_get_setting_802_1x (connection); s_8021x = nm_connection_get_setting_802_1x (connection);
if (!s_8021x) { if (!s_8021x) {
@ -562,11 +562,11 @@ write_8021x_setting (NMConnection *connection,
svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH", svSetValueStr (ifcfg, "IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH",
nm_setting_802_1x_get_phase2_domain_suffix_match (s_8021x)); nm_setting_802_1x_get_phase2_domain_suffix_match (s_8021x));
timeout = nm_setting_802_1x_get_auth_timeout (s_8021x); vint = nm_setting_802_1x_get_auth_timeout (s_8021x);
if (timeout > 0) svSetValueInt64_cond (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", vint > 0, vint);
svSetValueInt64 (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", timeout);
else vint = nm_setting_802_1x_get_auth_retries (s_8021x);
svUnsetValue (ifcfg, "IEEE_8021X_AUTH_TIMEOUT"); svSetValueInt64_cond (ifcfg, "IEEE_8021X_AUTH_RETRIES", vint > 0, vint);
if (!write_8021x_certs (s_8021x, secrets, blobs, FALSE, ifcfg, error)) if (!write_8021x_certs (s_8021x, secrets, blobs, FALSE, ifcfg, error))
return FALSE; return FALSE;