summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFernando Fernandez Mancera <ffmancera@riseup.net>2023-02-23 10:01:40 +0100
committerFernando Fernandez Mancera <ffmancera@riseup.net>2023-02-23 10:01:40 +0100
commit61c09717483f9660d84982591da3b75add5f7feb (patch)
treecff94835345fd8c7337c00da4eff49328d1d2bd2
parentb5e347b31316ca62646017b928c834eeab1004e8 (diff)
parent81fbe0634e4c0e31d742420d91c01e460aaa2fd5 (diff)
downloadNetworkManager-61c09717483f9660d84982591da3b75add5f7feb.tar.gz
merge: branch 'th/devcon-track-autoconnect'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1530
-rw-r--r--src/core/NetworkManagerUtils.c10
-rw-r--r--src/core/NetworkManagerUtils.h20
-rw-r--r--src/core/devices/nm-device-private.h4
-rw-r--r--src/core/devices/nm-device.c2
-rw-r--r--src/core/devices/nm-device.h5
-rw-r--r--src/core/devices/ovs/nm-ovs-factory.c6
-rw-r--r--src/core/devices/wifi/nm-device-iwd.c7
-rw-r--r--src/core/nm-manager.c446
-rw-r--r--src/core/nm-manager.h41
-rw-r--r--src/core/nm-policy.c154
-rw-r--r--src/core/settings/nm-settings-connection.c160
-rw-r--r--src/core/settings/nm-settings-connection.h45
-rw-r--r--src/core/settings/nm-settings.c14
-rw-r--r--src/core/settings/nm-settings.h2
14 files changed, 678 insertions, 238 deletions
diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c
index 6f4c60f876..b65745a1cb 100644
--- a/src/core/NetworkManagerUtils.c
+++ b/src/core/NetworkManagerUtils.c
@@ -1860,3 +1860,13 @@ nm_linux_platform_setup_with_tc_cache(void)
{
nm_platform_setup(nm_linux_platform_new(NULL, FALSE, FALSE, TRUE));
}
+
+/*****************************************************************************/
+
+NM_UTILS_FLAGS2STR_DEFINE(
+ nm_settings_autoconnect_blocked_reason_to_string,
+ NMSettingsAutoconnectBlockedReason,
+ NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE, "none"),
+ NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST, "user-request"),
+ NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED, "failed"),
+ NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS, "no-secrets"), );
diff --git a/src/core/NetworkManagerUtils.h b/src/core/NetworkManagerUtils.h
index 67c9cba471..c55e6255bc 100644
--- a/src/core/NetworkManagerUtils.h
+++ b/src/core/NetworkManagerUtils.h
@@ -228,6 +228,26 @@ void nm_utils_ip_routes_to_dbus(int addr_family,
/*****************************************************************************/
+typedef enum _nm_packed {
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE = 0,
+
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST = (1LL << 0),
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED = (1LL << 1),
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS = (1LL << 2),
+
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_ALL =
+ (NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST
+ | NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED
+ | NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS),
+} NMSettingsAutoconnectBlockedReason;
+
+const char *
+nm_settings_autoconnect_blocked_reason_to_string(NMSettingsAutoconnectBlockedReason reason,
+ char *buf,
+ gsize len);
+
+/*****************************************************************************/
+
/* For now, all we track about a DHCP lease is the GHashTable with
* the options.
*
diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h
index c597e05260..6f3a1c3e42 100644
--- a/src/core/devices/nm-device-private.h
+++ b/src/core/devices/nm-device-private.h
@@ -29,10 +29,6 @@ enum NMActStageReturn {
#define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000
-NMSettings *nm_device_get_settings(NMDevice *self);
-
-NMManager *nm_device_get_manager(NMDevice *self);
-
gboolean nm_device_set_ip_ifindex(NMDevice *self, int ifindex);
gboolean nm_device_set_ip_iface(NMDevice *self, const char *iface);
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 6f8b416440..c0cdd733d9 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -17729,6 +17729,7 @@ nm_device_init(NMDevice *self)
c_list_init(&priv->concheck_lst_head);
c_list_init(&self->devices_lst);
+ c_list_init(&self->devcon_dev_lst_head);
c_list_init(&priv->slaves);
priv->ipdhcp_data_6.v6.mode = NM_NDISC_DHCP_LEVEL_NONE;
@@ -17849,6 +17850,7 @@ dispose(GObject *object)
_LOGD(LOGD_DEVICE, "disposing");
nm_assert(c_list_is_empty(&self->devices_lst));
+ nm_assert(c_list_is_empty(&self->devcon_dev_lst_head));
while ((con_handle = c_list_first_entry(&priv->concheck_lst_head,
NMDeviceConnectivityHandle,
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
index 65e3433404..435a6f82aa 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -144,6 +144,7 @@ struct _NMDevice {
NMDBusObject parent;
struct _NMDevicePrivate *_priv;
CList devices_lst;
+ CList devcon_dev_lst_head;
};
/* The flags have an relaxing meaning, that means, specifying more flags, can make
@@ -421,6 +422,10 @@ typedef struct _NMDeviceClass {
const char *(*get_dhcp_anycast_address)(NMDevice *self);
} NMDeviceClass;
+NMSettings *nm_device_get_settings(NMDevice *self);
+
+NMManager *nm_device_get_manager(NMDevice *self);
+
GType nm_device_get_type(void);
struct _NMDedupMultiIndex *nm_device_get_multi_index(NMDevice *self);
diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c
index 50023778cd..2ca1a0b5c7 100644
--- a/src/core/devices/ovs/nm-ovs-factory.c
+++ b/src/core/devices/ovs/nm-ovs-factory.c
@@ -240,9 +240,11 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_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 9d444e45f3..5e83a0c53e 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -69,6 +69,26 @@ 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 {
ASYNC_OP_TYPE_AC_AUTH_ACTIVATE_INTERNAL,
ASYNC_OP_TYPE_AC_AUTH_ACTIVATE_USER,
@@ -173,6 +193,8 @@ typedef struct {
} prop_filter;
NMRfkillManager *rfkill_mgr;
+ GHashTable *devcon_data_dict;
+
CList link_cb_lst;
NMCheckpointManager *checkpoint_mgr;
@@ -415,6 +437,11 @@ static void _activation_auth_done(NMManager *self,
static void _rfkill_update(NMManager *self, NMRfkillType rtype);
+static DevConData *_devcon_lookup_data(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ gboolean create);
+
/*****************************************************************************/
static NM_CACHED_QUARK_FCN("autoconnect-root", autoconnect_root_quark);
@@ -1212,6 +1239,415 @@ 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_AUTOCONNECT_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_AUTOCONNECT_BLOCKED_REASON_FAILED
+ | NM_SETTINGS_AUTOCONNECT_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_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS
+ | NM_SETTINGS_AUTOCONNECT_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_AUTOCONNECT_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)
+{
+ const DevConData *data = ptr;
+
+ nm_assert(NM_IS_DEVICE(data->device));
+ nm_assert(NM_IS_SETTINGS_CONNECTION(data->sett_conn));
+
+ return nm_hash_vals(1832112199u, data->device, data->sett_conn);
+}
+
+static gboolean
+_devcon_data_equal(gconstpointer ptr_a, gconstpointer ptr_b)
+{
+ const DevConData *data_a = ptr_a;
+ const DevConData *data_b = ptr_b;
+
+ nm_assert(NM_IS_DEVICE(data_a->device));
+ nm_assert(NM_IS_SETTINGS_CONNECTION(data_a->sett_conn));
+ nm_assert(NM_IS_DEVICE(data_b->device));
+ nm_assert(NM_IS_SETTINGS_CONNECTION(data_b->sett_conn));
+
+ return data_a->device == data_b->device && data_a->sett_conn == data_b->sett_conn;
+}
+
+static DevConData *
+_devcon_lookup_data(NMManager *self,
+ NMDevice *device,
+ NMSettingsConnection *sett_conn,
+ gboolean create)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
+ DevConData *data;
+ DevConData needle;
+
+ 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));
+
+ needle.device = device;
+ needle.sett_conn = sett_conn;
+
+ data = g_hash_table_lookup(priv->devcon_data_dict, &needle);
+
+ if (data)
+ return data;
+ if (!create)
+ return NULL;
+
+ data = g_slice_new(DevConData);
+ *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);
+
+ g_hash_table_add(priv->devcon_data_dict, data);
+
+ return data;
+}
+
+static void
+_devcon_remove_data(NMManager *self, DevConData *data)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
+
+ nm_assert(data);
+ nm_assert(NM_IS_DEVICE(data->device));
+ nm_assert(NM_IS_SETTINGS_CONNECTION(data->sett_conn));
+ nm_assert(data == _devcon_lookup_data(self, data->device, data->sett_conn, FALSE));
+
+ c_list_unlink_stale(&data->dev_lst);
+ c_list_unlink_stale(&data->con_lst);
+ g_hash_table_remove(priv->devcon_data_dict, data);
+ nm_g_slice_free(data);
+}
+
+static gboolean
+_devcon_remove_device_all(NMManager *self, NMDevice *device)
+{
+ DevConData *data;
+ gboolean changed;
+
+ nm_assert(NM_IS_DEVICE(device));
+
+ while ((data = c_list_first_entry(&device->devcon_dev_lst_head, DevConData, dev_lst))) {
+ changed = TRUE;
+ _devcon_remove_data(self, data);
+ }
+
+ return changed;
+}
+
+static gboolean
+_devcon_remove_sett_conn_all(NMManager *self, NMSettingsConnection *sett_conn)
+{
+ DevConData *data;
+ gboolean changed = FALSE;
+
+ nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn));
+
+ while ((data = c_list_first_entry(&sett_conn->devcon_con_lst_head, DevConData, con_lst))) {
+ changed = TRUE;
+ _devcon_remove_data(self, data);
+ }
+
+ return changed;
+}
+
+void
+nm_manager_notify_delete_settings_connections(NMManager *self, NMSettingsConnection *sett_conn)
+{
+ _devcon_remove_sett_conn_all(self, sett_conn);
+}
+
+/*****************************************************************************/
+
static void
_config_changed_cb(NMConfig *config,
NMConfigData *config_data,
@@ -1814,6 +2250,8 @@ remove_device(NMManager *self, NMDevice *device, gboolean quitting)
nm_settings_device_removed(priv->settings, device, quitting);
+ _devcon_remove_device_all(self, device);
+
c_list_unlink(&device->devices_lst);
_parent_notify_changed(self, device, TRUE);
@@ -5159,7 +5597,7 @@ _internal_activate_device(NMManager *self, NMActiveConnection *active, GError **
if (nm_active_connection_get_activation_reason(active)
== NM_ACTIVATION_REASON_AUTOCONNECT
&& NM_FLAGS_HAS(nm_settings_connection_autoconnect_blocked_reason_get(parent_con),
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST)) {
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST)) {
g_set_error(error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_DEPENDENCY_FAILED,
@@ -5790,7 +6228,7 @@ _activation_auth_done(NMManager *self,
nm_settings_connection_autoconnect_blocked_reason_set(
connection,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST,
FALSE);
g_dbus_method_invocation_return_value(
invocation,
@@ -8114,6 +8552,8 @@ nm_manager_init(NMManager *self)
priv->state = NM_STATE_DISCONNECTED;
priv->startup = TRUE;
+ priv->devcon_data_dict = g_hash_table_new(_devcon_data_hash, _devcon_data_equal);
+
/* sleep/wake handling */
priv->sleep_monitor = nm_sleep_monitor_new();
g_signal_connect(priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING, G_CALLBACK(sleeping_cb), self);
@@ -8447,6 +8887,8 @@ dispose(GObject *object)
nm_clear_pointer(&priv->device_route_metrics, g_hash_table_destroy);
+ nm_clear_pointer(&priv->devcon_data_dict, g_hash_table_destroy);
+
G_OBJECT_CLASS(nm_manager_parent_class)->dispose(object);
}
diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h
index 0cbbcbf0ae..ad8d0ba81a 100644
--- a/src/core/nm-manager.h
+++ b/src/core/nm-manager.h
@@ -207,6 +207,11 @@ struct _NMDnsManager *nm_manager_get_dns_manager(NMManager *self);
/*****************************************************************************/
+void nm_manager_notify_delete_settings_connections(NMManager *self,
+ NMSettingsConnection *sett_conn);
+
+/*****************************************************************************/
+
void nm_manager_device_auth_request(NMManager *self,
NMDevice *device,
GDBusMethodInvocation *context,
@@ -219,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..014bed256f 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -1328,9 +1328,11 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
TRUE);
schedule_activate_check(self, nm_active_connection_get_device(ac));
}
@@ -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,9 +1437,11 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
TRUE);
schedule_activate_check(self, device);
return;
@@ -1600,10 +1604,12 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_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,13 +1827,16 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
FALSE)) {
if (!nm_settings_connection_autoconnect_is_blocked(sett_conn))
changed = TRUE;
@@ -1968,9 +1959,11 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
TRUE);
}
break;
@@ -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) {
@@ -2012,7 +2004,7 @@ device_state_changed(NMDevice *device,
nm_settings_connection_get_id(sett_conn));
nm_settings_connection_autoconnect_blocked_reason_set(
sett_conn,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS,
TRUE);
blocked = TRUE;
}
@@ -2027,26 +2019,37 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
TRUE);
blocked = TRUE;
}
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
@@ -2087,27 +2090,34 @@ device_state_changed(NMDevice *device,
case NM_DEVICE_STATE_DEACTIVATING:
if (sett_conn) {
NMSettingsAutoconnectBlockedReason blocked_reason =
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE;
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE;
switch (nm_device_state_reason_check(reason)) {
case NM_DEVICE_STATE_REASON_USER_REQUESTED:
- blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST;
+ blocked_reason = NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST;
break;
case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED:
- blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED;
+ blocked_reason = NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED;
break;
default:
break;
}
- if (blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE) {
+ if (blocked_reason != NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE) {
_LOGD(LOGD_DEVICE,
"blocking autoconnect of connection '%s': %s",
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_AUTOCONNECT_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,9 +2156,11 @@ 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,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_ALL,
FALSE);
break;
case NM_DEVICE_STATE_SECONDARIES:
diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c
index 1638efcd7e..b80af551ce 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;
@@ -227,6 +220,22 @@ static guint _get_seen_bssids(NMSettingsConnection *self,
/*****************************************************************************/
+NMSettings *
+nm_settings_connection_get_settings(NMSettingsConnection *self)
+{
+ g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), NULL);
+
+ return NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->settings;
+}
+
+NMManager *
+nm_settings_connection_get_manager(NMSettingsConnection *self)
+{
+ return nm_settings_get_manager(nm_settings_connection_get_settings(self));
+}
+
+/*****************************************************************************/
+
NMDevice *
nm_settings_connection_default_wired_get_device(NMSettingsConnection *self)
{
@@ -1445,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,
@@ -1539,10 +1502,13 @@ update_auth_cb(NMSettingsConnection *self,
/* New secrets, allow autoconnection again */
if (nm_settings_connection_autoconnect_blocked_reason_set(
self,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS,
+ NM_SETTINGS_AUTOCONNECT_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);
}
}
@@ -1615,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);
}
@@ -2534,56 +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;
-}
-
-static NM_UTILS_FLAGS2STR_DEFINE(
- _autoconnect_blocked_reason_to_string,
- NMSettingsAutoconnectBlockedReason,
- NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE, "none"),
- NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, "user-request"),
- NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, "failed"),
- NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, "no-secrets"), );
-
NMSettingsAutoconnectBlockedReason
nm_settings_connection_autoconnect_blocked_reason_get(NMSettingsConnection *self)
{
@@ -2591,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",
- _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;
}
@@ -2624,9 +2544,7 @@ nm_settings_connection_autoconnect_is_blocked(NMSettingsConnection *self)
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE(self);
- if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
- return TRUE;
- if (priv->autoconnect_retries == 0)
+ if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE)
return TRUE;
flags = priv->flags;
@@ -2740,14 +2658,13 @@ nm_settings_connection_init(NMSettingsConnection *self)
self->_priv = priv;
c_list_init(&self->_connections_lst);
+ c_list_init(&self->devcon_con_lst_head);
c_list_init(&priv->seen_bssids_lst_head);
c_list_init(&priv->call_ids_lst_head);
c_list_init(&priv->auth_lst_head);
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 *
@@ -2768,6 +2685,7 @@ dispose(GObject *object)
nm_assert(!priv->default_wired_device);
nm_assert(c_list_is_empty(&self->_connections_lst));
+ nm_assert(c_list_is_empty(&self->devcon_con_lst_head));
nm_assert(c_list_is_empty(&priv->auth_lst_head));
/* Cancel in-progress secrets requests */
diff --git a/src/core/settings/nm-settings-connection.h b/src/core/settings/nm-settings-connection.h
index 47599c3d6e..546e4efb14 100644
--- a/src/core/settings/nm-settings-connection.h
+++ b/src/core/settings/nm-settings-connection.h
@@ -9,6 +9,7 @@
#include "nm-dbus-object.h"
#include "nm-connection.h"
+#include "NetworkManagerUtils.h"
#include "nm-settings-storage.h"
@@ -188,19 +189,6 @@ typedef enum _NMSettingsConnectionIntFlags {
_NM_SETTINGS_CONNECTION_INT_FLAGS_ALL = ((_NM_SETTINGS_CONNECTION_INT_FLAGS_LAST - 1) << 1) - 1,
} NMSettingsConnectionIntFlags;
-typedef enum {
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE = 0,
-
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST = (1LL << 0),
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED = (1LL << 1),
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS = (1LL << 2),
-
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL =
- (NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST
- | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED
- | NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS),
-} NMSettingsAutoconnectBlockedReason;
-
typedef struct _NMSettingsConnectionCallId NMSettingsConnectionCallId;
typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass;
@@ -210,6 +198,7 @@ struct _NMSettingsConnectionPrivate;
struct _NMSettingsConnection {
NMDBusObject parent;
CList _connections_lst;
+ CList devcon_con_lst_head;
struct _NMSettingsConnectionPrivate *_priv;
};
@@ -217,6 +206,10 @@ GType nm_settings_connection_get_type(void);
NMSettingsConnection *nm_settings_connection_new(void);
+NMSettings *nm_settings_connection_get_settings(NMSettingsConnection *self);
+
+NMManager *nm_settings_connection_get_manager(NMSettingsConnection *self);
+
NMConnection *nm_settings_connection_get_connection(NMSettingsConnection *self);
void _nm_settings_connection_set_connection(NMSettingsConnection *self,
@@ -345,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);
diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c
index 63476c3c94..82dfb624c1 100644
--- a/src/core/settings/nm-settings.c
+++ b/src/core/settings/nm-settings.c
@@ -451,6 +451,16 @@ static void _startup_complete_check(NMSettings *self, gint64 now_msec);
/*****************************************************************************/
+NMManager *
+nm_settings_get_manager(NMSettings *self)
+{
+ g_return_val_if_fail(NM_IS_SETTINGS(self), NULL);
+
+ return NM_SETTINGS_GET_PRIVATE(self)->manager;
+}
+
+/*****************************************************************************/
+
static void
_emit_connection_added(NMSettings *self, NMSettingsConnection *sett_conn)
{
@@ -1109,7 +1119,7 @@ _connection_changed_update(NMSettings *self,
if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT)) {
nm_settings_connection_autoconnect_blocked_reason_set(
sett_conn,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST,
TRUE);
}
@@ -1237,6 +1247,8 @@ _connection_changed_delete(NMSettings *self,
| NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL,
FALSE);
+ nm_manager_notify_delete_settings_connections(priv->manager, sett_conn);
+
_emit_connection_removed(self, sett_conn);
_nm_settings_connection_cleanup_after_remove(sett_conn);
diff --git a/src/core/settings/nm-settings.h b/src/core/settings/nm-settings.h
index aba3c56545..020623d07d 100644
--- a/src/core/settings/nm-settings.h
+++ b/src/core/settings/nm-settings.h
@@ -58,6 +58,8 @@ NMSettings *nm_settings_get(void);
NMSettings *nm_settings_new(NMManager *manager);
+NMManager *nm_settings_get_manager(NMSettings *self);
+
gboolean nm_settings_start(NMSettings *self, GError **error);
typedef void (*NMSettingsAddCallback)(NMSettings *settings,