-From 91976250359b263a44861aebe553b20627fe487e Mon Sep 17 00:00:00 2001
+From 7f8ac02e8524633d92941f7934440c19f1002616 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:17 +0200
-Subject: [PATCH 01/19] HE/VHT: fix frequency setup with HE enabled
+Subject: HE/VHT: Fix frequency setup with HE enabled
-Some places in the code base were not using the
-wrappers like hostapd_set_oper_centr_freq_seg0_idx
-and friends. This could lead to errors, for example when
-joining 80 MHz mesh networks. Fix this, by enforcing
-usage of these wrappers.
+Some places in the code base were not using the wrappers like
+hostapd_set_oper_centr_freq_seg0_idx and friends. This could lead to
+errors, for example when joining 80 MHz mesh networks. Fix this, by
+enforcing usage of these wrappers.
-wpa_supplicant_conf_ap_ht now checks for HE capability
-before dealing with VHT in order for these wrappers to work,
-as they first check HE support in the config.
+wpa_supplicant_conf_ap_ht() now checks for HE capability before dealing
+with VHT in order for these wrappers to work, as they first check HE
+support in the config.
-While doing these changes, I've noticed that the extra
-channel setup code for mesh networks in wpa_supplicant/mesh.c
-should not be necessary anymore and dropped it.
-wpa_supplicant_conf_ap_ht should handle this setup already.
+While doing these changes, I've noticed that the extra channel setup
+code for mesh networks in wpa_supplicant/mesh.c should not be necessary
+anymore and dropped it. wpa_supplicant_conf_ap_ht() should handle this
+setup already.
Acked-by: John Crispin <john@phrozen.org>
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
- conf->vht_oper_centr_freq_seg0_idx =
- conf->channel + conf->secondary_channel * 2;
- conf->vht_oper_chwidth = CHANWIDTH_USE_HT;
-+ hostapd_set_oper_centr_freq_seg0_idx(conf,
-+ conf->channel + conf->secondary_channel * 2);
++ hostapd_set_oper_centr_freq_seg0_idx(
++ conf, conf->channel + conf->secondary_channel * 2);
+ hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
}
-From d869c753b79a1423c2bd9b0afdfa0d89d55a930c Mon Sep 17 00:00:00 2001
+From 93da12fd9ff7596f057ddd3f0e67210960fe6a90 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:18 +0200
-Subject: [PATCH 02/19] mesh: fix channel init order, disable pri/sec channel
- switch
+Subject: mesh: Fix channel init order, disable pri/sec channel switch
-wpa_supplicant_conf_ap_ht has to happen before hostapd_setup_interface
-in order for its configuration settings to have effect on interface
-configuration.
+wpa_supplicant_conf_ap_ht() has to happen before
+hostapd_setup_interface() in order for its configuration settings to
+have effect on interface configuration.
Disable primary and secondary channel switch because of missing tie
breaking rule/frames in mesh networks. A rather long comment about
this issue is placed in mesh.c in the corresponding place.
-In consequence, remove mesh coex test, which contradicts this change.
-
I was not able to reproduce the memory corruption during
-mesh_secure_ocv_mix_legacy, which lead to a revert of a similar patch
-in the past.
+mesh_secure_ocv_mix_legacy, which lead to a revert of a similar patch in
+the past.
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- tests/hwsim/test_wpas_mesh.py | 50 -----------------------------------
- wpa_supplicant/mesh.c | 25 ++++++++++++++++--
- 2 files changed, 23 insertions(+), 52 deletions(-)
+ wpa_supplicant/mesh.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
---- a/tests/hwsim/test_wpas_mesh.py
-+++ b/tests/hwsim/test_wpas_mesh.py
-@@ -933,56 +933,6 @@ def _test_wpas_mesh_open_5ghz(dev, apdev
- dev[0].dump_monitor()
- dev[1].dump_monitor()
-
--def test_wpas_mesh_open_5ghz_coex(dev, apdev):
-- """Mesh network on 5 GHz band and 20/40 coex change"""
-- try:
-- _test_wpas_mesh_open_5ghz_coex(dev, apdev)
-- finally:
-- dev[0].request("MESH_GROUP_REMOVE " + dev[0].ifname)
-- dev[1].request("MESH_GROUP_REMOVE " + dev[1].ifname)
-- set_world_reg(apdev0=apdev[0], dev0=dev[0])
-- dev[0].flush_scan_cache()
-- dev[1].flush_scan_cache()
--
--def _test_wpas_mesh_open_5ghz_coex(dev, apdev):
-- check_mesh_support(dev[0])
-- subprocess.call(['iw', 'reg', 'set', 'US'])
--
-- # Start a 20 MHz BSS on channel 40 that would be the secondary channel of
-- # HT40+ mesh on channel 36.
-- params = {"ssid": "test-ht40",
-- "hw_mode": "a",
-- "channel": "40",
-- "country_code": "US"}
-- hapd = hostapd.add_ap(apdev[0], params)
-- bssid = hapd.own_addr()
--
-- for i in range(2):
-- for j in range(5):
-- ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5)
-- if ev is None:
-- raise Exception("No regdom change event")
-- if "alpha2=US" in ev:
-- break
-- dev[i].scan_for_bss(bssid, freq=5200)
-- add_open_mesh_network(dev[i], freq="5180")
--
-- check_mesh_joined_connected(dev)
--
-- freq = dev[0].get_status_field("freq")
-- if freq != "5200":
-- raise Exception("Unexpected STATUS freq=" + freq)
-- sig = dev[0].request("SIGNAL_POLL").splitlines()
-- if "FREQUENCY=5200" not in sig:
-- raise Exception("Unexpected SIGNAL_POLL output: " + str(sig))
--
-- hapd.disable()
-- dev[0].mesh_group_remove()
-- dev[1].mesh_group_remove()
-- check_mesh_group_removed(dev[0])
-- check_mesh_group_removed(dev[1])
-- dev[0].dump_monitor()
-- dev[1].dump_monitor()
-
- def test_wpas_mesh_open_ht40(dev, apdev):
- """Mesh and HT40 support difference"""
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -363,6 +363,29 @@ static int wpa_supplicant_mesh_init(stru
+@@ -363,6 +363,31 @@ static int wpa_supplicant_mesh_init(stru
conf->basic_rates[rate_len] = -1;
}
+ /* While it can enhance performance to switch the primary channel, which
+ * is also the secondary channel of another network at the same time),
-+ * to the other primary channel, problems exist with this in mesh networks.
++ * to the other primary channel, problems exist with this in mesh
++ * networks.
+ *
+ * Example with problems:
+ * - 3 mesh nodes M1-M3, freq (5200, 5180)
+ * - other node O1, e.g. AP mode, freq (5180, 5200),
+ * Locations: O1 M1 M2 M3
+ *
-+ * M3 can only send frames to M1 over M2, no direct connection is possible
-+ * Start O1, M1 and M3 first, M1 or O1 will switch channels to align with
-+ * each other. M3 does not swap, because M1 or O1 cannot be reached.
-+ * M2 is started afterwards and can either connect to M3 or M1 because of
-+ * this primary secondary channel switch.
++ * M3 can only send frames to M1 over M2, no direct connection is
++ * possible
++ * Start O1, M1 and M3 first, M1 or O1 will switch channels to align
++ * with* each other. M3 does not swap, because M1 or O1 cannot be
++ * reached. M2 is started afterwards and can either connect to M3 or M1
++ * because of this primary secondary channel switch.
+ *
+ * Solutions: (1) central coordination -> not always possible
+ * (2) disable pri/sec channel switch in mesh networks
+ *
-+ * In AP mode, when all nodes can work independently, this poses of course
-+ * no problem, therefore disable it only in mesh mode.`*/
++ * In AP mode, when all nodes can work independently, this poses of
++ * course no problem, therefore disable it only in mesh mode. */
+ conf->no_pri_sec_switch = 1;
+ wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
+
if (wpa_drv_init_mesh(wpa_s)) {
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
return -1;
-@@ -374,8 +397,6 @@ static int wpa_supplicant_mesh_init(stru
+@@ -374,8 +399,6 @@ static int wpa_supplicant_mesh_init(stru
return -1;
}
-From 978a59514ccde994b5c06e1cbb49cc8cebe6381c Mon Sep 17 00:00:00 2001
+From df6745e8c8c1312d41f3e7fd044f438408526a2b Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:19 +0200
-Subject: [PATCH 03/19] wpa_supplicant: handle HT40 and mode downgrade in AP
- mode
+Subject: wpa_supplicant: Handle HT40 and mode downgrade in AP mode
-This patch adds some missing pieces to the interface configuration
-of AP/mesh mode in wpa_supplicant.
+Add some missing pieces to the interface configuration of AP/mesh mode
+in wpa_supplicant.
- check for secondary channel and HT40 capability
- - try to downgrade to 11b if 11g is not available
+ - try to downgrade to IEEE 802.11b if 802.11g is not available
Especially with the HT40 check, this code now performs all settings,
which the deleted/duplicated mesh code did.
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- wpa_supplicant/ap.c | 49 ++++++++++++++++++++++++++++++++++++---------
- 1 file changed, 40 insertions(+), 9 deletions(-)
+ wpa_supplicant/ap.c | 52 +++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 43 insertions(+), 9 deletions(-)
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
-@@ -134,6 +134,23 @@ no_vht:
+@@ -134,6 +134,24 @@ no_vht:
}
-+static struct hostapd_hw_modes *wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
-+ enum hostapd_hw_mode hw_mode)
++static struct hostapd_hw_modes *
++wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
++ enum hostapd_hw_mode hw_mode)
+{
+ struct hostapd_hw_modes *mode = NULL;
+ int i;
int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
struct hostapd_config *conf)
-@@ -147,9 +164,6 @@ int wpa_supplicant_conf_ap_ht(struct wpa
+@@ -147,9 +165,6 @@ int wpa_supplicant_conf_ap_ht(struct wpa
return -1;
}
/*
* Enable HT20 if the driver supports it, by setting conf->ieee80211n
* and a mask of allowed capabilities within conf->ht_capab.
-@@ -158,17 +172,27 @@ int wpa_supplicant_conf_ap_ht(struct wpa
+@@ -158,17 +173,28 @@ int wpa_supplicant_conf_ap_ht(struct wpa
*/
if (wpa_s->hw.modes) {
struct hostapd_hw_modes *mode = NULL;
- }
+ mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
+
-+ /* may drop drop to 11b if driver does not support 11g */
++ /* May drop to IEEE 802.11b if the driver does not support IEEE
++ * 802.11g */
+ if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
+ conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
+ wpa_printf(MSG_INFO,
-+ "Try downgrade to IEEE 802.11b as 802.11g is not "
-+ "supported by the current hardware");
-+ mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
++ "Try downgrade to IEEE 802.11b as 802.11g is not supported by the current hardware");
++ mode = wpa_supplicant_find_hw_mode(wpa_s,
++ conf->hw_mode);
+ }
+
+ if (!mode) {
+ wpa_printf(MSG_ERROR,
-+ "No match between requested and supported hw modes found");
++ "No match between requested and supported hw modes found");
+ return -1;
}
#ifdef CONFIG_HT_OVERRIDES
-@@ -193,6 +217,13 @@ int wpa_supplicant_conf_ap_ht(struct wpa
+@@ -193,6 +219,14 @@ int wpa_supplicant_conf_ap_ht(struct wpa
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
ssid->ht40);
conf->ieee80211n = 1;
+
+ if (ssid->ht40 &&
-+ mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
++ (mode->ht_capab &
++ HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
+ conf->secondary_channel = ssid->ht40;
+ else
+ conf->secondary_channel = 0;
-From 7f7325dae1d03a3964d4e91940d8369f3fed7b43 Mon Sep 17 00:00:00 2001
+From d34b33451c83414d690661905f14cf585fb10ccd Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
-Date: Tue, 30 Jun 2020 13:53:20 +0200
-Subject: [PATCH 04/19] wpa_supplicant: fix frequency config for non p2p vht/he
- cases
+Date: Wed, 14 Oct 2020 21:31:15 +0200
+Subject: wpa_supplicant: Fix frequency config for VHT/HE cases
-Fix compile without CONFIG_P2P and only set secondary channel seg idx
-if we use a mode supporting a sec channel for vht/he.
+Fix compilation without CONFIG_P2P and only set secondary channel seg
+idx if we use a mode supporting a sec channel for VHT/HE.
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- wpa_supplicant/ap.c | 23 +++++++++++++----------
- 1 file changed, 13 insertions(+), 10 deletions(-)
+ wpa_supplicant/ap.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
if (!conf->secondary_channel)
goto no_vht;
-@@ -62,24 +62,27 @@ static void wpas_conf_ap_vht(struct wpa_
+@@ -62,24 +62,28 @@ static void wpas_conf_ap_vht(struct wpa_
if (ssid->max_oper_chwidth)
hostapd_set_oper_chwidth(conf, ssid->max_oper_chwidth);
- ieee80211_freq_to_chan(ssid->vht_center_freq2,
- &freq_seg_idx);
- hostapd_set_oper_centr_freq_seg1_idx(conf, freq_seg_idx);
--
++ if (hostapd_get_oper_chwidth(conf) == CHANWIDTH_80P80MHZ) {
++ ieee80211_freq_to_chan(ssid->vht_center_freq2,
++ &freq_seg_idx);
++ hostapd_set_oper_centr_freq_seg1_idx(conf, freq_seg_idx);
++ }
+
if (!ssid->p2p_group) {
- if (!ssid->vht_center_freq1 ||
- hostapd_get_oper_chwidth(conf) == CHANWIDTH_USE_HT)
- wpa_printf(MSG_DEBUG, "VHT seg0 index %d for AP",
- hostapd_get_oper_centr_freq_seg0_idx(conf));
+
-+ if (hostapd_get_oper_chwidth(conf) == CHANWIDTH_80P80MHZ) {
-+ ieee80211_freq_to_chan(ssid->vht_center_freq2,
-+ &freq_seg_idx);
-+ hostapd_set_oper_centr_freq_seg1_idx(conf, freq_seg_idx);
-+ }
-+
-+ wpa_printf(MSG_DEBUG, "VHT seg0 index %d and seg1 index %d for AP",
++ wpa_printf(MSG_DEBUG,
++ "VHT seg0 index %d and seg1 index %d for AP",
+ hostapd_get_oper_centr_freq_seg0_idx(conf),
+ hostapd_get_oper_centr_freq_seg1_idx(conf));
return;
-From ff7fb3fa0831c8521327d777c5607a3b7d8736b8 Mon Sep 17 00:00:00 2001
+From 5965c7da5d6d0b81ef32cd19d9f69efcd9e0aa5c Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:21 +0200
-Subject: [PATCH 05/19] wpa_supplicant: enable vht and he in default config
- parameters
+Subject: wpa_supplicant: Enable VHT and HE in default config parameters
Enable VHT and HE as default config parameters in order for
wpa_supplicant AP mode to use it, if hw support is given.
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- wpa_supplicant/config.c | 2 ++
- 1 file changed, 2 insertions(+)
+ wpa_supplicant/config.c | 2 ++
+ wpa_supplicant/config_file.c | 3 ++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
#ifdef IEEE8021X_EAPOL
ssid->eapol_flags = DEFAULT_EAPOL_FLAGS;
ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
+--- a/wpa_supplicant/config_file.c
++++ b/wpa_supplicant/config_file.c
+@@ -876,9 +876,10 @@ static void wpa_config_write_network(FIL
+ write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1);
+ INT(disabled);
+ INT(mixed_cell);
+- INT(vht);
++ INT_DEF(vht, 1);
+ INT_DEF(ht, 1);
+ INT(ht40);
++ INT_DEF(he, 1);
+ INT_DEF(max_oper_chwidth, DEFAULT_MAX_OPER_CHWIDTH);
+ INT(vht_center_freq1);
+ INT(vht_center_freq2);
-From 6522dcbbcf71abcb80cce84b93b4a9a5cfcd4fca Mon Sep 17 00:00:00 2001
+From a72599b319ab0e17ebdf3415b45d6deb405c3a84 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:22 +0200
-Subject: [PATCH 06/19] hw_features: better debug messages for some error cases
+Subject: hw_features: Better debug messages for some error cases
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- src/common/hw_features_common.c | 29 ++++++++++++++++++++++-------
- 1 file changed, 22 insertions(+), 7 deletions(-)
+ src/common/hw_features_common.c | 36 ++++++++++++++++++++++++++-------
+ 1 file changed, 29 insertions(+), 7 deletions(-)
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
-@@ -540,13 +540,18 @@ int hostapd_set_freq_params(struct hosta
+@@ -540,13 +540,20 @@ int hostapd_set_freq_params(struct hosta
if (center_segment1 ||
(center_segment0 != 0 &&
5000 + center_segment0 * 5 != data->center_freq1 &&
- 2407 + center_segment0 * 5 != data->center_freq1))
+ 2407 + center_segment0 * 5 != data->center_freq1)) {
-+ wpa_printf(MSG_ERROR, "20/40 MHz: center segment 0 (=%i) and center freq 1 (=%i) not in sync",
++ wpa_printf(MSG_ERROR,
++ "20/40 MHz: center segment 0 (=%d) and center freq 1 (=%d) not in sync",
+ center_segment0, data->center_freq1);
return -1;
+ }
if (center_segment1 == center_segment0 + 4 ||
- center_segment1 == center_segment0 - 4)
+ center_segment1 == center_segment0 - 4) {
-+ wpa_printf(MSG_ERROR, "80+80 MHz: center segment 1 only 20 MHz apart");
++ wpa_printf(MSG_ERROR,
++ "80+80 MHz: center segment 1 only 20 MHz apart");
return -1;
+ }
data->center_freq2 = 5000 + center_segment1 * 5;
/* fall through */
case CHANWIDTH_80MHZ:
-@@ -555,8 +560,10 @@ int hostapd_set_freq_params(struct hosta
+@@ -555,8 +562,11 @@ int hostapd_set_freq_params(struct hosta
center_segment1) ||
(oper_chwidth == CHANWIDTH_80P80MHZ &&
!center_segment1) ||
- !sec_channel_offset)
+ !sec_channel_offset) {
-+ wpa_printf(MSG_ERROR, "80/80+80 MHz: center segment 1 wrong or no second channel offset");
++ wpa_printf(MSG_ERROR,
++ "80/80+80 MHz: center segment 1 wrong or no second channel offset");
return -1;
+ }
if (!center_segment0) {
if (channel <= 48)
center_segment0 = 42;
-@@ -582,16 +589,22 @@ int hostapd_set_freq_params(struct hosta
+@@ -582,16 +592,25 @@ int hostapd_set_freq_params(struct hosta
center_segment0 == channel - 2 ||
center_segment0 == channel - 6)
data->center_freq1 = 5000 + center_segment0 * 5;
- else
+ else {
-+ wpa_printf(MSG_ERROR, "Wrong coupling between HT and VHT/HE channel setting");
++ wpa_printf(MSG_ERROR,
++ "Wrong coupling between HT and VHT/HE channel setting");
return -1;
+ }
}
data->bandwidth = 160;
- if (center_segment1)
+ if (center_segment1) {
-+ wpa_printf(MSG_ERROR, "160 MHz: center segment 1 should not be set");
++ wpa_printf(MSG_ERROR,
++ "160 MHz: center segment 1 should not be set");
return -1;
- if (!sec_channel_offset)
+ }
+ if (!sec_channel_offset) {
-+ wpa_printf(MSG_ERROR, "160 MHz: second channel offset not set");
++ wpa_printf(MSG_ERROR,
++ "160 MHz: second channel offset not set");
return -1;
+ }
/*
* Note: HT/VHT config and params are coupled. Check if
* HT40 channel band is in VHT160 channel band configuration.
-@@ -605,8 +618,10 @@ int hostapd_set_freq_params(struct hosta
+@@ -605,8 +624,11 @@ int hostapd_set_freq_params(struct hosta
center_segment0 == channel - 10 ||
center_segment0 == channel - 14)
data->center_freq1 = 5000 + center_segment0 * 5;
- else
+ else {
-+ wpa_printf(MSG_ERROR, "160 MHz: HT40 channel band is not in 160 MHz band");
++ wpa_printf(MSG_ERROR,
++ "160 MHz: HT40 channel band is not in 160 MHz band");
return -1;
+ }
break;
-From 6eacc14904b6f09a1490e697c01adf5dc56c4905 Mon Sep 17 00:00:00 2001
+From c3f37c35f0ef02bd88ce4faf25a466e52e7a64f8 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:23 +0200
-Subject: [PATCH 07/19] dfs: use helper functions for vht/he parameters
+Subject: DFS: Use helper functions for VHT/HE parameters
+
+This is needed to cover the HE-specific conf->he_oper_chwidth value in
+addition to conf->vht_oper_chwidth.
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- src/ap/dfs.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
+ src/ap/dfs.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
-@@ -955,10 +955,12 @@ dfs_downgrade_bandwidth(struct hostapd_i
+@@ -955,10 +955,13 @@ dfs_downgrade_bandwidth(struct hostapd_i
if (*skip_radar) {
*skip_radar = 0;
} else {
- if (iface->conf->vht_oper_chwidth == CHANWIDTH_USE_HT)
-+ int oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
++ int oper_chwidth;
+
++ oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
+ if (oper_chwidth == CHANWIDTH_USE_HT)
break;
*skip_radar = 1;
-From 11e5bbe58eebdb10793eec374b6c8ccc7daf7ec8 Mon Sep 17 00:00:00 2001
+From f1df4fbfc7ad3d8c18a8c9fe5c71628f2ed09bb7 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
Date: Tue, 30 Jun 2020 14:18:56 +0200
-Subject: [PATCH 08/19] mesh: use setup completion callback to complete mesh
- join
+Subject: mesh: Use setup completion callback to complete mesh join
-mesh join function is the last function to be called during
-mesh join process, but it's been called a bit earlier than
-it's supposed to be, so that some mesh parameter values
-such as VHT capabilities not applied correct when mesh join
-is in process.
-Moreover current design of mesh join that is called directly
-after mesh initialization isn't suitable for DFS channels to use,
-since mesh join process should be paused until DFS CAC is
-done and resumed after it's done.
-The callback will be called by hostapd_setup_interface_complete_sync.
-There is possiblity that completing mesh init fails, so add error
-handle codes.
+Mesh join function is the last function to be called during mesh join
+process, but it's been called a bit earlier than it's supposed to be, so
+that some mesh parameter values such as VHT capabilities were not
+applied correct when mesh join is in process. Moreover, the current
+design of mesh join that is called directly after mesh initialization
+isn't suitable for DFS channels to use, since mesh join process should
+be paused until DFS CAC is done and resumed after it's done.
+
+The callback will be called by hostapd_setup_interface_complete_sync().
+There is a possibility that completing mesh init fails, so add error
+handling codes for that.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
src/ap/hostapd.c | 11 ++++++++++-
- wpa_supplicant/mesh.c | 12 ++++++++++--
- 2 files changed, 20 insertions(+), 3 deletions(-)
+ wpa_supplicant/mesh.c | 12 +++++++++++-
+ 2 files changed, 21 insertions(+), 2 deletions(-)
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
+#ifdef CONFIG_MESH
-+ if (delay_apply_cfg && iface->mconf == NULL) {
++ if (delay_apply_cfg && !iface->mconf) {
+ wpa_printf(MSG_ERROR, "Error while completing mesh init");
+ goto fail;
+ }
if (ret) {
wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
- iface->bss[0]->conf->iface);
-+ iface->conf ? iface->conf->bss[0]->iface : "N/A");
++ iface->conf ? iface->conf->bss[0]->iface : "N/A");
return -1;
}
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -193,7 +193,6 @@ static int wpas_mesh_init_rsn(struct wpa
- return !wpa_s->mesh_rsn ? -1 : 0;
- }
-
--
- static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
- {
- struct hostapd_iface *ifmsh = wpa_s->ifmsh;
-@@ -244,6 +243,13 @@ static int wpas_mesh_complete(struct wpa
+@@ -244,6 +244,14 @@ static int wpas_mesh_complete(struct wpa
}
+static void wpas_mesh_complete_cb(void *arg)
+{
+ struct wpa_supplicant *wpa_s = arg;
++
+ wpas_mesh_complete(wpa_s);
+}
+
static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
struct hostapd_freq_params *freq)
-@@ -267,6 +273,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -267,6 +275,7 @@ static int wpa_supplicant_mesh_init(stru
if (!ifmsh)
return -ENOMEM;
ifmsh->drv_flags = wpa_s->drv_flags;
ifmsh->drv_flags2 = wpa_s->drv_flags2;
ifmsh->num_bss = 1;
-@@ -285,6 +292,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -285,6 +294,8 @@ static int wpa_supplicant_mesh_init(stru
bss->drv_priv = wpa_s->drv_priv;
bss->iface = ifmsh;
bss->mesh_sta_free_cb = mesh_mpm_free_sta;
frequency = ssid->frequency;
if (frequency != freq->freq &&
frequency == freq->freq + freq->sec_channel_offset * 20) {
-@@ -523,7 +532,6 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -525,7 +536,6 @@ int wpa_supplicant_join_mesh(struct wpa_
goto out;
}
-From 87c5e8883898e7eb8e9637e212350c1925a22654 Mon Sep 17 00:00:00 2001
+From e3608040c4ebf7c5a5d6b6fd4ca2a4d2143df4cc Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
Date: Tue, 30 Jun 2020 14:18:57 +0200
-Subject: [PATCH 09/19] mesh: update ssid->frequency as pri/sec channel switch
+Subject: mesh: Update ssid->frequency as pri/sec channels switch
-ssid->frequency is one of variables used to gets channel
-number from given frequency. Leave it as unchanged when
-pri/sec channel switched will cause picking up wrong
-channel number after applying secondary channel offset
-for HT40 and leads failing interface bring-up.
+ssid->frequency is one of the variables used to get the channel number
+from a given frequency. Leaving it as unchanged when pri/sec channel
+switch will cause picking up a wrong channel number after applying the
+secondary channel offset for HT40 and leads to failing interface
+bring-up.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -299,6 +299,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -301,6 +301,7 @@ static int wpa_supplicant_mesh_init(stru
frequency == freq->freq + freq->sec_channel_offset * 20) {
wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
frequency = freq->freq;
-From af8dcbc87466ed6472850a4f1cfe252652cb3d26 Mon Sep 17 00:00:00 2001
+From 8725909789555e549d92b1f8f582fa63adb390a5 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
Date: Tue, 30 Jun 2020 14:18:59 +0200
-Subject: [PATCH 11/19] mesh: do not set offchanok on DFS channels in non-ETSI
+Subject: nl80211: Do not set offchanok on DFS channels in non-ETSI for mesh
mac80211 does not allow mgmt tx to use off channel on
DFS channels in non-ETSI domain, because it will invalidate
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
- src/drivers/driver_nl80211.c | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
+ src/drivers/driver_nl80211.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -7788,7 +7788,11 @@ static int wpa_driver_nl80211_send_actio
- int ret = -1;
- u8 *buf;
- struct ieee80211_hdr *hdr;
-+ struct hostapd_hw_modes *modes;
- int offchanok = 1;
-+ u16 num_modes, flags;
-+ u8 dfs_domain;
-+ int i;
-
- if (is_ap_interface(drv->nlmode) && (int) freq == bss->freq &&
- bss->beacon_set)
-@@ -7817,6 +7821,21 @@ static int wpa_driver_nl80211_send_actio
+@@ -7817,6 +7817,28 @@ static int wpa_driver_nl80211_send_actio
os_memset(bss->rand_addr, 0, ETH_ALEN);
}
++#ifdef CONFIG_MESH
+ if (is_mesh_interface(drv->nlmode)) {
++ struct hostapd_hw_modes *modes;
++ u16 num_modes, flags;
++ u8 dfs_domain;
++ int i;
++
+ modes = nl80211_get_hw_feature_data(bss, &num_modes,
+ &flags, &dfs_domain);
+ if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
+ os_free(modes);
+ }
+ }
++#endif /* CONFIG_MESH */
+
if (is_ap_interface(drv->nlmode) &&
(!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
-From ab6995f15aae17af93507dd2344615f91672a31a Mon Sep 17 00:00:00 2001
+From a27faf2c9a0c07f6a74420824b941cdc91c33b45 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
Date: Tue, 30 Jun 2020 14:19:00 +0200
-Subject: [PATCH 12/19] mesh: fix channel switch error during CAC
+Subject: mesh: Fix channel switch error during CAC
-Mesh interface has used its channel parameters that configured
-during its initialization even after channel switched due to
-DFS radar detection during CAC which caused channel switch error.
-This change fixes the error by updating its channel parameters
-when channel's been changed from initial one.
+Mesh interface would have used its channel parameters that were
+configured during initialization even after channel switch due to DFS
+radar detection during CAC which could result in a channel switch error.
+Fix the error by updating the channel parameters when channel has been
+changed from the initial one.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
- wpa_supplicant/mesh.c | 34 ++++++++++++++++++++++++++++++++++
- 1 file changed, 34 insertions(+)
+ wpa_supplicant/mesh.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
#include "ap/sta_info.h"
#include "ap/hostapd.h"
#include "ap/ieee802_11.h"
-@@ -206,6 +207,39 @@ static int wpas_mesh_complete(struct wpa
+@@ -207,6 +208,43 @@ static int wpas_mesh_complete(struct wpa
return -1;
}
+ /*
-+ * inspect if channel's been changed since initialized.
-+ * i.e. DFS radar detection
++ * Update channel configuration if the channel has changed since the
++ * initial setting, i.e., due to DFS radar detection during CAC.
+ */
+ if (ifmsh->freq != params->freq.freq) {
++ struct he_capabilities *he_capab = NULL;
++
+ wpa_s->assoc_freq = ifmsh->freq;
+ ssid->frequency = ifmsh->freq;
-+ struct he_capabilities *he_capab = NULL;
+
+ if (ifmsh->current_mode)
-+ he_capab = &ifmsh->current_mode->he_capab[IEEE80211_MODE_MESH];
++ he_capab = &ifmsh->current_mode->he_capab[
++ IEEE80211_MODE_MESH];
+
-+ if (hostapd_set_freq_params(¶ms->freq,
-+ ifmsh->conf->hw_mode,
-+ ifmsh->freq,
-+ ifmsh->conf->channel,
-+ ifmsh->conf->enable_edmg,
-+ ifmsh->conf->edmg_channel,
-+ ifmsh->conf->ieee80211n,
-+ ifmsh->conf->ieee80211ac,
-+ ifmsh->conf->ieee80211ax,
-+ ifmsh->conf->secondary_channel,
-+ hostapd_get_oper_chwidth(ifmsh->conf),
-+ hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
-+ hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
-+ ifmsh->conf->vht_capab,
-+ he_capab)) {
-+ wpa_printf(MSG_ERROR, "Error updating mesh frequency params.");
++ if (hostapd_set_freq_params(
++ ¶ms->freq,
++ ifmsh->conf->hw_mode,
++ ifmsh->freq,
++ ifmsh->conf->channel,
++ ifmsh->conf->enable_edmg,
++ ifmsh->conf->edmg_channel,
++ ifmsh->conf->ieee80211n,
++ ifmsh->conf->ieee80211ac,
++ ifmsh->conf->ieee80211ax,
++ ifmsh->conf->secondary_channel,
++ hostapd_get_oper_chwidth(ifmsh->conf),
++ hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
++ hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
++ ifmsh->conf->vht_capab,
++ he_capab)) {
++ wpa_printf(MSG_ERROR,
++ "Error updating mesh frequency params");
+ wpa_supplicant_mesh_deinit(wpa_s);
+ return -1;
+ }
-From f1118eca5b1a63a4acb2a11ceea15dc4bc259c77 Mon Sep 17 00:00:00 2001
+From 12ae3e3dba0e0826a4b181e1e5f1f9fd8708845c Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
Date: Tue, 30 Jun 2020 14:19:01 +0200
-Subject: [PATCH 13/19] mesh: inform kernel driver DFS handler in userspace
+Subject: mesh: Inform kernel driver about DFS handler in userspace
-NL80211_ATTR_HANDLE_DFS is required by kerenel space
-to enable DFS channels that indicates DFS handler
-resides in userspace.
+The kernel requires indication of DFS handler residing in user space
+(NL80211_ATTR_HANDLE_DFS) to enable DFS channels.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
#define WPA_DRIVER_MESH_FLAG_SAE_AUTH 0x00000004
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
unsigned int flags;
-+ u8 handle_dfs;
++ bool handle_dfs;
};
struct wpa_driver_set_key_params {
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -10070,6 +10070,9 @@ static int nl80211_join_mesh(struct i802
+@@ -10073,6 +10073,9 @@ static int nl80211_join_mesh(struct i802
wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags);
-+ if (params->handle_dfs)
-+ if (nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS))
-+ goto fail;
++ if (params->handle_dfs && nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS))
++ goto fail;
++
container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP);
if (!container)
goto fail;
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -355,6 +355,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -361,6 +361,7 @@ static int wpa_supplicant_mesh_init(stru
conf->country[0] = wpa_s->conf->country[0];
conf->country[1] = wpa_s->conf->country[1];
conf->country[2] = ' ';
-+ wpa_s->mesh_params->handle_dfs = 1;
++ wpa_s->mesh_params->handle_dfs = true;
}
bss->iconf = conf;
-From 30bdefd7559d57eae8c3c7e6f721ecf7be929bf2 Mon Sep 17 00:00:00 2001
+From 0896c442dcd5477ac8c49036c089f728f703df88 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 14:19:02 +0200
-Subject: [PATCH 14/19] mesh: fixes for mesh init/deinit
+Subject: mesh: Fix for mesh init/deinit
Send mesh group started notification after join completion
callback is called.
}
-@@ -244,8 +246,7 @@ static int wpas_mesh_complete(struct wpa
+@@ -249,8 +251,7 @@ static int wpas_mesh_complete(struct wpa
wpas_mesh_init_rsn(wpa_s)) {
wpa_printf(MSG_ERROR,
"mesh: RSN initialization failed - deinit mesh");
return -1;
}
-@@ -270,9 +271,15 @@ static int wpas_mesh_complete(struct wpa
+@@ -275,9 +276,15 @@ static int wpas_mesh_complete(struct wpa
/* hostapd sets the interface down until we associate */
wpa_drv_set_operstate(wpa_s, 1);
return ret;
}
-@@ -563,7 +570,7 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -571,7 +578,7 @@ int wpa_supplicant_join_mesh(struct wpa_
wpa_s->mesh_params = params;
if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) {
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
ret = -1;
goto out;
}
-@@ -573,14 +580,15 @@ out:
+@@ -581,14 +588,15 @@ out:
}
-From d017f5d98a143c46c3c3fcb0e6507ca0b2bebdb0 Mon Sep 17 00:00:00 2001
+From 7c2cad969a67453c35422cc6ad1d2803dc27adc1 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 14:19:03 +0200
-Subject: [PATCH 15/19] mesh: fix DFS deinit/init
+Subject: mesh: Fix DFS deinit/init
-The hostapd DFS code deinitializes and initializes the
-AP interface, if a clean channel switch is not possible.
-In this case the AP code paths would deinit the driver, for
-example nl80211, without wpa_supplicant code paths getting
-notice of this.
+The hostapd DFS code deinitializes and initializes the AP interface, if
+a clean channel switch is not possible. In this case the AP code paths
+would deinit the driver, for example nl80211, without wpa_supplicant
+code paths getting notice of this.
-Therefore add callbacks for wpa_supplicant mesh methods,
-which are called on init/deinit of the AP bss. These
-callbacks are then used to handle the reset in the mesh
-code.
+Therefore add callbacks for wpa_supplicant mesh methods, which are
+called on init/deinit of the AP BSS. These callbacks are then used to
+handle the reset in the mesh code.
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- src/ap/dfs.c | 2 +-
- src/ap/hostapd.c | 17 ++++++--
+ src/ap/dfs.c | 7 +++-
+ src/ap/hostapd.c | 15 +++++--
src/ap/hostapd.h | 6 +++
- wpa_supplicant/mesh.c | 90 +++++++++++++++++++++++++++++++++++++------
- 4 files changed, 100 insertions(+), 15 deletions(-)
+ wpa_supplicant/mesh.c | 94 ++++++++++++++++++++++++++++++++++++++-----
+ 4 files changed, 107 insertions(+), 15 deletions(-)
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
-@@ -1112,7 +1112,7 @@ static int hostapd_dfs_start_channel_swi
+@@ -1032,6 +1032,7 @@ static int hostapd_dfs_start_channel_swi
+ int err = 1;
+ struct hostapd_hw_modes *cmode = iface->current_mode;
+ u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
++ int ieee80211_mode = IEEE80211_MODE_AP;
+
+ wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
+ __func__, iface->cac_started ? "yes" : "no",
+@@ -1099,6 +1100,10 @@ static int hostapd_dfs_start_channel_swi
+ os_memset(&csa_settings, 0, sizeof(csa_settings));
+ csa_settings.cs_count = 5;
+ csa_settings.block_tx = 1;
++#ifdef CONFIG_MESH
++ if (iface->mconf)
++ ieee80211_mode = IEEE80211_MODE_MESH;
++#endif /* CONFIG_MESH */
+ err = hostapd_set_freq_params(&csa_settings.freq_params,
+ iface->conf->hw_mode,
+ channel->freq,
+@@ -1113,7 +1118,7 @@ static int hostapd_dfs_start_channel_swi
oper_centr_freq_seg0_idx,
oper_centr_freq_seg1_idx,
cmode->vht_capab,
- &cmode->he_capab[IEEE80211_MODE_AP]);
-+ &cmode->he_capab[iface->conf->hw_mode]);
++ &cmode->he_capab[ieee80211_mode]);
if (err) {
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
{
hostapd_free_stas(hapd);
hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
-@@ -2690,6 +2690,13 @@ int hostapd_enable_iface(struct hostapd_
+@@ -2690,6 +2690,12 @@ int hostapd_enable_iface(struct hostapd_
{
size_t j;
-+ if (hapd_iface == NULL)
++ if (!hapd_iface)
+ return -1;
+
-+ if (hapd_iface->enable_iface_cb != NULL) {
++ if (hapd_iface->enable_iface_cb)
+ return hapd_iface->enable_iface_cb(hapd_iface);
-+ }
+
if (hapd_iface->bss[0]->drv_priv != NULL) {
wpa_printf(MSG_ERROR, "Interface %s already enabled",
hapd_iface->conf->bss[0]->iface);
-@@ -2751,6 +2758,10 @@ int hostapd_disable_iface(struct hostapd
+@@ -2751,6 +2757,9 @@ int hostapd_disable_iface(struct hostapd
if (hapd_iface == NULL)
return -1;
-+ if (hapd_iface->disable_iface_cb != NULL) {
++ if (hapd_iface->disable_iface_cb)
+ return hapd_iface->disable_iface_cb(hapd_iface);
-+ }
+
if (hapd_iface->bss[0]->drv_priv == NULL) {
wpa_printf(MSG_INFO, "Interface %s already disabled",
void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -28,15 +28,20 @@
+@@ -28,15 +28,22 @@
#include "mesh.h"
-static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s)
-+static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s, bool also_clear_hostapd)
++static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s,
++ bool also_clear_hostapd)
{
- wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, true);
- wpa_s->ifmsh = NULL;
- wpa_s->current_ssid = NULL;
-+ wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, also_clear_hostapd);
++ wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh,
++ also_clear_hostapd);
+
+ if (also_clear_hostapd) {
+ wpa_s->ifmsh = NULL;
wpa_supplicant_leave_mesh(wpa_s, false);
}
-@@ -237,7 +242,7 @@ static int wpas_mesh_complete(struct wpa
- ifmsh->conf->vht_capab,
- he_capab)) {
- wpa_printf(MSG_ERROR, "Error updating mesh frequency params.");
+@@ -242,7 +249,7 @@ static int wpas_mesh_complete(struct wpa
+ he_capab)) {
+ wpa_printf(MSG_ERROR,
+ "Error updating mesh frequency params");
- wpa_supplicant_mesh_deinit(wpa_s);
+ wpa_supplicant_mesh_deinit(wpa_s, true);
return -1;
}
}
-@@ -246,7 +251,7 @@ static int wpas_mesh_complete(struct wpa
+@@ -251,7 +258,7 @@ static int wpas_mesh_complete(struct wpa
wpas_mesh_init_rsn(wpa_s)) {
wpa_printf(MSG_ERROR,
"mesh: RSN initialization failed - deinit mesh");
return -1;
}
-@@ -291,6 +296,67 @@ static void wpas_mesh_complete_cb(void *
+@@ -297,6 +304,69 @@ static void wpas_mesh_complete_cb(void *
}
+static int wpa_supplicant_mesh_disable_iface_cb(struct hostapd_iface *ifmsh)
+{
+ struct wpa_supplicant *wpa_s = ifmsh->owner;
-+ int j;
++ size_t j;
+
+ wpa_supplicant_mesh_deinit(wpa_s, false);
+
+ hostapd_cleanup_cs_params(ifmsh->bss[j]);
+#endif /* NEED_AP_MLME */
+
-+ /* same as hostapd_interface_deinit without deinitializing ctrl-iface */
++ /* Same as hostapd_interface_deinit() without deinitializing control
++ * interface */
+ for (j = 0; j < ifmsh->num_bss; j++) {
+ struct hostapd_data *hapd = ifmsh->bss[j];
++
+ hostapd_bss_deinit_no_free(hapd);
+ hostapd_free_hapd_data(hapd);
+ }
static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
struct hostapd_freq_params *freq)
-@@ -318,6 +384,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -324,6 +394,8 @@ static int wpa_supplicant_mesh_init(stru
ifmsh->drv_flags = wpa_s->drv_flags;
ifmsh->drv_flags2 = wpa_s->drv_flags2;
ifmsh->num_bss = 1;
ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
sizeof(struct hostapd_data *));
if (!ifmsh->bss)
-@@ -451,7 +519,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -459,7 +531,7 @@ static int wpa_supplicant_mesh_init(stru
return 0;
out_free:
return -ENOMEM;
}
-@@ -499,7 +567,7 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -507,7 +579,7 @@ int wpa_supplicant_join_mesh(struct wpa_
goto out;
}
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
wpa_s->group_cipher = WPA_CIPHER_NONE;
-@@ -588,7 +656,7 @@ int wpa_supplicant_leave_mesh(struct wpa
+@@ -596,7 +668,7 @@ int wpa_supplicant_leave_mesh(struct wpa
/* Need to send peering close messages first */
if (need_deinit)
-From 928da9a270deaf4409aee4d87a33a6f61b56c136 Mon Sep 17 00:00:00 2001
+From 06161d4f108905d10c63060c82973ad70a844247 Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 14:19:05 +0200
-Subject: [PATCH 17/19] mesh: fix mesh_oom test
+Subject: mesh: Fix mesh_oom test
Only change freq params, if ifmsh->freq is set initially, which only
happens if hostapd_get_hw_features in setup_interface2 succeeds.
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -218,7 +218,7 @@ static int wpas_mesh_complete(struct wpa
- * inspect if channel's been changed since initialized.
- * i.e. DFS radar detection
+@@ -221,7 +221,7 @@ static int wpas_mesh_complete(struct wpa
+ * Update channel configuration if the channel has changed since the
+ * initial setting, i.e., due to DFS radar detection during CAC.
*/
- if (ifmsh->freq != params->freq.freq) {
+ if (ifmsh->freq > 0 && ifmsh->freq != params->freq.freq) {
- wpa_s->assoc_freq = ifmsh->freq;
- ssid->frequency = ifmsh->freq;
struct he_capabilities *he_capab = NULL;
+
+ wpa_s->assoc_freq = ifmsh->freq;
-From 1eab0e62920f443f8814bad846f6439843223b69 Mon Sep 17 00:00:00 2001
+From 89ad24379d4a1c1decdb8ee693ffc50fcc5b4c1a Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 14:19:06 +0200
-Subject: [PATCH 18/19] mesh: move mesh freq setting to own function
+Subject: mesh: Move mesh frequency setting to its own function
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
- wpa_supplicant/mesh.c | 59 ++++++++++++++++++++++++++-----------------
- 1 file changed, 36 insertions(+), 23 deletions(-)
+ wpa_supplicant/mesh.c | 62 ++++++++++++++++++++++++-------------------
+ 1 file changed, 35 insertions(+), 27 deletions(-)
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -201,6 +201,40 @@ static int wpas_mesh_init_rsn(struct wpa
- return !wpa_s->mesh_rsn ? -1 : 0;
+@@ -204,6 +204,40 @@ static int wpas_mesh_init_rsn(struct wpa
}
-+
+
+static int wpas_mesh_update_freq_params(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
+ if (ifmsh->current_mode)
+ he_capab = &ifmsh->current_mode->he_capab[IEEE80211_MODE_MESH];
+
-+ if (hostapd_set_freq_params(¶ms->freq,
-+ ifmsh->conf->hw_mode,
-+ ifmsh->freq,
-+ ifmsh->conf->channel,
-+ ifmsh->conf->enable_edmg,
-+ ifmsh->conf->edmg_channel,
-+ ifmsh->conf->ieee80211n,
-+ ifmsh->conf->ieee80211ac,
-+ ifmsh->conf->ieee80211ax,
-+ ifmsh->conf->secondary_channel,
-+ hostapd_get_oper_chwidth(ifmsh->conf),
-+ hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
-+ hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
-+ ifmsh->conf->vht_capab,
-+ he_capab)) {
-+ wpa_printf(MSG_ERROR, "Error updating mesh frequency params.");
++ if (hostapd_set_freq_params(
++ ¶ms->freq,
++ ifmsh->conf->hw_mode,
++ ifmsh->freq,
++ ifmsh->conf->channel,
++ ifmsh->conf->enable_edmg,
++ ifmsh->conf->edmg_channel,
++ ifmsh->conf->ieee80211n,
++ ifmsh->conf->ieee80211ac,
++ ifmsh->conf->ieee80211ax,
++ ifmsh->conf->secondary_channel,
++ hostapd_get_oper_chwidth(ifmsh->conf),
++ hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
++ hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
++ ifmsh->conf->vht_capab,
++ he_capab)) {
++ wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
+ wpa_supplicant_mesh_deinit(wpa_s, true);
+ return -1;
+ }
static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
{
struct hostapd_iface *ifmsh = wpa_s->ifmsh;
-@@ -221,30 +255,8 @@ static int wpas_mesh_complete(struct wpa
+@@ -222,36 +256,10 @@ static int wpas_mesh_complete(struct wpa
+ * initial setting, i.e., due to DFS radar detection during CAC.
+ */
if (ifmsh->freq > 0 && ifmsh->freq != params->freq.freq) {
+- struct he_capabilities *he_capab = NULL;
+-
wpa_s->assoc_freq = ifmsh->freq;
ssid->frequency = ifmsh->freq;
-- struct he_capabilities *he_capab = NULL;
-
- if (ifmsh->current_mode)
-- he_capab = &ifmsh->current_mode->he_capab[IEEE80211_MODE_MESH];
+- he_capab = &ifmsh->current_mode->he_capab[
+- IEEE80211_MODE_MESH];
-
-- if (hostapd_set_freq_params(¶ms->freq,
-- ifmsh->conf->hw_mode,
-- ifmsh->freq,
-- ifmsh->conf->channel,
-- ifmsh->conf->enable_edmg,
-- ifmsh->conf->edmg_channel,
-- ifmsh->conf->ieee80211n,
-- ifmsh->conf->ieee80211ac,
-- ifmsh->conf->ieee80211ax,
-- ifmsh->conf->secondary_channel,
-- hostapd_get_oper_chwidth(ifmsh->conf),
-- hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
-- hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
-- ifmsh->conf->vht_capab,
-- he_capab)) {
-- wpa_printf(MSG_ERROR, "Error updating mesh frequency params.");
+- if (hostapd_set_freq_params(
+- ¶ms->freq,
+- ifmsh->conf->hw_mode,
+- ifmsh->freq,
+- ifmsh->conf->channel,
+- ifmsh->conf->enable_edmg,
+- ifmsh->conf->edmg_channel,
+- ifmsh->conf->ieee80211n,
+- ifmsh->conf->ieee80211ac,
+- ifmsh->conf->ieee80211ax,
+- ifmsh->conf->secondary_channel,
+- hostapd_get_oper_chwidth(ifmsh->conf),
+- hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
+- hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
+- ifmsh->conf->vht_capab,
+- he_capab)) {
+- wpa_printf(MSG_ERROR,
+- "Error updating mesh frequency params");
- wpa_supplicant_mesh_deinit(wpa_s, true);
-+ if (wpas_mesh_update_freq_params(wpa_s) != 0)
++ if (wpas_mesh_update_freq_params(wpa_s) < 0)
return -1;
- }
}
if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
-@@ -518,6 +530,7 @@ static int wpa_supplicant_mesh_init(stru
- }
-
- return 0;
-+
- out_free:
- wpa_supplicant_mesh_deinit(wpa_s, true);
- return -ENOMEM;
if (!chan) {
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -9473,6 +9473,10 @@ static int nl80211_switch_channel(void *
+@@ -9476,6 +9476,10 @@ static int nl80211_switch_channel(void *
if (ret)
goto error;
-From c7cca9b08f3e1e49c4a4a59ec66c47d91448e6ae Mon Sep 17 00:00:00 2001
+From 58bbbb5981440da508164cbd423ca5dd7c1b98d8 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 13 Feb 2021 23:59:28 +0200
-Subject: [PATCH] nl80211: Ignore 4addr mode enabling error if it was already
- enabled
+Subject: nl80211: Ignore 4addr mode enabling error if it was already enabled
nl80211_set_4addr_mode() could fail when trying to enable 4addr mode on
an interface that is in a bridge and has 4addr mode already enabled.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
- src/drivers/driver_nl80211.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
+ src/drivers/driver_nl80211.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
-diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 72189da24..011a15e68 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -617,6 +617,7 @@ struct wiphy_idx_data {
};
-@@ -639,6 +640,9 @@ static int netdev_info_handler(struct nl_msg *msg, void *arg)
+@@ -639,6 +640,9 @@ static int netdev_info_handler(struct nl
os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
ETH_ALEN);
return NL_SKIP;
}
-@@ -691,6 +695,20 @@ static int nl80211_get_macaddr(struct i802_bss *bss)
+@@ -691,6 +695,20 @@ static int nl80211_get_macaddr(struct i8
}
static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
struct nl80211_wiphy_data *w)
{
-@@ -11482,6 +11500,11 @@ static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname,
+@@ -11511,6 +11529,11 @@ static int nl80211_set_4addr_mode(void *
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
msg = NULL;
if (!ret) {
if (bridge_ifname[0] && val &&
i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
---
-2.29.2
-
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -10023,6 +10023,9 @@ static int nl80211_put_mesh_config(struc
+@@ -10044,6 +10044,9 @@ static int nl80211_put_mesh_config(struc
if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
params->auto_plinks)) ||
INT(frequency);
INT(enable_edmg);
INT(edmg_channel);
-@@ -1527,6 +1528,9 @@ static void wpa_config_write_global(FILE
+@@ -1528,6 +1529,9 @@ static void wpa_config_write_global(FILE
fprintf(f, "mesh_max_inactivity=%d\n",
config->mesh_max_inactivity);
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -137,6 +137,7 @@ static struct mesh_conf * mesh_config_cr
+@@ -139,6 +139,7 @@ static struct mesh_conf * mesh_config_cr
conf->mesh_cc_id = 0;
conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
-@@ -434,6 +435,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -440,6 +441,7 @@ static int wpa_supplicant_mesh_init(stru
bss->conf->start_disabled = 1;
bss->conf->mesh = MESH_ENABLED;
bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
-@@ -647,6 +649,10 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -654,6 +656,10 @@ int wpa_supplicant_join_mesh(struct wpa_
}
params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
-From 53f8fdb534d5222a0e852e38afde3f49832ace06 Mon Sep 17 00:00:00 2001
+From 4a7e0ac26839424e6a91d38fd126160b18a30a60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be>
-Date: Thu, 26 Nov 2020 09:27:40 +0100
-Subject: [PATCH] hostapd: Add an option to notify management frames on
- ctrl_iface
+Date: Mon, 30 Nov 2020 12:10:46 +0100
+Subject: hostapd: Add an option to notify management frames on ctrl_iface
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-In some contexts (e.g. Multi-AP) it can be useful to have access to
-some of the management frames in upper layers (e.g. to be able to
+In some contexts (e.g., Multi-AP) it can be useful to have access to
+some of the management frames in upper layers (e.g., to be able to
process the content of association requests externally).
Add 'notify_mgmt_frames'. When enabled, it will notify the ctrl_iface
-when a management frame arrives using 'AP_MGMT_FRAME_RECEIVED'.
+when a management frame arrives using the AP-MGMT-FRAME-RECEIVED event
+message.
Note that to avoid completely flooding the ctrl_iface, not all
-management frames are included (e.g. beacons are excluded).
+management frames are included (e.g., Beacon and Probe Request frames
+are excluded).
Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
---
hostapd/config_file.c | 2 ++
hostapd/hostapd.conf | 4 ++++
src/ap/ap_config.h | 2 ++
- src/ap/ieee802_11.c | 25 +++++++++++++++++++++++++
+ src/ap/ieee802_11.c | 28 ++++++++++++++++++++++++++++
src/common/wpa_ctrl.h | 3 +++
- 5 files changed, 36 insertions(+)
+ 5 files changed, 39 insertions(+)
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
} else if (os_strcmp(buf, "broadcast_deauth") == 0) {
bss->broadcast_deauth = atoi(pos);
+ } else if (os_strcmp(buf, "notify_mgmt_frames") == 0) {
-+ conf->notify_mgmt_frames = atoi(pos);
++ bss->notify_mgmt_frames = atoi(pos);
#ifdef CONFIG_DPP
} else if (os_strcmp(buf, "dpp_name") == 0) {
os_free(bss->dpp_name);
# Default: 1 (enabled)
#broadcast_deauth=1
-+# Get notifications for management frames:
++# Get notifications for received Management frames on control interface
+# Default: 0 (disabled)
+#notify_mgmt_frames=0
+
# ieee80211n: Whether IEEE 802.11n (HT) is enabled
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
-@@ -1060,6 +1060,8 @@ struct hostapd_config {
- unsigned int airtime_update_interval;
- #define AIRTIME_MODE_MAX (__AIRTIME_MODE_MAX - 1)
- #endif /* CONFIG_AIRTIME_POLICY */
-+
-+ u8 notify_mgmt_frames;
- };
+@@ -745,6 +745,8 @@ struct hostapd_bss_config {
+ int broadcast_deauth;
++ int notify_mgmt_frames;
++
+ #ifdef CONFIG_DPP
+ char *dpp_name;
+ char *dpp_mud_url;
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
-@@ -4878,6 +4878,28 @@ static int handle_action(struct hostapd_
- return 1;
- }
+@@ -4880,6 +4880,31 @@ static int handle_action(struct hostapd_
-+/**
-+ * notify_mgmt_frame - notify of management frames on the control interface.
-+ * @hapd: hostapd BSS data structure (the BSS to which the management frame was
+
+ /**
++ * notify_mgmt_frame - Notify of Management frames on the control interface
++ * @hapd: hostapd BSS data structure (the BSS to which the Management frame was
+ * sent to)
-+ * @buf: management frame data (starting from IEEE 802.11 header)
-+ * @len: length of frame data in octets
++ * @buf: Management frame data (starting from the IEEE 802.11 header)
++ * @len: Length of frame data in octets
+ *
-+ * Notify the control interface of any management frame.
++ * Notify the control interface of any received Management frame.
+ */
+static void notify_mgmt_frame(struct hostapd_data *hapd, const u8 *buf,
+ size_t len)
+
+ if (hex) {
+ wpa_snprintf_hex(hex, hex_len, buf, len);
-+ wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, AP_MGMT_FRAME_RECEIVED "buf=%s", hex);
++ wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO,
++ AP_MGMT_FRAME_RECEIVED "buf=%s", hex);
+ os_free(hex);
+ }
+}
-
- /**
++
++
++/**
* ieee802_11_mgmt - process incoming IEEE 802.11 management frames
-@@ -4969,6 +4991,9 @@ int ieee802_11_mgmt(struct hostapd_data
+ * @hapd: hostapd BSS data structure (the BSS to which the management frame was
+ * sent to)
+@@ -4969,6 +4994,9 @@ int ieee802_11_mgmt(struct hostapd_data
if (hapd->iconf->track_sta_max_num)
sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
-+ if (hapd->iconf->notify_mgmt_frames)
++ if (hapd->conf->notify_mgmt_frames)
+ notify_mgmt_frame(hapd, buf, len);
+
switch (stype) {
wpa_printf(MSG_DEBUG, "mgmt::auth");
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
-@@ -396,6 +396,9 @@ extern "C" {
- #define BIT(x) (1U << (x))
- #endif
+@@ -392,6 +392,9 @@ extern "C" {
+ * frame=<saqueryreq/saqueryresp> error=<error string> */
+ #define OCV_FAILURE "OCV-FAILURE "
+/* Event triggered for received management frame */
+#define AP_MGMT_FRAME_RECEIVED "AP-MGMT-FRAME-RECEIVED "
+
- /* BSS command information masks */
-
- #define WPA_BSS_MASK_ALL 0xFFFDFFFF
+ #ifndef BIT
+ #define BIT(x) (1U << (x))
+ #endif
--- /dev/null
+From 2fd90eb095e18ce1c505bb6acaccff76072aeebe Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be>
+Date: Thu, 4 Feb 2021 16:36:13 +0100
+Subject: WPS: Use helper variables to clean up code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is in preparation of larger changes in hostapd_update_wps() to keep
+the commits more readable.
+
+Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
+---
+ src/ap/wps_hostapd.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+--- a/src/ap/wps_hostapd.c
++++ b/src/ap/wps_hostapd.c
+@@ -1398,22 +1398,25 @@ void hostapd_deinit_wps(struct hostapd_d
+
+ void hostapd_update_wps(struct hostapd_data *hapd)
+ {
+- if (hapd->wps == NULL)
++ struct wps_context *wps = hapd->wps;
++ struct hostapd_bss_config *conf = hapd->conf;
++
++ if (!wps)
+ return;
+
+ #ifdef CONFIG_WPS_UPNP
+- hapd->wps->friendly_name = hapd->conf->friendly_name;
+- hapd->wps->manufacturer_url = hapd->conf->manufacturer_url;
+- hapd->wps->model_description = hapd->conf->model_description;
+- hapd->wps->model_url = hapd->conf->model_url;
+- hapd->wps->upc = hapd->conf->upc;
++ wps->friendly_name = conf->friendly_name;
++ wps->manufacturer_url = conf->manufacturer_url;
++ wps->model_description = conf->model_description;
++ wps->model_url = conf->model_url;
++ wps->upc = conf->upc;
+ #endif /* CONFIG_WPS_UPNP */
+
+- hostapd_wps_set_vendor_ext(hapd, hapd->wps);
+- hostapd_wps_set_application_ext(hapd, hapd->wps);
++ hostapd_wps_set_vendor_ext(hapd, wps);
++ hostapd_wps_set_application_ext(hapd, wps);
+
+- if (hapd->conf->wps_state)
+- wps_registrar_update_ie(hapd->wps->registrar);
++ if (conf->wps_state)
++ wps_registrar_update_ie(wps->registrar);
+ else
+ hostapd_deinit_wps(hapd);
+ }
-From b389a77a0f6dccf495dbce5be9476000f6ec06a2 Mon Sep 17 00:00:00 2001
+From f95ccc102a6e55bb2543ba68164d6a007a188b25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be>
-Date: Wed, 9 Dec 2020 19:55:53 +0100
-Subject: [PATCH] wps: reconfigure credentials on reload
+Date: Thu, 4 Feb 2021 16:36:13 +0100
+Subject: WPS: Reconfigure credentials on hostapd config reload
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When new credentials are configured and hostapd is reconfigured using
-SIGHUP (or reload on the ctrl_iface), also update the wps credentials.
+SIGHUP (or RELOAD on the ctrl_iface), also update the WPS credentials.
-Before these changes, when WPS is triggered the registar always serves
+Before these changes, when WPS is triggered the Registar always serves
the credentials that were configured when hostapd started.
Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
---
- src/ap/wps_hostapd.c | 86 +++++++++++++++++++++++++++++++++++++++--
- src/wps/wps.h | 6 +++
- src/wps/wps_registrar.c | 29 ++++++++++++++
- 3 files changed, 118 insertions(+), 3 deletions(-)
+ src/ap/wps_hostapd.c | 82 +++++++++++++++++++++++++++++++++++++++++
+ src/wps/wps.h | 5 +++
+ src/wps/wps_registrar.c | 29 +++++++++++++++
+ 3 files changed, 116 insertions(+)
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
-@@ -1375,6 +1375,43 @@ static void hostapd_wps_nfc_clear(struct
- #endif /* CONFIG_WPS_NFC */
+@@ -1376,6 +1376,48 @@ static void hostapd_wps_nfc_clear(struct
}
-+int hostapd_wps_update_multi_ap(struct hostapd_data *hapd,
-+ struct wps_registrar *reg) {
+
++static int hostapd_wps_update_multi_ap(struct hostapd_data *hapd,
++ struct wps_registrar *reg)
++{
+ struct hostapd_bss_config *conf = hapd->conf;
+ u8 *multi_ap_backhaul_network_key = NULL;
+ size_t multi_ap_backhaul_network_key_len = 0;
-+ int ret = -1;
++ int ret;
++
++ if (!(conf->multi_ap & FRONTHAUL_BSS) ||
++ !conf->multi_ap_backhaul_ssid.ssid_len)
++ return 0;
+
-+ if ((conf->multi_ap & FRONTHAUL_BSS) &&
-+ conf->multi_ap_backhaul_ssid.ssid_len) {
-+ if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
-+ multi_ap_backhaul_network_key =
-+ (u8 *) os_strdup(conf->multi_ap_backhaul_ssid.wpa_passphrase);
-+ if (multi_ap_backhaul_network_key == NULL)
-+ return -1;
-+ multi_ap_backhaul_network_key_len =
-+ os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
-+ } else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
-+ multi_ap_backhaul_network_key = os_malloc(2 * PMK_LEN + 1);
-+ if (multi_ap_backhaul_network_key == NULL)
-+ return -1;
-+ wpa_snprintf_hex((char *) multi_ap_backhaul_network_key,
-+ 2 * PMK_LEN + 1,
-+ conf->multi_ap_backhaul_ssid.wpa_psk->psk,
-+ PMK_LEN);
-+ multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
-+ }
-+ ret = wps_registrar_update_multi_ap(reg,
-+ conf->multi_ap_backhaul_ssid.ssid,
-+ conf->multi_ap_backhaul_ssid.ssid_len,
-+ multi_ap_backhaul_network_key,
-+ multi_ap_backhaul_network_key_len);
-+ os_free(multi_ap_backhaul_network_key);
++ if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
++ multi_ap_backhaul_network_key =
++ (u8 *) os_strdup(
++ conf->multi_ap_backhaul_ssid.wpa_passphrase);
++ if (!multi_ap_backhaul_network_key)
++ return -1;
++ multi_ap_backhaul_network_key_len =
++ os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
++ } else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
++ multi_ap_backhaul_network_key = os_malloc(2 * PMK_LEN + 1);
++ if (!multi_ap_backhaul_network_key)
++ return -1;
++ wpa_snprintf_hex((char *) multi_ap_backhaul_network_key,
++ 2 * PMK_LEN + 1,
++ conf->multi_ap_backhaul_ssid.wpa_psk->psk,
++ PMK_LEN);
++ multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
+ }
++
++ ret = wps_registrar_update_multi_ap(
++ reg, conf->multi_ap_backhaul_ssid.ssid,
++ conf->multi_ap_backhaul_ssid.ssid_len,
++ multi_ap_backhaul_network_key,
++ multi_ap_backhaul_network_key_len);
++ os_free(multi_ap_backhaul_network_key);
++
+ return ret;
+}
+
+
-
void hostapd_deinit_wps(struct hostapd_data *hapd)
{
-@@ -1409,11 +1446,54 @@ void hostapd_update_wps(struct hostapd_d
- hapd->wps->upc = hapd->conf->upc;
+ eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+@@ -1412,6 +1454,46 @@ void hostapd_update_wps(struct hostapd_d
+ wps->upc = conf->upc;
#endif /* CONFIG_WPS_UPNP */
-- hostapd_wps_set_vendor_ext(hapd, hapd->wps);
-- hostapd_wps_set_application_ext(hapd, hapd->wps);
-+ struct wps_context *wps = hapd->wps;
-+ struct hostapd_bss_config *conf = hapd->conf;
-+
+ os_memcpy(wps->ssid, conf->ssid.ssid, conf->ssid.ssid_len);
+ wps->ssid_len = conf->ssid.ssid_len;
+
-+ /* Clear wps settings, then fill them again */
++ /* Clear WPS settings, then fill them again */
+ os_free(wps->network_key);
+ wps->network_key = NULL;
+ wps->network_key_len = 0;
+ /* Use per-device PSKs */
+ } else if (conf->ssid.wpa_passphrase) {
+ wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase);
-+ if (wps->network_key == NULL)
++ if (!wps->network_key)
+ return;
+ wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
+ } else if (conf->ssid.wpa_psk) {
+ wps->network_key = os_malloc(2 * PMK_LEN + 1);
-+ if (wps->network_key == NULL)
++ if (!wps->network_key)
+ return;
+ wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
+ conf->ssid.wpa_psk->psk, PMK_LEN);
+#ifdef CONFIG_WEP
+ } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
+ wps->network_key = os_malloc(conf->ssid.wep.len[0]);
-+ if (wps->network_key == NULL)
++ if (!wps->network_key)
+ return;
+ os_memcpy(wps->network_key, conf->ssid.wep.key[0],
+ conf->ssid.wep.len[0]);
+
+ hostapd_wps_update_multi_ap(hapd, wps->registrar);
+
-+ hostapd_wps_set_vendor_ext(hapd, wps);
-+ hostapd_wps_set_application_ext(hapd, wps);
+ hostapd_wps_set_vendor_ext(hapd, wps);
+ hostapd_wps_set_application_ext(hapd, wps);
- if (hapd->conf->wps_state)
-- wps_registrar_update_ie(hapd->wps->registrar);
-+ wps_registrar_update_ie(wps->registrar);
- else
- hostapd_deinit_wps(hapd);
- }
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
-@@ -938,6 +938,12 @@ struct wpabuf * wps_build_nfc_handover_s
- struct wpabuf *nfc_dh_pubkey,
- struct wpabuf *nfc_dev_pw);
-
+@@ -873,6 +873,11 @@ int wps_registrar_add_nfc_password_token
+ const u8 *oob_dev_pw,
+ size_t oob_dev_pw_len);
+ void wps_registrar_flush(struct wps_registrar *reg);
+int wps_registrar_update_multi_ap(struct wps_registrar *reg,
+ const u8 *multi_ap_backhaul_ssid,
+ size_t multi_ap_backhaul_ssid_len,
+ const u8 *multi_ap_backhaul_network_key,
+ size_t multi_ap_backhaul_network_key_len);
-+
- /* ndef.c */
- struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
- struct wpabuf * ndef_build_wifi(const struct wpabuf *buf);
+
+ int wps_build_credential_wrap(struct wpabuf *msg,
+ const struct wps_credential *cred);
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -3669,6 +3669,35 @@ int wps_registrar_config_ap(struct wps_r
+ const u8 *multi_ap_backhaul_network_key,
+ size_t multi_ap_backhaul_network_key_len)
+{
-+ if (multi_ap_backhaul_ssid != NULL) {
++ if (multi_ap_backhaul_ssid) {
+ os_memcpy(reg->multi_ap_backhaul_ssid,
-+ multi_ap_backhaul_ssid,
-+ multi_ap_backhaul_ssid_len);
-+ reg->multi_ap_backhaul_ssid_len =
-+ multi_ap_backhaul_ssid_len;
++ multi_ap_backhaul_ssid, multi_ap_backhaul_ssid_len);
++ reg->multi_ap_backhaul_ssid_len = multi_ap_backhaul_ssid_len;
+ }
++
+ os_free(reg->multi_ap_backhaul_network_key);
+ reg->multi_ap_backhaul_network_key = NULL;
+ reg->multi_ap_backhaul_network_key_len = 0;
-+
-+ if (multi_ap_backhaul_network_key != NULL) {
++ if (multi_ap_backhaul_network_key) {
+ reg->multi_ap_backhaul_network_key =
+ os_memdup(multi_ap_backhaul_network_key,
+ multi_ap_backhaul_network_key_len);
-+ if (reg->multi_ap_backhaul_network_key == NULL)
++ if (!reg->multi_ap_backhaul_network_key)
+ return -1;
+ reg->multi_ap_backhaul_network_key_len =
+ multi_ap_backhaul_network_key_len;
+ }
++
+ return 0;
+}
++
+
#ifdef CONFIG_WPS_NFC
os_memset(&global, 0, sizeof(global));
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
-@@ -4581,8 +4581,8 @@ static void wpas_event_unprot_beacon(str
+@@ -4579,8 +4579,8 @@ static void wpas_event_unprot_beacon(str
}
{
struct wpa_supplicant *wpa_s = ctx;
int resched;
-@@ -5400,7 +5400,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -5398,7 +5398,7 @@ void wpa_supplicant_event(void *ctx, enu
}
} else if (os_strcmp(buf, "ht_capab") == 0) {
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
-@@ -984,6 +984,8 @@ struct hostapd_config {
+@@ -986,6 +986,8 @@ struct hostapd_config {
int ht_op_mode_fixed;
u16 ht_capab;
INT(enable_edmg);
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -467,6 +467,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -473,6 +473,8 @@ static int wpa_supplicant_mesh_init(stru
frequency);
goto out_free;
}
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -4646,7 +4646,7 @@ static int nl80211_set_channel(struct i8
+@@ -4664,7 +4664,7 @@ static int nl80211_set_channel(struct i8
freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled,
freq->bandwidth, freq->center_freq1, freq->center_freq2);
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
-@@ -1466,15 +1466,35 @@ int ap_switch_channel(struct wpa_supplic
+@@ -1470,15 +1470,35 @@ int ap_switch_channel(struct wpa_supplic
#ifdef CONFIG_CTRL_IFACE
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -2788,10 +2788,15 @@ static int wpa_driver_nl80211_del_beacon
+@@ -2806,10 +2806,15 @@ static int wpa_driver_nl80211_del_beacon
struct nl_msg *msg;
struct wpa_driver_nl80211_data *drv = bss->drv;
return send_and_recv_msgs(drv, msg, NULL, NULL);
}
-@@ -5261,7 +5266,7 @@ static void nl80211_teardown_ap(struct i
+@@ -5279,7 +5284,7 @@ static void nl80211_teardown_ap(struct i
nl80211_mgmt_unsubscribe(bss, "AP teardown");
nl80211_put_wiphy_data_ap(bss);
}
-@@ -7679,8 +7684,6 @@ static int wpa_driver_nl80211_if_remove(
+@@ -7697,8 +7702,6 @@ static int wpa_driver_nl80211_if_remove(
} else {
wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
nl80211_teardown_ap(bss);
nl80211_destroy_bss(bss);
if (!bss->added_if)
i802_set_iface_flags(bss, 0);
-@@ -8074,7 +8077,6 @@ static int wpa_driver_nl80211_deinit_ap(
+@@ -8095,7 +8098,6 @@ static int wpa_driver_nl80211_deinit_ap(
if (!is_ap_interface(drv->nlmode))
return -1;
wpa_driver_nl80211_del_beacon(bss);
/*
* If the P2P GO interface was dynamically added, then it is
-@@ -8094,7 +8096,6 @@ static int wpa_driver_nl80211_stop_ap(vo
+@@ -8115,7 +8117,6 @@ static int wpa_driver_nl80211_stop_ap(vo
if (!is_ap_interface(drv->nlmode))
return -1;
wpa_driver_nl80211_del_beacon(bss);
if (ieee802_11_build_ap_params(hapd, ¶ms) < 0)
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
-@@ -4581,6 +4581,60 @@ static void wpas_event_unprot_beacon(str
+@@ -4579,6 +4579,60 @@ static void wpas_event_unprot_beacon(str
}
void supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
-@@ -4883,8 +4937,10 @@ void supplicant_event(void *ctx, enum wp
+@@ -4881,8 +4935,10 @@ void supplicant_event(void *ctx, enum wp
channel_width_to_string(data->ch_switch.ch_width),
data->ch_switch.cf1,
data->ch_switch.cf2);
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
-@@ -1324,7 +1324,7 @@ int wpas_ap_wps_nfc_report_handover(stru
+@@ -1328,7 +1328,7 @@ int wpas_ap_wps_nfc_report_handover(stru
#endif /* CONFIG_WPS */
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -5584,7 +5584,7 @@ static int wpa_driver_nl80211_ibss(struc
+@@ -5602,7 +5602,7 @@ static int wpa_driver_nl80211_ibss(struc
struct wpa_driver_associate_params *params)
{
struct nl_msg *msg;
int count = 0;
wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
-@@ -5611,6 +5611,37 @@ retry:
+@@ -5629,6 +5629,37 @@ retry:
nl80211_put_beacon_int(msg, params->beacon_int))
goto fail;
@@ -1549,6 +1549,7 @@ struct wpa_driver_mesh_join_params {
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
unsigned int flags;
- u8 handle_dfs;
+ bool handle_dfs;
+ int mcast_rate;
};
struct wpa_driver_set_key_params {
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -10043,6 +10043,18 @@ static int nl80211_put_mesh_id(struct nl
+@@ -10064,6 +10064,18 @@ static int nl80211_put_mesh_id(struct nl
}
static int nl80211_put_mesh_config(struct nl_msg *msg,
struct wpa_driver_mesh_bss_params *params)
{
-@@ -10104,6 +10116,7 @@ static int nl80211_join_mesh(struct i802
+@@ -10125,6 +10137,7 @@ static int nl80211_join_mesh(struct i802
nl80211_put_basic_rates(msg, params->basic_rates) ||
nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
nl80211_put_beacon_int(msg, params->beacon_int) ||
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -592,6 +592,7 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -599,6 +599,7 @@ int wpa_supplicant_join_mesh(struct wpa_
params->meshid = ssid->ssid;
params->meshid_len = ssid->ssid_len;
os_free(conf->basic_rates);
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
-@@ -871,6 +871,7 @@ struct hostapd_bss_config {
+@@ -873,6 +873,7 @@ struct hostapd_bss_config {
*/
u8 mka_psk_set;
#endif /* CONFIG_MACSEC */
};
/**
-@@ -1062,6 +1063,7 @@ struct hostapd_config {
+@@ -1064,6 +1065,7 @@ struct hostapd_config {
unsigned int airtime_update_interval;
#define AIRTIME_MODE_MAX (__AIRTIME_MODE_MAX - 1)
#endif /* CONFIG_AIRTIME_POLICY */
+ char *config_id;
-
- u8 notify_mgmt_frames;
};
+
+
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -218,6 +218,10 @@ static int hostapd_iface_conf_changed(st
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -4493,6 +4493,9 @@ static int wpa_driver_nl80211_set_ap(voi
+@@ -4511,6 +4511,9 @@ static int wpa_driver_nl80211_set_ap(voi
if (ret) {
wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
ret, strerror(-ret));
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
-@@ -1086,8 +1086,15 @@ static int hostapd_dfs_start_channel_swi
+@@ -1088,8 +1088,15 @@ static int hostapd_dfs_start_channel_swi
&oper_centr_freq_seg0_idx,
&oper_centr_freq_seg1_idx,
&skip_radar);