diff options
-rw-r--r-- | src/core/NetworkManagerUtils.c | 10 | ||||
-rw-r--r-- | src/core/NetworkManagerUtils.h | 20 | ||||
-rw-r--r-- | src/core/devices/nm-device-private.h | 4 | ||||
-rw-r--r-- | src/core/devices/nm-device.c | 2 | ||||
-rw-r--r-- | src/core/devices/nm-device.h | 5 | ||||
-rw-r--r-- | src/core/devices/ovs/nm-ovs-factory.c | 6 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-device-iwd.c | 7 | ||||
-rw-r--r-- | src/core/nm-manager.c | 446 | ||||
-rw-r--r-- | src/core/nm-manager.h | 41 | ||||
-rw-r--r-- | src/core/nm-policy.c | 154 | ||||
-rw-r--r-- | src/core/settings/nm-settings-connection.c | 160 | ||||
-rw-r--r-- | src/core/settings/nm-settings-connection.h | 45 | ||||
-rw-r--r-- | src/core/settings/nm-settings.c | 14 | ||||
-rw-r--r-- | src/core/settings/nm-settings.h | 2 |
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, |