diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c index 50023778c..6a42960e0 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 e03227cd0..abfbd1a54 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 07a11150f..51fd8aeee 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 851b9b538..ad8d0ba81 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 d7e05b7b5..ea9643f40 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 cc2d27b79..8503e6453 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 9ddb939d9..546e4efb1 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);