wifi: cleanup ensure_hotspot_frequency()

wifi: choose a (stable) random channel for Wi-Fi hotspot

The channel depends on the SSID.

Based-on-patch-by: xiangnian <xiangnian@uniontech.com>

See-also: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1054

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1099
This commit is contained in:
Thomas Haller
2022-02-15 11:05:24 +01:00
parent 4f9f0587d5
commit f18bf17dea
4 changed files with 74 additions and 20 deletions

3
NEWS
View File

@@ -8,6 +8,9 @@ subject to change and not guaranteed to be compatible with
the later release. the later release.
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* Wi-Fi hotspots will use a (stable) random channel number unless one is
chosen manually.
============================================= =============================================
NetworkManager-1.36 NetworkManager-1.36
Overview of changes since NetworkManager-1.34 Overview of changes since NetworkManager-1.34

View File

@@ -3103,28 +3103,75 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
static void static void
ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP *ap) ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP *ap)
{ {
guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0};
guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0};
guint32 *rnd_freqs;
guint rnd_freqs_len;
NMDevice *device = NM_DEVICE(self); NMDevice *device = NM_DEVICE(self);
const char *band = nm_setting_wireless_get_band(s_wifi); const char *band = nm_setting_wireless_get_band(s_wifi);
const guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0}; guint32 freq;
const guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0}; guint64 rnd;
guint32 freq = 0; guint i;
guint l;
g_assert(ap); nm_assert(ap);
nm_assert(NM_IN_STRSET(band, NULL, "a", "bg"));
if (nm_wifi_ap_get_freq(ap)) if (nm_wifi_ap_get_freq(ap))
return; return;
if (g_strcmp0(band, "a") == 0) {
freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device), GBytes *ssid;
nm_device_get_ifindex(device), gsize ssid_len;
a_freqs); const guint8 *ssid_data;
else const guint8 random_seed[16] = {0x9a,
freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device), 0xdc,
nm_device_get_ifindex(device), 0x86,
bg_freqs); 0x9a,
0xa8,
0xa2,
0x07,
0x97,
0xbe,
0x6d,
0xe6,
0x99,
0x9f,
0xa8,
0x09,
0x2b};
if (!freq) /* Calculate a stable "random" number based on the SSID. */
freq = (g_strcmp0(band, "a") == 0) ? 5180 : 2462; ssid = nm_setting_wireless_get_ssid(s_wifi);
ssid_data = g_bytes_get_data(ssid, &ssid_len);
rnd = c_siphash_hash(random_seed, ssid_data, ssid_len);
}
if (nm_streq0(band, "a")) {
rnd_freqs = a_freqs;
rnd_freqs_len = G_N_ELEMENTS(a_freqs) - 1;
} else {
rnd_freqs = bg_freqs;
rnd_freqs_len = G_N_ELEMENTS(bg_freqs) - 1;
}
/* shuffle the frequencies (inplace). The idea is to choose
* a different frequency depending on the SSID. */
for (i = 0, l = rnd_freqs_len; l > 1; i++, l--) {
/* Add an arbitrary chosen (prime) number to rnd, to get more "random"
* numbers. Since we only shuffle a handful of elements, that's good
* enough (and stable). */
rnd += 5630246189u;
NM_SWAP(&rnd_freqs[i], &rnd_freqs[i + (rnd % l)]);
}
freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device),
nm_device_get_ifindex(device),
rnd_freqs);
if (freq == 0)
freq = rnd_freqs[0];
_LOGD(LOGD_WIFI, "set frequency for hotspot AP to %u", freq);
if (nm_wifi_ap_set_freq(ap, freq)) if (nm_wifi_ap_set_freq(ap, freq))
_ap_dump(self, LOGL_DEBUG, ap, "updated", 0); _ap_dump(self, LOGL_DEBUG, ap, "updated", 0);

View File

@@ -384,8 +384,10 @@ wifi_nl80211_find_freq(NMWifiUtils *data, const guint32 *freqs)
int i; int i;
int j; int j;
for (i = 0; i < self->num_freqs; i++) { /* It's important to check the values in the order of @freqs, because
* that array might be sorted to contain preferred frequencies first. */
for (j = 0; freqs[j] != 0; j++) { for (j = 0; freqs[j] != 0; j++) {
for (i = 0; i < self->num_freqs; i++) {
if (self->freqs[i] == freqs[j]) if (self->freqs[i] == freqs[j])
return freqs[j]; return freqs[j];
} }

View File

@@ -255,8 +255,10 @@ wifi_wext_find_freq(NMWifiUtils *data, const guint32 *freqs)
guint i; guint i;
guint j; guint j;
for (i = 0; i < wext->num_freqs; i++) { /* It's important to check the values in the order of @freqs, because
* that array might be sorted to contain preferred frequencies first. */
for (j = 0; freqs[j] != 0; j++) { for (j = 0; freqs[j] != 0; j++) {
for (i = 0; i < wext->num_freqs; i++) {
if (wext->freqs[i] == freqs[j]) if (wext->freqs[i] == freqs[j])
return freqs[j]; return freqs[j];
} }