wifi: fix aggressively roaming (background Wi-Fi scanning) based on seen-bssids

"wifi.seen-bssids" looks like a regular property, but it is not. Unlike
almost all other properties, it does not contain user configuration,
rather it gets filled by the daemon.

The values are thus stored in "/var/lib/NetworkManager/seen-bssids"
file, and the daemon maintains the values separately from the profile.
Only before exporting the profile on D-Bus, the value gets merged (see
NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->>getsettings_cached and
nm_connection_to_dbus_full().

Hence, looking at nm_setting_wireless_get_num_seen_bssids() is not
working. Fix that.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1253

Fixes: 0f3203338c ('wifi: roam aggressively if we on a multi-AP network')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1577
(cherry picked from commit 07c6f933d1)
This commit is contained in:
Thomas Haller 2023-03-21 16:55:29 +01:00
parent f71cd2eb72
commit 3ddc17700d
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
6 changed files with 34 additions and 11 deletions

View file

@ -2912,10 +2912,11 @@ supplicant_connection_timeout_cb(gpointer user_data)
}
static NMSupplicantConfig *
build_supplicant_config(NMDeviceWifi *self,
NMConnection *connection,
guint32 fixed_freq,
GError **error)
build_supplicant_config(NMDeviceWifi *self,
NMSettingsConnection *sett_conn,
NMConnection *connection,
guint32 fixed_freq,
GError **error)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self);
NMSupplicantConfig *config = NULL;
@ -2944,7 +2945,10 @@ build_supplicant_config(NMDeviceWifi *self,
goto error;
}
if (!nm_supplicant_config_add_bgscan(config, connection, error)) {
if (!nm_supplicant_config_add_bgscan(config,
connection,
nm_settings_connection_get_num_seen_bssids(sett_conn),
error)) {
g_prefix_error(error, "bgscan: ");
goto error;
}
@ -3279,6 +3283,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
NMActRequest *req;
NMWifiAP *ap;
NMConnection *connection;
NMSettingsConnection *sett_conn;
const char *setting_name;
NMSettingWireless *s_wireless;
GError *error = NULL;
@ -3302,6 +3307,9 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
ap_mode = nm_wifi_ap_get_mode(ap);
sett_conn = nm_act_request_get_settings_connection(req);
nm_assert(sett_conn);
connection = nm_act_request_get_applied_connection(req);
s_wireless = nm_connection_get_setting_wireless(connection);
nm_assert(s_wireless);
@ -3350,7 +3358,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
set_powersave(device);
/* Build up the supplicant configuration */
config = build_supplicant_config(self, connection, nm_wifi_ap_get_freq(ap), &error);
config = build_supplicant_config(self, sett_conn, connection, nm_wifi_ap_get_freq(ap), &error);
if (!config) {
_LOGE(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) couldn't build wireless configuration: %s",

View file

@ -2532,6 +2532,14 @@ nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *se
nm_key_file_db_set_string_list(priv->kf_db_seen_bssids, connection_uuid, seen_bssids_strv, i);
}
guint
nm_settings_connection_get_num_seen_bssids(NMSettingsConnection *self)
{
g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(self), 0);
return nm_g_hash_table_size(NM_SETTINGS_CONNECTION_GET_PRIVATE(self)->seen_bssids_hash);
}
/*****************************************************************************/
/**

View file

@ -345,6 +345,8 @@ gboolean nm_settings_connection_has_seen_bssid(NMSettingsConnection *self, const
void nm_settings_connection_add_seen_bssid(NMSettingsConnection *self, const char *seen_bssid);
guint nm_settings_connection_get_num_seen_bssids(NMSettingsConnection *self);
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);

View file

@ -592,7 +592,10 @@ nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
}
gboolean
nm_supplicant_config_add_bgscan(NMSupplicantConfig *self, NMConnection *connection, GError **error)
nm_supplicant_config_add_bgscan(NMSupplicantConfig *self,
NMConnection *connection,
guint num_seen_bssids,
GError **error)
{
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
@ -629,7 +632,7 @@ nm_supplicant_config_add_bgscan(NMSupplicantConfig *self, NMConnection *connecti
* when the signal is still somewhat OK so we have an up-to-date roam
* candidate list when the signal gets bad.
*/
if (nm_setting_wireless_get_num_seen_bssids(s_wifi) > 1
if (num_seen_bssids > 1u
|| ((s_wsec = nm_connection_get_setting_wireless_security(connection))
&& NM_IN_STRSET(nm_setting_wireless_security_get_key_mgmt(s_wsec),
"ieee8021x",

View file

@ -44,8 +44,10 @@ gboolean nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
guint32 fixed_freq,
GError **error);
gboolean
nm_supplicant_config_add_bgscan(NMSupplicantConfig *self, NMConnection *connection, GError **error);
gboolean nm_supplicant_config_add_bgscan(NMSupplicantConfig *self,
NMConnection *connection,
guint num_seen_bssids,
GError **error);
gboolean nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig *self,
NMSettingWirelessSecurity *setting,

View file

@ -127,7 +127,7 @@ build_supplicant_config(NMConnection *connection,
g_assert_no_error(error);
g_assert(success);
success = nm_supplicant_config_add_bgscan(config, connection, &error);
success = nm_supplicant_config_add_bgscan(config, connection, 0, &error);
g_assert_no_error(error);
g_assert(success);