summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-02-15 11:05:24 +0100
committerThomas Haller <thaller@redhat.com>2022-02-21 16:03:24 +0100
commitf18bf17deaa5ccdc445c33d7e9a0334f1de399a6 (patch)
tree1f2d4fd7bfa3e1a8c4a1341f58ad81370b0e16e4
parent4f9f0587d58261526c9650a2df4d31a1350426c0 (diff)
downloadNetworkManager-f18bf17deaa5ccdc445c33d7e9a0334f1de399a6.tar.gz
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
-rw-r--r--NEWS3
-rw-r--r--src/core/devices/wifi/nm-device-wifi.c81
-rw-r--r--src/libnm-platform/wifi/nm-wifi-utils-nl80211.c6
-rw-r--r--src/libnm-platform/wifi/nm-wifi-utils-wext.c6
4 files changed, 75 insertions, 21 deletions
diff --git a/NEWS b/NEWS
index fd150ea434..7b58fecf6e 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ subject to change and not guaranteed to be compatible with
the later release.
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
Overview of changes since NetworkManager-1.34
diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c
index cfb73848fb..314ba56688 100644
--- a/src/core/devices/wifi/nm-device-wifi.c
+++ b/src/core/devices/wifi/nm-device-wifi.c
@@ -3103,28 +3103,75 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
static void
ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP *ap)
{
- NMDevice *device = NM_DEVICE(self);
- const char *band = nm_setting_wireless_get_band(s_wifi);
- const guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0};
- const guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0};
- guint32 freq = 0;
-
- g_assert(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);
+ const char *band = nm_setting_wireless_get_band(s_wifi);
+ guint32 freq;
+ guint64 rnd;
+ guint i;
+ guint l;
+
+ nm_assert(ap);
+ nm_assert(NM_IN_STRSET(band, NULL, "a", "bg"));
if (nm_wifi_ap_get_freq(ap))
return;
- if (g_strcmp0(band, "a") == 0)
- freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device),
- nm_device_get_ifindex(device),
- a_freqs);
- else
- freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device),
- nm_device_get_ifindex(device),
- bg_freqs);
+ {
+ GBytes *ssid;
+ gsize ssid_len;
+ const guint8 *ssid_data;
+ const guint8 random_seed[16] = {0x9a,
+ 0xdc,
+ 0x86,
+ 0x9a,
+ 0xa8,
+ 0xa2,
+ 0x07,
+ 0x97,
+ 0xbe,
+ 0x6d,
+ 0xe6,
+ 0x99,
+ 0x9f,
+ 0xa8,
+ 0x09,
+ 0x2b};
+
+ /* Calculate a stable "random" number based on the SSID. */
+ 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];
- if (!freq)
- freq = (g_strcmp0(band, "a") == 0) ? 5180 : 2462;
+ _LOGD(LOGD_WIFI, "set frequency for hotspot AP to %u", freq);
if (nm_wifi_ap_set_freq(ap, freq))
_ap_dump(self, LOGL_DEBUG, ap, "updated", 0);
diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c
index 3906384b13..2659414e11 100644
--- a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c
+++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c
@@ -384,8 +384,10 @@ wifi_nl80211_find_freq(NMWifiUtils *data, const guint32 *freqs)
int i;
int j;
- for (i = 0; i < self->num_freqs; i++) {
- for (j = 0; freqs[j] != 0; j++) {
+ /* 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 (i = 0; i < self->num_freqs; i++) {
if (self->freqs[i] == freqs[j])
return freqs[j];
}
diff --git a/src/libnm-platform/wifi/nm-wifi-utils-wext.c b/src/libnm-platform/wifi/nm-wifi-utils-wext.c
index 8d0e6ed04a..678d71fe60 100644
--- a/src/libnm-platform/wifi/nm-wifi-utils-wext.c
+++ b/src/libnm-platform/wifi/nm-wifi-utils-wext.c
@@ -255,8 +255,10 @@ wifi_wext_find_freq(NMWifiUtils *data, const guint32 *freqs)
guint i;
guint j;
- for (i = 0; i < wext->num_freqs; i++) {
- for (j = 0; freqs[j] != 0; j++) {
+ /* 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 (i = 0; i < wext->num_freqs; i++) {
if (wext->freqs[i] == freqs[j])
return freqs[j];
}