merge: branch 'th/devcon-track-autoconnect'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1530
This commit is contained in:
Fernando Fernandez Mancera 2023-02-23 10:01:40 +01:00
commit 61c0971748
14 changed files with 678 additions and 238 deletions

View file

@ -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"), );

View file

@ -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.
*

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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__ */

View file

@ -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:

View file

@ -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 */

View file

@ -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);

View file

@ -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);

View file

@ -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,