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