summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFernando Fernandez Mancera <ffmancera@riseup.net>2023-02-15 10:35:08 +0100
committerFernando Fernandez Mancera <ffmancera@riseup.net>2023-02-23 09:12:37 +0100
commitb73b34c3ee308bea93c1725b573f2e24c400d70a (patch)
treee264dfd1b0446c255f32616c5cb270326ba1da57
parent10c38eabb92b1e9fafedaa61adeda242fa60a3e6 (diff)
policy: track autoconnect retries per Device x Connection
Autoconnect retries are not being tracked by connection anymore. Now it is tracked per Device x Connection. In addition, autoconnect might be blocked for the connection due to no secrets or user requested. All the properties tracking the retries and blocked time were move to DevConData and the functions to manipulate them aswell. In NMPolicy the logic didn't change very much. Instead of looking into the connection when the device failed activation it looks for DevConData.
-rw-r--r--src/core/devices/ovs/nm-ovs-factory.c4
-rw-r--r--src/core/devices/wifi/nm-device-iwd.c7
-rw-r--r--src/core/nm-manager.c305
-rw-r--r--src/core/nm-manager.h36
-rw-r--r--src/core/nm-policy.c130
-rw-r--r--src/core/settings/nm-settings-connection.c130
-rw-r--r--src/core/settings/nm-settings-connection.h26
7 files changed, 442 insertions, 196 deletions
diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c
index 50023778cd..6a42960e08 100644
--- a/src/core/devices/ovs/nm-ovs-factory.c
+++ b/src/core/devices/ovs/nm-ovs-factory.c
@@ -240,7 +240,9 @@ ovsdb_interface_failed(NMOvsdb *ovsdb,
return;
if (connection) {
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ nm_device_get_manager(device),
+ device,
connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
TRUE);
diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c
index e03227cd03..abfbd1a54b 100644
--- a/src/core/devices/wifi/nm-device-iwd.c
+++ b/src/core/devices/wifi/nm-device-iwd.c
@@ -2302,9 +2302,10 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
* to reset the retry count so we set no timeout.
*/
if (priv->iwd_autoconnect) {
- NMSettingsConnection *sett_conn = nm_act_request_get_settings_connection(req);
-
- nm_settings_connection_autoconnect_retries_set(sett_conn, 0);
+ nm_manager_devcon_autoconnect_retries_set(nm_device_get_manager(device),
+ device,
+ nm_act_request_get_settings_connection(req),
+ 0);
}
/* With priv->iwd_autoconnect, if we're assuming a connection because
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index 07a11150fa..51fd8aeee8 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -69,11 +69,24 @@ typedef struct {
bool os_owner : 1;
} RfkillRadioState;
+#define AUTOCONNECT_RESET_RETRIES_TIMER_SEC 300
+
typedef struct {
NMDevice *device;
NMSettingsConnection *sett_conn;
CList dev_lst;
CList con_lst;
+
+ /* Autoconnet retries needs to be tracked for each (device, connection)
+ * tuple because when a connection is a multiconnect one, each valid device
+ * must try to autoconnect the retries defined in the connection. */
+ struct {
+ guint32 retries;
+ gint32 blocked_until_sec;
+ NMSettingsAutoconnectBlockedReason blocked_reason;
+ bool initialized : 1;
+ } autoconnect;
+
} DevConData;
typedef enum {
@@ -1226,6 +1239,292 @@ active_connection_get_by_path(NMManager *self, const char *path)
/*****************************************************************************/
+static guint32
+_autoconnect_retries_initial(NMSettingsConnection *sett_conn)
+{
+ NMSettingConnection *s_con;
+ int retries = -1;
+
+ s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(sett_conn));
+ if (s_con)
+ retries = nm_setting_connection_get_autoconnect_retries(s_con);
+
+ if (retries == -1)
+ retries = nm_config_data_get_autoconnect_retries_default(NM_CONFIG_GET_DATA);
+
+ nm_assert(retries >= 0 && ((guint) retries) <= ((guint) G_MAXINT32));
+
+ if (retries == 0)
+ return NM_AUTOCONNECT_RETRIES_FOREVER;
+ return (guint32) retries;
+}
+
+static void
+_autoconnect_retries_set(NMManager *self, DevConData *data, guint32 retries, gboolean is_reset)
+{
+ nm_assert(data);
+
+ if (data->autoconnect.retries != retries || !data->autoconnect.initialized) {
+ _LOGT(LOGD_SETTINGS,
+ "autoconnect: device[%p] (%s): retries set %d%s",
+ data->device,
+ nm_device_get_ip_iface(data->device),
+ retries,
+ is_reset ? " (reset)" : "");
+ data->autoconnect.initialized = TRUE;
+ data->autoconnect.retries = retries;
+ }
+
+ if (retries != 0) {
+ _LOGT(LOGD_SETTINGS,
+ "autoconnect: device[%p] (%s): no longer block autoconnect (due to retry count) %s",
+ data->device,
+ nm_device_get_ip_iface(data->device),
+ is_reset ? " (reset)" : "");
+ data->autoconnect.blocked_until_sec = 0;
+ } else {
+ /* NOTE: the blocked time must be identical for all connections, otherwise
+ * the tracking of resetting the retry count in NMPolicy needs adjustment
+ * in _connection_autoconnect_retries_set() (as it would need to re-evaluate
+ * the next-timeout every time a connection gets blocked). */
+ data->autoconnect.blocked_until_sec =
+ nm_utils_get_monotonic_timestamp_sec() + AUTOCONNECT_RESET_RETRIES_TIMER_SEC;
+ _LOGT(LOGD_SETTINGS,
+ "autoconnect: device[%p] (%s): block autoconnect due to retry count for %d seconds",
+ data->device,
+ nm_device_get_ip_iface(data->device),
+ AUTOCONNECT_RESET_RETRIES_TIMER_SEC);
+ }
+}
+
+/**
+ * nm_manager_devcon_autoconnect_retries_get:
+ * @self: the #NMManager
+ * @device: the #NMDevice
+ * @sett_conn: the #NMSettingsConnection
+ *
+ * Returns the number of autoconnect retries left for the (device, connection)
+ * tuple. If the value is not yet set, initialize it with the value from the
+ * connection or with the global default.
+ */
+guint32
+nm_manager_devcon_autoconnect_retries_get(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn)
+{
+ DevConData *data;
+
+ nm_assert(NM_IS_MANAGER(self));
+ nm_assert(NM_IS_DEVICE(device));
+ nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
+ nm_assert(self == nm_device_get_manager(device));
+ nm_assert(self == nm_settings_connection_get_manager(sett_conn));
+
+ data = _devcon_lookup_data(self, device, sett_conn, TRUE);
+
+ if (G_UNLIKELY(!data->autoconnect.initialized)) {
+ _autoconnect_retries_set(self, data, _autoconnect_retries_initial(sett_conn), FALSE);
+ }
+
+ return data->autoconnect.retries;
+}
+
+void
+nm_manager_devcon_autoconnect_retries_set(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ guint32 retries)
+{
+ _autoconnect_retries_set(self,
+ _devcon_lookup_data(self, device, sett_conn, TRUE),
+ retries,
+ FALSE);
+}
+
+void
+nm_manager_devcon_autoconnect_retries_reset(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn)
+{
+ DevConData *data;
+
+ nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
+
+ if (device)
+ _autoconnect_retries_set(self,
+ _devcon_lookup_data(self, device, sett_conn, TRUE),
+ _autoconnect_retries_initial(sett_conn),
+ TRUE);
+ else {
+ c_list_for_each_entry (data, &sett_conn->devcon_con_lst_head, con_lst)
+ _autoconnect_retries_set(self, data, _autoconnect_retries_initial(sett_conn), TRUE);
+ }
+}
+
+/**
+ * nm_manager_devcon_autoconnect_reset_reconnect_all:
+ * @self: the #NMManager
+ * @device: the #NMDevice
+ * @sett_conn: the #NMSettingsConnection
+ * @only_no_secrets: boolean to reset all reasons or only no secrets.
+ *
+ * Returns a boolean indicating if something changed or not when resetting the
+ * blocked reasons. If a #NMDevice is present then we also reset the reasons
+ * for the (device, connection) tuple.
+ */
+gboolean
+nm_manager_devcon_autoconnect_reset_reconnect_all(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ gboolean only_no_secrets)
+{
+ gboolean changed = FALSE;
+
+ nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
+
+ if (only_no_secrets) {
+ /* we only reset the no-secrets blocked flag. */
+ if (nm_settings_connection_autoconnect_blocked_reason_set(
+ sett_conn,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS,
+ FALSE)) {
+ /* maybe the connection is still blocked afterwards for other reasons
+ * and in the larger picture nothing changed. Check if the connection
+ * is still blocked or not. */
+ if (!nm_settings_connection_autoconnect_is_blocked(sett_conn))
+ changed = TRUE;
+ }
+
+ return changed;
+ }
+
+ /* we reset the tries-count and any blocked-reason */
+ nm_manager_devcon_autoconnect_retries_reset(self, NULL, sett_conn);
+
+ /* if there is a device and we changed the state, then something changed. */
+ if (device
+ && nm_manager_devcon_autoconnect_blocked_reason_set(
+ self,
+ device,
+ sett_conn,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED
+ | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
+ FALSE))
+ changed = TRUE;
+
+ /* we remove all the blocked reason from the connection, if something
+ * happened, then it means the status changed */
+ if (nm_settings_connection_autoconnect_blocked_reason_set(
+ sett_conn,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS
+ | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
+ FALSE))
+ changed = TRUE;
+
+ return changed;
+}
+
+gint32
+nm_manager_devcon_autoconnect_retries_blocked_until(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn)
+{
+ DevConData *data;
+ gint32 min_stamp;
+
+ nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
+
+ if (device) {
+ data = _devcon_lookup_data(self, device, sett_conn, TRUE);
+ return data->autoconnect.blocked_until_sec;
+ } else {
+ min_stamp = 0;
+ c_list_for_each_entry (data, &sett_conn->devcon_con_lst_head, con_lst) {
+ gint32 condev_stamp = data->autoconnect.blocked_until_sec;
+ if (condev_stamp == 0)
+ continue;
+
+ if (min_stamp == 0 || min_stamp > condev_stamp)
+ min_stamp = condev_stamp;
+ }
+ }
+
+ return min_stamp;
+}
+
+gboolean
+nm_manager_devcon_autoconnect_is_blocked(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn)
+{
+ DevConData *data;
+
+ nm_assert(NM_IS_DEVICE(device));
+ nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
+
+ if (nm_settings_connection_autoconnect_is_blocked(sett_conn))
+ return TRUE;
+
+ data = _devcon_lookup_data(self, device, sett_conn, TRUE);
+ if (data->autoconnect.blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
+ return TRUE;
+
+ if (data->autoconnect.retries == 0 && data->autoconnect.initialized)
+ return TRUE;
+
+ return FALSE;
+}
+
+gboolean
+nm_manager_devcon_autoconnect_blocked_reason_set(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ NMSettingsAutoconnectBlockedReason value,
+ gboolean set)
+{
+ NMSettingsAutoconnectBlockedReason v;
+ DevConData *data;
+ gboolean changed = FALSE;
+ char buf[100];
+
+ nm_assert(value);
+ nm_assert(sett_conn);
+
+ if (device) {
+ data = _devcon_lookup_data(self, device, sett_conn, TRUE);
+ v = data->autoconnect.blocked_reason;
+ v = NM_FLAGS_ASSIGN(v, value, set);
+
+ if (data->autoconnect.blocked_reason == v)
+ return FALSE;
+
+ _LOGT(LOGD_SETTINGS,
+ "autoconnect: blocked reason: %s for device %s",
+ nm_settings_autoconnect_blocked_reason_to_string(v, buf, sizeof(buf)),
+ nm_device_get_ip_iface(device));
+ data->autoconnect.blocked_reason = v;
+ return TRUE;
+ }
+
+ c_list_for_each_entry (data, &sett_conn->devcon_con_lst_head, con_lst) {
+ v = data->autoconnect.blocked_reason;
+ v = NM_FLAGS_ASSIGN(v, value, set);
+
+ if (data->autoconnect.blocked_reason == v)
+ continue;
+ _LOGT(LOGD_SETTINGS,
+ "autoconnect: blocked reason: %s for device %s",
+ nm_settings_autoconnect_blocked_reason_to_string(v, buf, sizeof(buf)),
+ nm_device_get_ip_iface(data->device));
+ data->autoconnect.blocked_reason = v;
+ changed = TRUE;
+ }
+
+ return changed;
+}
+
+/*****************************************************************************/
+
static guint
_devcon_data_hash(gconstpointer ptr)
{
@@ -1280,6 +1579,10 @@ _devcon_lookup_data(NMManager *self,
*data = (DevConData){
.device = device,
.sett_conn = sett_conn,
+ .autoconnect =
+ {
+ .initialized = FALSE,
+ },
};
c_list_link_tail(&device->devcon_dev_lst_head, &data->dev_lst);
c_list_link_tail(&sett_conn->devcon_con_lst_head, &data->con_lst);
@@ -1325,7 +1628,7 @@ static gboolean
_devcon_remove_sett_conn_all(NMManager *self, NMSettingsConnection *sett_conn)
{
DevConData *data;
- gboolean changed;
+ gboolean changed = FALSE;
nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h
index 851b9b5388..ad8d0ba81a 100644
--- a/src/core/nm-manager.h
+++ b/src/core/nm-manager.h
@@ -224,4 +224,40 @@ void nm_manager_device_auth_request(NMManager *self,
void nm_manager_unblock_failed_ovs_interfaces(NMManager *self);
+/*****************************************************************************/
+
+#define NM_AUTOCONNECT_RETRIES_FOREVER G_MAXUINT32
+
+guint32 nm_manager_devcon_autoconnect_retries_get(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn);
+
+void nm_manager_devcon_autoconnect_retries_set(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ guint32 retries);
+
+void nm_manager_devcon_autoconnect_retries_reset(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn);
+
+gboolean nm_manager_devcon_autoconnect_reset_reconnect_all(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ gboolean only_no_secrets);
+
+gint32 nm_manager_devcon_autoconnect_retries_blocked_until(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn);
+
+gboolean nm_manager_devcon_autoconnect_is_blocked(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn);
+
+gboolean nm_manager_devcon_autoconnect_blocked_reason_set(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ NMSettingsAutoconnectBlockedReason value,
+ gboolean set);
+
#endif /* __NETWORKMANAGER_MANAGER_H__ */
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
index d7e05b7b5b..ea9643f400 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -1328,7 +1328,9 @@ pending_ac_state_changed(NMActiveConnection *ac, guint state, guint reason, NMPo
*/
if (reason != NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED) {
con = nm_active_connection_get_settings_connection(ac);
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ nm_active_connection_get_device(ac),
con,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
TRUE);
@@ -1391,7 +1393,7 @@ auto_activate_device(NMPolicy *self, NMDevice *device)
NMSettingConnection *s_con;
const char *permission;
- if (nm_settings_connection_autoconnect_is_blocked(candidate))
+ if (nm_manager_devcon_autoconnect_is_blocked(priv->manager, device, candidate))
continue;
cand_conn = nm_settings_connection_get_connection(candidate);
@@ -1435,7 +1437,9 @@ auto_activate_device(NMPolicy *self, NMDevice *device)
"connection '%s' auto-activation failed: %s",
nm_settings_connection_get_id(best_connection),
error->message);
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ device,
best_connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
TRUE);
@@ -1600,8 +1604,10 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self)
NMConnection *connection = nm_settings_connection_get_connection(sett_conn);
if (nm_connection_get_setting_ovs_interface(connection)) {
- nm_settings_connection_autoconnect_retries_reset(sett_conn);
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_retries_reset(priv->manager, NULL, sett_conn);
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ NULL,
sett_conn,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
FALSE);
@@ -1637,33 +1643,11 @@ reset_autoconnect_all(
NULL))
continue;
- if (only_no_secrets) {
- /* we only reset the no-secrets blocked flag. */
- if (nm_settings_connection_autoconnect_blocked_reason_set(
- sett_conn,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS,
- FALSE)) {
- /* maybe the connection is still blocked afterwards for other reasons
- * and in the larger picture nothing changed. But it's too complicated
- * to find out exactly. Just assume, something changed to be sure. */
- if (!nm_settings_connection_autoconnect_is_blocked(sett_conn))
- changed = TRUE;
- }
- } else {
- /* we reset the tries-count and any blocked-reason */
- if (nm_settings_connection_autoconnect_retries_get(sett_conn) == 0)
- changed = TRUE;
- nm_settings_connection_autoconnect_retries_reset(sett_conn);
-
- if (nm_settings_connection_autoconnect_blocked_reason_set(
- sett_conn,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL
- & ~NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
- FALSE)) {
- if (!nm_settings_connection_autoconnect_is_blocked(sett_conn))
- changed = TRUE;
- }
- }
+ if (nm_manager_devcon_autoconnect_reset_reconnect_all(priv->manager,
+ device,
+ sett_conn,
+ only_no_secrets))
+ changed = TRUE;
}
return changed;
}
@@ -1737,12 +1721,13 @@ reset_connections_retries(gpointer user_data)
for (i = 0; connections[i]; i++) {
NMSettingsConnection *connection = connections[i];
- con_stamp = nm_settings_connection_autoconnect_retries_blocked_until(connection);
+ con_stamp =
+ nm_manager_devcon_autoconnect_retries_blocked_until(priv->manager, NULL, connection);
if (con_stamp == 0)
continue;
if (con_stamp <= now) {
- nm_settings_connection_autoconnect_retries_reset(connection);
+ nm_manager_devcon_autoconnect_retries_reset(priv->manager, NULL, connection);
changed = TRUE;
} else if (min_stamp == 0 || min_stamp > con_stamp)
min_stamp = con_stamp;
@@ -1761,20 +1746,23 @@ reset_connections_retries(gpointer user_data)
}
static void
-_connection_autoconnect_retries_set(NMPolicy *self, NMSettingsConnection *connection, int tries)
+_connection_autoconnect_retries_set(NMPolicy *self,
+ NMDevice *device,
+ NMSettingsConnection *connection,
+ guint32 tries)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
nm_assert(NM_IS_SETTINGS_CONNECTION(connection));
- nm_assert(tries >= 0);
- nm_settings_connection_autoconnect_retries_set(connection, tries);
+ nm_manager_devcon_autoconnect_retries_set(priv->manager, device, connection, tries);
if (tries == 0) {
/* Schedule a handler to reset retries count */
if (!priv->reset_retries_id) {
- gint32 retry_time =
- nm_settings_connection_autoconnect_retries_blocked_until(connection);
+ gint32 retry_time = nm_manager_devcon_autoconnect_retries_blocked_until(priv->manager,
+ device,
+ connection);
g_warn_if_fail(retry_time != 0);
priv->reset_retries_id =
@@ -1839,11 +1827,14 @@ activate_slave_connections(NMPolicy *self, NMDevice *device)
continue;
if (!internal_activation) {
- if (nm_settings_connection_autoconnect_retries_get(sett_conn) == 0)
- changed = TRUE;
- nm_settings_connection_autoconnect_retries_reset(sett_conn);
+ nm_manager_devcon_autoconnect_retries_reset(priv->manager, NULL, sett_conn);
+ /* we cannot know if they changed or not, so considering we did a reset, let's consider they changed. */
+ changed = TRUE;
}
- if (nm_settings_connection_autoconnect_blocked_reason_set(
+ /* unblock the devices associated with that connection */
+ if (nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ NULL,
sett_conn,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
FALSE)) {
@@ -1968,7 +1959,9 @@ device_state_changed(NMDevice *device,
* a missing SIM or wrong modem initialization).
*/
if (sett_conn) {
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ device,
sett_conn,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
TRUE);
@@ -1988,7 +1981,6 @@ device_state_changed(NMDevice *device,
if (sett_conn && old_state >= NM_DEVICE_STATE_PREPARE
&& old_state <= NM_DEVICE_STATE_ACTIVATED) {
gboolean blocked = FALSE;
- int tries;
guint64 con_v;
if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) {
@@ -2027,9 +2019,13 @@ device_state_changed(NMDevice *device,
* dependency-failed.
*/
_LOGD(LOGD_DEVICE,
- "connection '%s' now blocked from autoconnect due to failed dependency",
+ "autoconnect: connection[%p] (%s) now blocked from autoconnect due to failed "
+ "dependency",
+ sett_conn,
nm_settings_connection_get_id(sett_conn));
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ device,
sett_conn,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
TRUE);
@@ -2037,16 +2033,23 @@ device_state_changed(NMDevice *device,
}
if (!blocked) {
- tries = nm_settings_connection_autoconnect_retries_get(sett_conn);
- if (tries > 0) {
+ guint32 tries;
+
+ tries = nm_manager_devcon_autoconnect_retries_get(priv->manager, device, sett_conn);
+ if (tries == 0) {
+ /* blocked */
+ } else if (tries != NM_AUTOCONNECT_RETRIES_FOREVER) {
_LOGD(LOGD_DEVICE,
- "connection '%s' failed to autoconnect; %d tries left",
+ "autoconnect: connection[%p] (%s): failed to autoconnect; %u tries left",
+ sett_conn,
nm_settings_connection_get_id(sett_conn),
- tries - 1);
- _connection_autoconnect_retries_set(self, sett_conn, tries - 1);
- } else if (tries != 0) {
+ tries - 1u);
+ _connection_autoconnect_retries_set(self, device, sett_conn, tries - 1u);
+ } else {
_LOGD(LOGD_DEVICE,
- "connection '%s' failed to autoconnect; infinite tries left",
+ "autoconnect: connection[%p] (%s) failed to autoconnect; infinite tries "
+ "left",
+ sett_conn,
nm_settings_connection_get_id(sett_conn));
}
}
@@ -2055,7 +2058,7 @@ device_state_changed(NMDevice *device,
case NM_DEVICE_STATE_ACTIVATED:
if (sett_conn) {
/* Reset auto retries back to default since connection was successful */
- nm_settings_connection_autoconnect_retries_reset(sett_conn);
+ nm_manager_devcon_autoconnect_retries_reset(priv->manager, device, sett_conn);
}
/* Since there is no guarantee that device_l3cd_changed() is called
@@ -2105,9 +2108,16 @@ device_state_changed(NMDevice *device,
nm_settings_connection_get_id(sett_conn),
NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_string,
nm_device_state_reason_check(reason)));
- nm_settings_connection_autoconnect_blocked_reason_set(sett_conn,
- blocked_reason,
- TRUE);
+ if (blocked_reason == NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED)
+ nm_manager_devcon_autoconnect_blocked_reason_set(priv->manager,
+ device,
+ sett_conn,
+ blocked_reason,
+ TRUE);
+ else
+ nm_settings_connection_autoconnect_blocked_reason_set(sett_conn,
+ blocked_reason,
+ TRUE);
}
}
ip6_remove_device_prefix_delegations(self, device);
@@ -2146,7 +2156,9 @@ device_state_changed(NMDevice *device,
case NM_DEVICE_STATE_IP_CONFIG:
/* We must have secrets if we got here. */
if (sett_conn)
- nm_settings_connection_autoconnect_blocked_reason_set(
+ nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ device,
sett_conn,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL,
FALSE);
diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c
index cc2d27b795..8503e64536 100644
--- a/src/core/settings/nm-settings-connection.c
+++ b/src/core/settings/nm-settings-connection.c
@@ -24,13 +24,10 @@
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-audit-manager.h"
#include "nm-settings.h"
+#include "nm-manager.h"
#include "nm-dbus-manager.h"
#include "settings/plugins/keyfile/nms-keyfile-storage.h"
-#define AUTOCONNECT_RETRIES_UNSET -2
-#define AUTOCONNECT_RETRIES_FOREVER -1
-#define AUTOCONNECT_RESET_RETRIES_TIMER 300
-
#define SEEN_BSSIDS_MAX 30
#define _NM_SETTINGS_UPDATE2_FLAG_ALL_PERSIST_MODES \
@@ -159,10 +156,6 @@ typedef struct _NMSettingsConnectionPrivate {
guint64 last_secret_agent_version_id;
- int autoconnect_retries;
-
- gint32 autoconnect_retries_blocked_until;
-
bool timestamp_set : 1;
NMSettingsAutoconnectBlockedReason autoconnect_blocked_reason : 4;
@@ -1461,52 +1454,6 @@ update_complete(NMSettingsConnection *self, UpdateInfo *info, GError *error)
g_slice_free(UpdateInfo, info);
}
-static int
-_autoconnect_retries_initial(NMSettingsConnection *self)
-{
- NMSettingConnection *s_con;
- int retries = -1;
-
- s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(self));
- if (s_con)
- retries = nm_setting_connection_get_autoconnect_retries(s_con);
-
- /* -1 means 'default' */
- if (retries == -1)
- retries = nm_config_data_get_autoconnect_retries_default(NM_CONFIG_GET_DATA);
-
- /* 0 means 'forever', which is translated to a retry count of -1 */
- if (retries == 0)
- retries = AUTOCONNECT_RETRIES_FOREVER;
-
- nm_assert(retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0);
- return retries;
-}
-
-static void
-_autoconnect_retries_set(NMSettingsConnection *self, int retries, gboolean is_reset)
-{
- NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self);
-
- g_return_if_fail(retries == AUTOCONNECT_RETRIES_FOREVER || retries >= 0);
-
- if (priv->autoconnect_retries != retries) {
- _LOGT("autoconnect: retries set %d%s", retries, is_reset ? " (reset)" : "");
- priv->autoconnect_retries = retries;
- }
-
- if (retries)
- priv->autoconnect_retries_blocked_until = 0;
- else {
- /* NOTE: the blocked time must be identical for all connections, otherwise
- * the tracking of resetting the retry count in NMPolicy needs adjustment
- * in _connection_autoconnect_retries_set() (as it would need to re-evaluate
- * the next-timeout every time a connection gets blocked). */
- priv->autoconnect_retries_blocked_until =
- nm_utils_get_monotonic_timestamp_sec() + AUTOCONNECT_RESET_RETRIES_TIMER;
- }
-}
-
static void
update_auth_cb(NMSettingsConnection *self,
GDBusMethodInvocation *context,
@@ -1558,7 +1505,10 @@ update_auth_cb(NMSettingsConnection *self,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS,
FALSE)
&& !nm_settings_connection_autoconnect_blocked_reason_get(self))
- nm_settings_connection_autoconnect_retries_reset(self);
+ nm_manager_devcon_autoconnect_retries_reset(
+ nm_settings_connection_get_manager(self),
+ NULL,
+ self);
}
}
@@ -1631,7 +1581,9 @@ update_auth_cb(NMSettingsConnection *self,
}
/* Reset auto retries back to default since connection was updated */
- nm_settings_connection_autoconnect_retries_reset(self);
+ nm_manager_devcon_autoconnect_retries_reset(nm_settings_connection_get_manager(self),
+ NULL,
+ self);
update_complete(self, info, local);
}
@@ -2550,48 +2502,6 @@ nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *se
/*****************************************************************************/
-/**
- * nm_settings_connection_autoconnect_retries_get:
- * @self: the settings connection
- *
- * Returns the number of autoconnect retries left. If the value is
- * not yet set, initialize it with the value from the connection or
- * with the global default.
- */
-int
-nm_settings_connection_autoconnect_retries_get(NMSettingsConnection *self)
-{
- NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self);
-
- if (G_UNLIKELY(priv->autoconnect_retries == AUTOCONNECT_RETRIES_UNSET)) {
- _autoconnect_retries_set(self, _autoconnect_retries_initial(self), TRUE);
- }
- return priv->autoconnect_retries;
-}
-
-void
-nm_settings_connection_autoconnect_retries_set(NMSettingsConnection *self, int retries)
-{
- g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self));
- g_return_if_fail(retries >= 0);
-
- _autoconnect_retries_set(self, retries, FALSE);
-}
-
-void
-nm_settings_connection_autoconnect_retries_reset(NMSettingsConnection *self)
-{
- g_return_if_fail(NM_IS_SETTINGS_CONNECTION(self));
-
- _autoconnect_retries_set(self, _autoconnect_retries_initial(self), TRUE);
-}
-
-gint32
-nm_settings_connection_autoconnect_retries_blocked_until(NMSettingsConnection *self)
-{
- return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->autoconnect_retries_blocked_until;
-}
-
NMSettingsAutoconnectBlockedReason
nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self)
{
@@ -2599,25 +2509,27 @@ nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self
}
gboolean
-nm_settings_connection_autoconnect_blocked_reason_set_full(NMSettingsConnection *self,
- NMSettingsAutoconnectBlockedReason mask,
- NMSettingsAutoconnectBlockedReason value)
+nm_settings_connection_autoconnect_blocked_reason_set(NMSettingsConnection *self,
+ NMSettingsAutoconnectBlockedReason reason,
+ gboolean set)
{
NMSettingsAutoconnectBlockedReason v;
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self);
- char buf[100];
+ char buf1[100];
+ char buf2[100];
- nm_assert(mask);
- nm_assert(!NM_FLAGS_ANY(value, ~mask));
+ nm_assert(reason);
v = priv->autoconnect_blocked_reason;
- v = (v & ~mask) | (value & mask);
+ v = NM_FLAGS_ASSIGN(v, reason, set);
if (priv->autoconnect_blocked_reason == v)
return FALSE;
- _LOGT("autoconnect: blocked reason: %s",
- nm_settings_autoconnect_blocked_reason_to_string(v, buf, sizeof(buf)));
+ _LOGD("autoconnect: %s blocked reason: %s (now %s)",
+ set ? "set" : "unset",
+ nm_settings_autoconnect_blocked_reason_to_string(reason, buf1, sizeof(buf1)),
+ nm_settings_autoconnect_blocked_reason_to_string(v, buf2, sizeof(buf2)));
priv->autoconnect_blocked_reason = v;
return TRUE;
}
@@ -2634,8 +2546,6 @@ nm_settings_connection_autoconnect_is_blocked(NMSettingsConnection *self)
if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
return TRUE;
- if (priv->autoconnect_retries == 0)
- return TRUE;
flags = priv->flags;
if (NM_FLAGS_ANY(flags,
@@ -2755,8 +2665,6 @@ nm_settings_connection_init(NMSettingsConnection *self)
priv->agent_mgr = g_object_ref(nm_agent_manager_get());
priv->settings = g_object_ref(nm_settings_get());
-
- priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET;
}
NMSettingsConnection *
diff --git a/src/core/settings/nm-settings-connection.h b/src/core/settings/nm-settings-connection.h
index 9ddb939d98..546e4efb14 100644
--- a/src/core/settings/nm-settings-connection.h
+++ b/src/core/settings/nm-settings-connection.h
@@ -338,31 +338,15 @@ gboolean nm_settings_connection_has_seen_bssid(NMSettingsConnection *self, const
void nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *seen_bssid);
-int nm_settings_connection_autoconnect_retries_get(NMSettingsConnection *self);
-void nm_settings_connection_autoconnect_retries_set(NMSettingsConnection *self, int retries);
-void nm_settings_connection_autoconnect_retries_reset(NMSettingsConnection *self);
-
-gint32 nm_settings_connection_autoconnect_retries_blocked_until(NMSettingsConnection *self);
+gboolean nm_settings_connection_autoconnect_is_blocked(NMSettingsConnection *self);
NMSettingsAutoconnectBlockedReason
- nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self);
-gboolean nm_settings_connection_autoconnect_blocked_reason_set_full(
- NMSettingsConnection *self,
- NMSettingsAutoconnectBlockedReason mask,
- NMSettingsAutoconnectBlockedReason value);
+nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self);
-static inline gboolean
+gboolean
nm_settings_connection_autoconnect_blocked_reason_set(NMSettingsConnection *self,
- NMSettingsAutoconnectBlockedReason mask,
- gboolean set)
-{
- return nm_settings_connection_autoconnect_blocked_reason_set_full(
- self,
- mask,
- set ? mask : NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE);
-}
-
-gboolean nm_settings_connection_autoconnect_is_blocked(NMSettingsConnection *self);
+ NMSettingsAutoconnectBlockedReason reason,
+ gboolean set);
const char *nm_settings_connection_get_id(NMSettingsConnection *connection);
const char *nm_settings_connection_get_uuid(NMSettingsConnection *connection);