wifi-ax: update hostapd to latest 11.5-cs

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2022-05-18 10:59:06 +02:00
parent cc0d4bded2
commit f819bb8753
21 changed files with 2480 additions and 967 deletions

View File

@@ -0,0 +1,26 @@
Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver.h
+++ hostapd-2021-02-20-59e9794c/src/drivers/driver.h
@@ -19,6 +19,7 @@
#define WPA_SUPPLICANT_DRIVER_VERSION 4
+#include "nl80211_copy.h"
#include "ap/sta_info.h"
#include "common/defs.h"
#include "common/ieee802_11_defs.h"
Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ubus.c
+++ hostapd-2021-02-20-59e9794c/src/ap/ubus.c
@@ -882,7 +882,8 @@ hostapd_switch_chan(struct ubus_context
chwidth, seg0, seg1,
iconf->vht_capab,
mode ? &mode->he_capab[IEEE80211_MODE_AP] :
- NULL);
+ NULL,
+ iconf->he_6ghz_reg_pwr_type);
for (i = 0; i < hapd->iface->num_bss; i++) {
struct hostapd_data *bss = hapd->iface->bss[i];

View File

@@ -2,7 +2,7 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
@@ -2458,6 +2458,8 @@ static int hostapd_config_fill(struct ho
@@ -2460,6 +2460,8 @@ static int hostapd_config_fill(struct ho
conf->ieee80211d = atoi(pos);
} else if (os_strcmp(buf, "ieee80211h") == 0) {
conf->ieee80211h = atoi(pos);
@@ -27,16 +27,17 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/dfs.c
+++ hostapd-2021-02-20-59e9794c/src/ap/dfs.c
@@ -18,6 +18,8 @@
@@ -18,7 +18,8 @@
#include "drivers/driver.h"
#include "dfs.h"
#include "crypto/crypto.h"
-
+#include "beacon.h"
+#include "eloop.h"
static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
@@ -1036,6 +1038,73 @@ static int hostapd_dfs_start_channel_swi
{
@@ -1036,6 +1037,73 @@ static int hostapd_dfs_start_channel_swi
return err;
}
@@ -110,7 +111,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c
static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
{
@@ -1071,6 +1140,9 @@ static int hostapd_dfs_start_channel_swi
@@ -1071,6 +1139,9 @@ static int hostapd_dfs_start_channel_swi
if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI)
skip_radar = 0;
@@ -120,7 +121,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c
/* Perform channel switch/CSA */
channel = dfs_get_valid_channel(iface, &secondary_channel,
&oper_centr_freq_seg0_idx,
@@ -1208,6 +1280,12 @@ int hostapd_dfs_radar_detected(struct ho
@@ -1208,6 +1279,12 @@ int hostapd_dfs_radar_detected(struct ho
if (!res)
return 0;
@@ -153,7 +154,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
@@ -2866,6 +2866,7 @@ int hostapd_disable_iface(struct hostapd
@@ -2884,6 +2884,7 @@ int hostapd_disable_iface(struct hostapd
hostapd_cleanup_cs_params(hapd_iface->bss[j]);
#endif /* NEED_AP_MLME */

View File

@@ -22,7 +22,18 @@ Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -4454,12 +4454,13 @@ void wpa_gtk_rekey(struct wpa_authentica
@@ -75,8 +75,10 @@ static const u32 eapol_key_timeout_no_retrans = 4000; /* ms */
/* TODO: make these configurable */
static const int dot11RSNAConfigPMKLifetime = 43200;
+#ifdef CONFIG_CTRL_IFACE_MIB
static const int dot11RSNAConfigPMKReauthThreshold = 70;
static const int dot11RSNAConfigSATimeout = 60;
+#endif
static inline int wpa_auth_mic_failure_report(
@@ -4454,12 +4456,13 @@ void wpa_gtk_rekey(struct wpa_authentica
}

View File

@@ -1,8 +1,22 @@
From 353f9b94d5f8a9a307ae80d62cd5fb503f126563 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Wed, 3 Jun 2020 16:32:11 +0200
Subject: [PATCH 1/7] multiple_bssid: add the config file
This patch adds a new config option to enable this feature.
Signed-off-by: John Crispin <john@phrozen.org>
---
hostapd/config_file.c | 2 ++
src/ap/ap_config.h | 2 ++
2 files changed, 4 insertions(+)
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
@@ -4681,6 +4681,8 @@ static int hostapd_config_fill(struct ho
@@ -4683,6 +4683,8 @@ static int hostapd_config_fill(struct ho
}
bss->mka_psk_set |= MKA_PSK_SET_CKN;
#endif /* CONFIG_MACSEC */
@@ -28,7 +42,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
@@ -87,6 +87,26 @@ int hostapd_for_each_interface(struct ha
@@ -89,6 +89,26 @@ int hostapd_for_each_interface(struct ha
}
@@ -55,7 +69,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
void hostapd_reconfig_encryption(struct hostapd_data *hapd)
{
if (hapd->wpa_auth)
@@ -1206,6 +1226,13 @@ static int hostapd_setup_bss(struct host
@@ -1208,6 +1228,13 @@ static int hostapd_setup_bss(struct host
if (!first || first == -1) {
u8 *addr = hapd->own_addr;
@@ -69,7 +83,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
if (!is_zero_ether_addr(conf->bssid)) {
/* Allocate the configured BSSID. */
@@ -1233,7 +1260,7 @@ static int hostapd_setup_bss(struct host
@@ -1235,7 +1262,7 @@ static int hostapd_setup_bss(struct host
conf->iface, addr, hapd,
&hapd->drv_priv, force_ifname, if_addr,
conf->bridge[0] ? conf->bridge : NULL,
@@ -82,7 +96,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
@@ -603,6 +603,8 @@ struct hostapd_iface {
@@ -621,6 +621,8 @@ struct hostapd_iface {
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
int (*cb)(struct hostapd_iface *iface,
void *ctx), void *ctx);
@@ -104,7 +118,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ap_drv_ops.c
}
@@ -497,13 +497,15 @@ int hostapd_set_ssid(struct hostapd_data
@@ -495,13 +495,15 @@ int hostapd_set_ssid(struct hostapd_data
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
const char *ifname, const u8 *addr, void *bss_ctx,
void **drv_priv, char *force_ifname, u8 *if_addr,
@@ -545,7 +559,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO, "No room for more AIDs");
resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
@@ -6970,4 +6975,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct
@@ -6969,4 +6974,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct
return eid;
}

View File

@@ -1,3 +1,28 @@
From 38823a3ae9fd084ee5822dfb228e109656187e85 Mon Sep 17 00:00:00 2001
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
Date: Tue, 8 Sep 2020 14:24:37 -0700
Subject: [PATCH] hostapd: Enable 6ghz support in 11s mesh
Enable 6ghz frequencies support in 11s mesh.
Configurations are similar to 5G/2G bands.
example:
network={
ssid="pr6gmesh123"
key_mgmt=SAE
mode=5
frequency=6195
psk="1234567890"
}
Also, fix assigning secondary channel for only bandwidth greater
than 20 MHz.
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
---
wpa_supplicant/mesh.c | 6 ++++
wpa_supplicant/wpa_supplicant.c | 54 +++++++++++++++++++++------------
2 files changed, 41 insertions(+), 21 deletions(-)
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/mesh.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/mesh.c

View File

@@ -1,3 +1,25 @@
From 01845904f9a5cdbd60f6aabdcfc0a8b191d90785 Mon Sep 17 00:00:00 2001
From: P Praneesh <ppranees@codeaurora.org>
Date: Sun, 27 Sep 2020 00:21:21 +0530
Subject: [PATCH] hostapd: Enable 160MHz support for 6G in 11s mesh
Since 6G has no dfs channel, enable 6G 160MHz bandwidth
as a default configuration for 11s mesh.
example:
network={
ssid="6gmesh160"
key_mgmt=SAE
mode=5
frequency=6275
psk="1234567890"
}
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
---
wpa_supplicant/wpa_supplicant.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c
@@ -59,7 +81,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
seg0 = freq->channel + 6;
seg1 = 0;
+ /* setup center_freq1 for 6G 160MHz */
+/* setup center_freq1 for 6G 160MHz */
+ if ((mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
+

View File

@@ -1,8 +1,29 @@
From baf3a982caee59ec08602a9e981d6742abc4fc7b Mon Sep 17 00:00:00 2001
From: Lavanya Suresh <lavaks@codeaurora.org>
Date: Mon, 28 Sep 2020 23:21:43 +0530
Subject: [PATCH] hostapd: Add support to change bss color by user
hostpad_cli command is added to change bss color in runtime,
for testing purpose. hostapd_cli status can be used to check
updated color.
Usage: hostapd_cli color_change <color>
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
---
hostapd/ctrl_iface.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
hostapd/hostapd_cli.c | 23 +++++++++++++++++++++++
src/ap/ctrl_iface_ap.c | 6 ++++--
src/ap/hostapd.c | 4 ++--
src/ap/hostapd.h | 3 ++-
5 files changed, 76 insertions(+), 5 deletions(-)
Index: hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/ctrl_iface.c
+++ hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c
@@ -2673,6 +2673,59 @@ static int hostapd_ctrl_check_freq_param
@@ -2679,6 +2679,59 @@ static int hostapd_ctrl_check_freq_param
}
#endif /* NEED_AP_MLME */
@@ -62,7 +83,7 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c
static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
char *pos)
@@ -3682,6 +3735,9 @@ static int hostapd_ctrl_iface_receive_pr
@@ -3688,6 +3741,9 @@ static int hostapd_ctrl_iface_receive_pr
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
reply_len = -1;
@@ -136,7 +157,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
@@ -3443,7 +3443,7 @@ int hostapd_csa_in_progress(struct hosta
@@ -3461,7 +3461,7 @@ int hostapd_csa_in_progress(struct hosta
#ifdef NEED_AP_MLME
@@ -145,7 +166,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
{
os_free(beacon->head);
beacon->head = NULL;
@@ -3833,7 +3833,7 @@ void hostapd_cleanup_cca_params(struct h
@@ -3851,7 +3851,7 @@ void hostapd_cleanup_cca_params(struct h
}
@@ -158,17 +179,12 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
@@ -661,11 +661,13 @@ void hostapd_periodic_iface(struct hosta
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
int hostapd_check_max_sta(struct hostapd_data *hapd);
@@ -649,6 +649,8 @@ void hostapd_interface_free(struct hosta
struct hostapd_iface * hostapd_alloc_iface(void);
struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
const char *config_file);
+void free_beacon_data(struct beacon_data *beacon);
#ifdef CONFIG_IEEE80211AX
void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap);
void hostapd_cleanup_cca_params(struct hostapd_data *hapd);
+int hostapd_fill_cca_settings(struct hostapd_data *hapd, struct cca_settings *settings);
#endif
/* utils.c */
struct hostapd_iface *
hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
const char *config_fname, int debug);

View File

@@ -15,11 +15,9 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
src/ap/ieee802_11.c | 106 +++++++++++++++++++++++++++++++++-----------
2 files changed, 85 insertions(+), 33 deletions(-)
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index eda20fc0d9df..74ac8584ab5e 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -485,8 +485,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
@@ -485,8 +485,7 @@ static u8 * hostapd_gen_probe_resp(struc
buflen += hostapd_eid_multiple_bssid_len(hapd, req_bss, 0,
known_bssids,
known_bssids_len);
@@ -29,7 +27,7 @@ index eda20fc0d9df..74ac8584ab5e 100644
resp = os_zalloc(buflen);
if (resp == NULL)
@@ -652,8 +651,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
@@ -667,8 +666,7 @@ static u8 * hostapd_gen_probe_resp(struc
pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
pos = hostapd_eid_owe_trans(hapd, pos, (u8 *) resp + buflen - pos);
pos = hostapd_eid_dpp_cc(hapd, pos, (u8 *) resp + buflen - pos);
@@ -39,7 +37,7 @@ index eda20fc0d9df..74ac8584ab5e 100644
if (hapd->conf->vendor_elements) {
os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
@@ -1532,8 +1530,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
@@ -1527,8 +1525,7 @@ int ieee802_11_build_ap_params(struct ho
tail_len += hostapd_mbo_ie_len(hapd);
tail_len += hostapd_eid_owe_trans_len(hapd);
tail_len += hostapd_eid_dpp_cc_len(hapd);
@@ -49,7 +47,7 @@ index eda20fc0d9df..74ac8584ab5e 100644
tailpos = tail = os_malloc(tail_len);
if (head == NULL || tail == NULL) {
@@ -1711,8 +1708,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
@@ -1713,8 +1710,7 @@ int ieee802_11_build_ap_params(struct ho
tailpos = hostapd_eid_owe_trans(hapd, tailpos,
tail + tail_len - tailpos);
tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos);
@@ -59,11 +57,9 @@ index eda20fc0d9df..74ac8584ab5e 100644
if (hapd->conf->vendor_elements) {
os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 97c5b42a7528..488f02f58f63 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -5989,6 +5989,7 @@ size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
@@ -7308,6 +7308,7 @@ size_t hostapd_eid_rnr_iface_len(struct
{
size_t len = 0;
int i;
@@ -71,7 +67,7 @@ index 97c5b42a7528..488f02f58f63 100644
for (i = 0; i < hapd->iface->num_bss; i++) {
if (hapd->iface->bss[i] == reporting_hapd ||
hapd->iface->bss[i]->conf->ignore_broadcast_ssid)
@@ -5999,29 +6000,69 @@ size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
@@ -7318,29 +7319,69 @@ size_t hostapd_eid_rnr_iface_len(struct
}
@@ -89,7 +85,7 @@ index 97c5b42a7528..488f02f58f63 100644
+ for (i = 0; i < hapd->iface->interfaces->count; i++) {
+ iface = hapd->iface->interfaces->iface[i];
+
+ if (iface == hapd->iface || !iface->conf->he_co_locate)
+ if (!iface || iface == hapd->iface || !iface->conf->he_co_locate)
+ continue;
+
len += (TBTT_HEADER_LENGTH +
@@ -99,7 +95,10 @@ index 97c5b42a7528..488f02f58f63 100644
+ return len;
+}
+
+
- if (type != WLAN_FC_STYPE_ACTION) {
- for (i = 0; i < hapd->iface->interfaces->count; i++) {
- struct hostapd_iface *iface = hapd->iface->interfaces->iface[i];
+static bool is_6ghz_colocated(struct hostapd_data *hapd)
+{
+ u8 i;
@@ -124,16 +123,13 @@ index 97c5b42a7528..488f02f58f63 100644
+ return false;
+}
- if (type != WLAN_FC_STYPE_ACTION) {
- for (i = 0; i < hapd->iface->interfaces->count; i++) {
- struct hostapd_iface *iface = hapd->iface->interfaces->iface[i];
- if (iface == hapd->iface || !iface->conf->he_co_locate)
- continue;
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
+{
+ size_t len = 0;
+
+ if (hapd->conf->rnr_beacon) {
+ if (hapd->iface->num_bss > 1)
len += (TBTT_HEADER_LENGTH +
@@ -153,7 +149,7 @@ index 97c5b42a7528..488f02f58f63 100644
if (len)
len += 2; /* Element ID and length */
@@ -6096,6 +6137,27 @@ static u8 *hostapd_eid_rnr_iface(struct hostapd_data *hapd,
@@ -7415,6 +7456,27 @@ static u8 *hostapd_eid_rnr_iface(struct
}
@@ -169,7 +165,7 @@ index 97c5b42a7528..488f02f58f63 100644
+ for (i = 0; i < hapd->iface->interfaces->count; i++) {
+ iface = hapd->iface->interfaces->iface[i];
+
+ if (iface == hapd->iface || !iface->conf->he_co_locate)
+ if (!iface || iface == hapd->iface || !iface->conf->he_co_locate)
+ continue;
+
+ eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid, count);
@@ -181,7 +177,7 @@ index 97c5b42a7528..488f02f58f63 100644
static u8 *hostapd_eid_neighbor_report_db(struct hostapd_data *hapd, u8 *eid,
int *count)
{
@@ -6138,22 +6200,16 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
@@ -7457,22 +7519,16 @@ u8 * hostapd_eid_rnr(struct hostapd_data
*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
size_offset = eid++;
@@ -211,6 +207,3 @@ index 97c5b42a7528..488f02f58f63 100644
if (!count)
eid -= 2;
--
2.25.0

View File

@@ -1,8 +1,35 @@
From a1d4da59739c2054eb46cf634320c8bd323a8069 Mon Sep 17 00:00:00 2001
From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
Date: Tue, 12 Jan 2021 18:12:37 +0530
Subject: [PATCH] hostapd: Add support for beacon tx mode
User can configure the beacon tx mode while bring-up the
AP via hostapd configuration and while bring-up MESH via
wpa_supplicant configuration.
Use the below configuration in the hostapd/wpa_supplicant
to configure the beacon tx mode.
"beacon_tx_mode=N", where N = 1 for STAGGERED beacon mode
and N = 2 for BURST beacon mode.
Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
---
hostapd/config_file.c | 9 +++++++++
src/ap/ap_config.c | 2 ++
src/ap/ap_config.h | 1 +
src/ap/beacon.c | 2 ++
src/ap/ctrl_iface_ap.c | 6 ++++--
src/drivers/driver.h | 5 +++++
src/drivers/driver_nl80211.c | 16 +++++++++++++++-
src/drivers/nl80211_copy.h | 4 ++++
8 files changed, 42 insertions(+), 3 deletions(-)
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
@@ -4590,6 +4590,15 @@ static int hostapd_config_fill(struct ho
@@ -4592,6 +4592,15 @@ static int hostapd_config_fill(struct ho
bss->disable_11ac = !!atoi(pos);
} else if (os_strcmp(buf, "disable_11ax") == 0) {
bss->disable_11ax = !!atoi(pos);

View File

@@ -1,3 +1,18 @@
From b6bb46ef161e1c3890f517fdb04f081926fc1a08 Mon Sep 17 00:00:00 2001
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
Date: Tue, 23 Mar 2021 19:57:43 +0530
Subject: [PATCH] hostapd: update missing 5.9GHz channels
Update channel 165 and 173 in allowed channel.
This fixes below upstream commit,
833cdbe - "Add support for new 5 GHz channels 173 and 177"
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
---
src/common/hw_features_common.c | 2 +-
wpa_supplicant/wpa_supplicant.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
Index: hostapd-2021-02-20-59e9794c/src/common/hw_features_common.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/common/hw_features_common.c
@@ -26,3 +41,42 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
6035, 6115, 6195, 6275, 6355, 6435, 6515,
6595, 6675, 6755, 6835, 6915, 6995 };
unsigned int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
Index: hostapd-2021-02-20-59e9794c/src/ap/acs.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/acs.c
+++ hostapd-2021-02-20-59e9794c/src/ap/acs.c
@@ -369,9 +369,10 @@ acs_survey_chan_interference_factor(stru
static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
{
const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620, 5660, 5745,
- 5785, 5955, 5995, 6035, 6075, 6115, 6155, 6195, 6235, 6275,
- 6315, 6355, 6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
- 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995, 7035, 7075 };
+ 5785, 5825, 5865, 5955, 5995, 6035, 6075, 6115, 6155, 6195,
+ 6235, 6275, 6315, 6355, 6395, 6435, 6475, 6515, 6555, 6595,
+ 6635, 6675, 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
+ 7035, 7075 };
unsigned int i;
for (i = 0; i < ARRAY_SIZE(allowed); i++)
@@ -384,9 +385,8 @@ static int acs_usable_bw40_chan(const st
static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
{
- const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 6035, 6115, 6195,
- 6275, 6355, 6435, 6515, 6595, 6675, 6755, 6835, 6915,
- 6995 };
+ const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 6035, 6115, 6195,
+ 6275, 6355, 6435, 6515, 6595, 6675, 6755, 6835, 6915, 6995 };
unsigned int i;
for (i = 0; i < ARRAY_SIZE(allowed); i++)
@@ -399,7 +399,7 @@ static int acs_usable_bw80_chan(const st
static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
{
- const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
+ const int allowed[] = { 5180, 5500, 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
unsigned int i;
for (i = 0; i < ARRAY_SIZE(allowed); i++)

View File

@@ -1,459 +0,0 @@
From 1c3438fec4bad13a676617915ff56af54e7b4542 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 2 Apr 2022 13:12:43 +0300
Subject: [PATCH] RADIUS ACL/PSK check during 4-way handshake
Add an alternative sequence for performing the RADIUS ACL check and PSK
fetch. The previously used (macaddr_acl=2, wpa_psk_radius=2) combination
does this during IEEE 802.11 Authentication frame exchange while the new
option (wpa_psk_radius=3) does this during the 4-way handshake. This
allows some more information to be provided to the RADIUS authentication
server.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
hostapd/config_file.c | 3 +-
hostapd/hostapd.conf | 5 ++-
src/ap/ap_config.c | 4 ++-
src/ap/ap_config.h | 5 +--
src/ap/ieee802_11.c | 5 ++-
src/ap/ieee802_11.h | 2 ++
src/ap/ieee802_11_auth.c | 76 ++++++++++++++++++++++++++++++++++++----
src/ap/ieee802_11_auth.h | 5 ++-
src/ap/wpa_auth.c | 51 ++++++++++++++++++++++++++-
src/ap/wpa_auth.h | 9 ++++-
src/ap/wpa_auth_glue.c | 25 ++++++++++++-
src/ap/wpa_auth_i.h | 1 +
12 files changed, 172 insertions(+), 19 deletions(-)
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2858,7 +2858,8 @@ static int hostapd_config_fill(struct ho
bss->wpa_psk_radius = atoi(pos);
if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
- bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
+ bss->wpa_psk_radius != PSK_RADIUS_REQUIRED &&
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS) {
wpa_printf(MSG_ERROR,
"Line %d: unknown wpa_psk_radius %d",
line, bss->wpa_psk_radius);
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -1635,12 +1635,15 @@ own_ip_addr=127.0.0.1
#wpa_psk_file=/etc/hostapd.wpa_psk
# Optionally, WPA passphrase can be received from RADIUS authentication server
-# This requires macaddr_acl to be set to 2 (RADIUS)
+# This requires macaddr_acl to be set to 2 (RADIUS) for wpa_psk_radius values
+# 1 and 2.
# 0 = disabled (default)
# 1 = optional; use default passphrase/psk if RADIUS server does not include
# Tunnel-Password
# 2 = required; reject authentication if RADIUS server does not include
# Tunnel-Password
+# 3 = ask RADIUS server during 4-way handshake if there is no locally
+# configured PSK/passphrase for the STA
#wpa_psk_radius=0
# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -1,6 +1,6 @@
/*
* hostapd / Configuration helper functions
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -1245,6 +1245,7 @@ static int hostapd_config_check_bss(stru
if (full_config && bss->wpa &&
bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS &&
bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
wpa_printf(MSG_ERROR, "WPA-PSK using RADIUS enabled, but no "
"RADIUS checking (macaddr_acl=2) enabled.");
@@ -1254,6 +1255,7 @@ static int hostapd_config_check_bss(stru
if (full_config && bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
bss->ssid.wpa_psk_file == NULL &&
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS &&
(bss->wpa_psk_radius != PSK_RADIUS_REQUIRED ||
bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH)) {
wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1,6 +1,6 @@
/*
* hostapd / Configuration definitions and helpers functions
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -367,7 +367,8 @@ struct hostapd_bss_config {
enum {
PSK_RADIUS_IGNORED = 0,
PSK_RADIUS_ACCEPTED = 1,
- PSK_RADIUS_REQUIRED = 2
+ PSK_RADIUS_REQUIRED = 2,
+ PSK_RADIUS_DURING_4WAY_HS = 3,
} wpa_psk_radius;
int wpa_pairwise;
int group_cipher; /* wpa_group value override from configuation */
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2348,9 +2348,8 @@ static int ieee802_11_allowed_address(st
}
-static int
-ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
- int res, struct radius_sta *info)
+int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
+ int res, struct radius_sta *info)
{
u32 session_timeout = info->session_timeout;
u32 acct_interim_interval = info->acct_interim_interval;
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -220,4 +220,6 @@ void auth_sae_process_commit(void *eloop
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len);
u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len);
+int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
+ int res, struct radius_sta *info);
#endif /* IEEE802_11_H */
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -1,6 +1,6 @@
/*
* hostapd / IEEE 802.11 authentication (ACL)
- * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -20,6 +20,8 @@
#include "hostapd.h"
#include "ap_config.h"
#include "ap_drv_ops.h"
+#include "sta_info.h"
+#include "wpa_auth.h"
#include "ieee802_11.h"
#include "ieee802_1x.h"
#include "ieee802_11_auth.h"
@@ -43,6 +45,8 @@ struct hostapd_acl_query_data {
u8 *auth_msg; /* IEEE 802.11 authentication frame from station */
size_t auth_msg_len;
struct hostapd_acl_query_data *next;
+ bool radius_psk;
+ int akm;
};
@@ -153,6 +157,13 @@ static int hostapd_radius_acl_query(stru
goto fail;
}
+ if (query->akm &&
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_AKM_SUITE,
+ wpa_akm_to_suite(query->akm))) {
+ wpa_printf(MSG_DEBUG, "Could not add WLAN-AKM-Suite");
+ goto fail;
+ }
+
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
goto fail;
return 0;
@@ -566,17 +577,40 @@ hostapd_acl_recv_radius(struct radius_ms
cache->next = hapd->acl_cache;
hapd->acl_cache = cache;
+ if (query->radius_psk) {
+ struct sta_info *sta;
+ bool success = cache->accepted == HOSTAPD_ACL_ACCEPT;
+
+ sta = ap_get_sta(hapd, query->addr);
+ if (!sta || !sta->wpa_sm) {
+ wpa_printf(MSG_DEBUG,
+ "No STA/SM entry found for the RADIUS PSK response");
+ goto done;
+ }
+#ifdef NEED_AP_MLME
+ if (success &&
+ (ieee802_11_set_radius_info(hapd, sta, cache->accepted,
+ info) < 0 ||
+ ap_sta_bind_vlan(hapd, sta) < 0))
+ success = false;
+#endif /* NEED_AP_MLME */
+ wpa_auth_sta_radius_psk_resp(sta->wpa_sm, success);
+ } else {
#ifdef CONFIG_DRIVER_RADIUS_ACL
- hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
- info->session_timeout);
+ hostapd_drv_set_radius_acl_auth(hapd, query->addr,
+ cache->accepted,
+ info->session_timeout);
#else /* CONFIG_DRIVER_RADIUS_ACL */
#ifdef NEED_AP_MLME
- /* Re-send original authentication frame for 802.11 processing */
- wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
- "successful RADIUS ACL query");
- ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL);
+ /* Re-send original authentication frame for 802.11 processing
+ */
+ wpa_printf(MSG_DEBUG,
+ "Re-sending authentication frame after successful RADIUS ACL query");
+ ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len,
+ NULL);
#endif /* NEED_AP_MLME */
#endif /* CONFIG_DRIVER_RADIUS_ACL */
+ }
done:
if (prev == NULL)
@@ -658,3 +692,31 @@ void hostapd_free_psk_list(struct hostap
os_free(prev);
}
}
+
+
+#ifndef CONFIG_NO_RADIUS
+void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
+ int key_mgmt, const u8 *anonce,
+ const u8 *eapol, size_t eapol_len)
+{
+ struct hostapd_acl_query_data *query;
+
+ query = os_zalloc(sizeof(*query));
+ if (!query)
+ return;
+
+ query->radius_psk = true;
+ query->akm = key_mgmt;
+ os_get_reltime(&query->timestamp);
+ os_memcpy(query->addr, addr, ETH_ALEN);
+ if (hostapd_radius_acl_query(hapd, addr, query)) {
+ wpa_printf(MSG_DEBUG,
+ "Failed to send Access-Request for RADIUS PSK/ACL query");
+ hostapd_acl_query_free(query);
+ return;
+ }
+
+ query->next = hapd->acl_queries;
+ hapd->acl_queries = query;
+}
+#endif /* CONFIG_NO_RADIUS */
--- a/src/ap/ieee802_11_auth.h
+++ b/src/ap/ieee802_11_auth.h
@@ -1,6 +1,6 @@
/*
* hostapd / IEEE 802.11 authentication (ACL)
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -36,5 +36,8 @@ void hostapd_free_psk_list(struct hostap
void hostapd_acl_expire(struct hostapd_data *hapd);
void hostapd_copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
struct hostapd_sta_wpa_psk_short *src);
+void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
+ int key_mgmt, const u8 *anonce,
+ const u8 *eapol, size_t eapol_len);
#endif /* IEEE802_11_AUTH_H */
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1,6 +1,6 @@
/*
* IEEE 802.11 RSN / WPA Authenticator
- * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -1465,6 +1465,12 @@ static void wpa_send_eapol_timeout(void
struct wpa_authenticator *wpa_auth = eloop_ctx;
struct wpa_state_machine *sm = timeout_ctx;
+ if (sm->waiting_radius_psk) {
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
+ "Ignore EAPOL-Key timeout while waiting for RADIUS PSK");
+ return;
+ }
+
sm->pending_1_of_4_timeout = 0;
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout");
sm->TimeoutEvt = true;
@@ -3003,6 +3009,19 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
break;
}
+ if (!ok && wpa_key_mgmt_wpa_psk_no_sae(sm->wpa_key_mgmt) &&
+ wpa_auth->conf.radius_psk && wpa_auth->cb->request_radius_psk &&
+ !sm->waiting_radius_psk) {
+ wpa_printf(MSG_DEBUG, "No PSK available - ask RADIUS server");
+ wpa_auth->cb->request_radius_psk(wpa_auth->cb_ctx, sm->addr,
+ sm->wpa_key_mgmt,
+ sm->ANonce,
+ sm->last_rx_eapol_key,
+ sm->last_rx_eapol_key_len);
+ sm->waiting_radius_psk = 1;
+ return;
+ }
+
if (!ok) {
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
"invalid MIC in msg 2/4 of 4-Way Handshake");
@@ -3758,6 +3777,11 @@ SM_STEP(WPA_PTK)
} else if (wpa_auth_uses_sae(sm) && sm->pmksa) {
SM_ENTER(WPA_PTK, PTKSTART);
#endif /* CONFIG_SAE */
+ } else if (wpa_key_mgmt_wpa_psk_no_sae(sm->wpa_key_mgmt) &&
+ wpa_auth->conf.radius_psk) {
+ wpa_printf(MSG_DEBUG,
+ "INITPSK: No PSK yet available for STA - use RADIUS later");
+ SM_ENTER(WPA_PTK, PTKSTART);
} else {
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
"no PSK configured for the STA");
@@ -5661,3 +5685,28 @@ void wpa_auth_set_ocv_override_freq(stru
}
#endif /* CONFIG_TESTING_OPTIONS */
+
+
+void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success)
+{
+ if (!sm->waiting_radius_psk) {
+ wpa_printf(MSG_DEBUG,
+ "Ignore RADIUS PSK response for " MACSTR
+ " that did not wait one",
+ MAC2STR(sm->addr));
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "RADIUS PSK response for " MACSTR " (%s)",
+ MAC2STR(sm->addr), success ? "success" : "fail");
+ sm->waiting_radius_psk = 0;
+
+ if (success) {
+ /* Try to process the EAPOL-Key msg 2/4 again */
+ sm->EAPOLKeyReceived = true;
+ } else {
+ sm->Disconnect = true;
+ }
+
+ eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
+}
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -1,6 +1,6 @@
/*
* hostapd - IEEE 802.11i-2004 / WPA Authenticator
- * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -273,6 +273,8 @@ struct wpa_auth_config {
* PTK derivation regardless of advertised capabilities.
*/
bool force_kdk_derivation;
+
+ bool radius_psk;
};
typedef enum {
@@ -320,6 +322,9 @@ struct wpa_auth_callbacks {
void (*store_ptksa)(void *ctx, const u8 *addr, int cipher,
u32 life_time, const struct wpa_ptk *ptk);
void (*clear_ptksa)(void *ctx, const u8 *addr, int cipher);
+ void (*request_radius_psk)(void *ctx, const u8 *addr, int key_mgmt,
+ const u8 *anonce,
+ const u8 *eapol, size_t eapol_len);
#ifdef CONFIG_IEEE80211R_AP
struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
@@ -567,4 +572,6 @@ void wpa_auth_set_ocv_override_freq(stru
enum wpa_auth_ocv_override_frame frame,
unsigned int freq);
+void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success);
+
#endif /* WPA_AUTH_H */
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -1,6 +1,6 @@
/*
* hostapd / WPA authenticator glue code
- * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -29,6 +29,7 @@
#include "ap_drv_ops.h"
#include "ap_config.h"
#include "ieee802_11.h"
+#include "ieee802_11_auth.h"
#include "pmksa_cache_auth.h"
#include "wpa_auth.h"
#include "wpa_auth_glue.h"
@@ -214,6 +215,8 @@ static void hostapd_wpa_auth_conf(struct
wconf->force_kdk_derivation = conf->force_kdk_derivation;
#endif /* CONFIG_TESTING_OPTIONS */
#endif /* CONFIG_PASN */
+
+ wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS;
}
@@ -1435,6 +1438,23 @@ static void hostapd_wpa_unregister_ft_ou
#endif /* CONFIG_IEEE80211R_AP */
+#ifndef CONFIG_NO_RADIUS
+static void hostapd_request_radius_psk(void *ctx, const u8 *addr, int key_mgmt,
+ const u8 *anonce,
+ const u8 *eapol, size_t eapol_len)
+{
+ struct hostapd_data *hapd = ctx;
+
+ wpa_printf(MSG_DEBUG, "RADIUS PSK request for " MACSTR " key_mgmt=0x%x",
+ MAC2STR(addr), key_mgmt);
+ wpa_hexdump(MSG_DEBUG, "ANonce", anonce, WPA_NONCE_LEN);
+ wpa_hexdump(MSG_DEBUG, "EAPOL", eapol, eapol_len);
+ hostapd_acl_req_radius_psk(hapd, addr, key_mgmt, anonce, eapol,
+ eapol_len);
+}
+#endif /* CONFIG_NO_RADIUS */
+
+
int hostapd_setup_wpa(struct hostapd_data *hapd)
{
struct wpa_auth_config _conf;
@@ -1478,6 +1498,9 @@ int hostapd_setup_wpa(struct hostapd_dat
.set_session_timeout = hostapd_wpa_auth_set_session_timeout,
.get_session_timeout = hostapd_wpa_auth_get_session_timeout,
#endif /* CONFIG_IEEE80211R_AP */
+#ifndef CONFIG_NO_RADIUS
+ .request_radius_psk = hostapd_request_radius_psk,
+#endif /* CONFIG_NO_RADIUS */
};
const u8 *wpa_ie;
size_t wpa_ie_len;
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -89,6 +89,7 @@ struct wpa_state_machine {
unsigned int rx_eapol_key_secure:1;
unsigned int update_snonce:1;
unsigned int alt_snonce_valid:1;
+ unsigned int waiting_radius_psk:1;
#ifdef CONFIG_IEEE80211R_AP
unsigned int ft_completed:1;
unsigned int pmk_r1_name_valid:1;

View File

@@ -0,0 +1,716 @@
From 57342b4c68d80754c3b6e1df4af1a46afc936a90 Mon Sep 17 00:00:00 2001
From: Hari Chandrakanthan <quic_haric@quicinc.com>
Date: Wed, 1 Dec 2021 21:27:36 +0530
Subject: [PATCH] hostapd : Add support to awgn mitigation for 6Ghz
when awgn interference is detected on operating channel,
AP is supposed to stop transmitting in that channel.
AP can reduce it's operating bandwidth or
completely move to another channel based on the
interference segment.
hostapd receives awgn notification through NL80211_CMD_AWGN_DETECT
cmd and the NL attribute NL80211_ATTR_AWGN_INTERFERENCE_BITMAP
provides the channel interference information.
Eg: For 80Mhz operating bandwidth, the chan bw interference
bitmap can be as follows.
segment chan_bw_interference_bitmap
0 0x01
1 0x02
2 0x04
3 0x08
segment 0 - primary 20Mhz
segment 1 - secondary 20Mhz
segment 2 - secondary 40Mhz lower
segment 3 - secondary 40Mhz upper
Signed-off-by: Hari Chandrakanthan <quic_haric@quicinc.com>
---
hostapd/Makefile | 1 +
src/ap/Makefile | 1 +
src/ap/drv_callbacks.c | 13 ++
src/ap/interference.c | 387 +++++++++++++++++++++++++++++++++++++
src/ap/interference.h | 41 ++++
src/drivers/driver.h | 13 ++
src/drivers/driver_common.c | 1 +
src/drivers/driver_nl80211_event.c | 30 +++
src/drivers/nl80211_copy.h | 13 ++
wpa_supplicant/Makefile | 1 +
10 files changed, 501 insertions(+)
create mode 100644 src/ap/interference.c
create mode 100644 src/ap/interference.h
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -1186,6 +1186,7 @@ OBJS += ../src/ap/ap_list.o
OBJS += ../src/ap/ieee802_11.o
OBJS += ../src/ap/hw_features.o
OBJS += ../src/ap/dfs.o
+OBJS += ../src/ap/interference.o
CFLAGS += -DNEED_AP_MLME
endif
OBJS += ../src/ap/ieee802_11_ht.o
--- a/src/ap/Makefile
+++ b/src/ap/Makefile
@@ -36,6 +36,7 @@ LIB_OBJS= \
ieee802_11_shared.o \
ieee802_11_vht.o \
ieee802_1x.o \
+ interference.o \
neighbor_db.o \
ndisc_snoop.o \
p2p_hostapd.o \
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -43,6 +43,7 @@
#include "dpp_hostapd.h"
#include "fils_hlp.h"
#include "neighbor_db.h"
+#include "interference.h"
#ifdef CONFIG_FILS
void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
@@ -1685,6 +1686,13 @@ static void hostapd_event_dfs_radar_dete
radar->cf1, radar->cf2);
}
+static void hostapd_event_awgn_detected(struct hostapd_data *hapd,
+ struct awgn_event *awgn_info)
+{
+ hostapd_intf_awgn_detected(hapd->iface, awgn_info->freq, awgn_info->chan_width,
+ awgn_info->cf1, awgn_info->cf2,
+ awgn_info->chan_bw_interference_bitmap);
+}
static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd,
struct dfs_event *radar)
@@ -2069,6 +2077,11 @@ void hostapd_wpa_event(void *ctx, enum w
break;
hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
break;
+ case EVENT_AWGN_DETECTED:
+ if (!data)
+ break;
+ hostapd_event_awgn_detected(hapd, &data->awgn_event);
+ break;
case EVENT_DFS_PRE_CAC_EXPIRED:
if (!data)
break;
--- /dev/null
+++ b/src/ap/interference.c
@@ -0,0 +1,393 @@
+/*
+ * AWGN - Additive white Gaussian Noise
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2013-2017, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided that
+ * the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "common/ieee802_11_defs.h"
+#include "common/hw_features_common.h"
+#include "common/wpa_ctrl.h"
+#include "hostapd.h"
+#include "ap_drv_ops.h"
+#include "drivers/driver.h"
+#include "beacon.h"
+#include "eloop.h"
+#include "hw_features.h"
+
+/*
+ * intf_awgn_chan_range_available - check whether the channel can operate
+ * in the given bandwidth in 6Ghz
+ * @first_chan_idx - channel index of the first 20Mhz channel in a segment
+ * @num_chans - number of 20Mhz channels needed for the operating bandwidth
+ */
+static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode,
+ int first_chan_idx, int num_chans)
+{
+ struct hostapd_channel_data *first_chan = NULL;
+ int allowed_40_6g[] = {1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105,
+ 113, 121, 129, 137, 145, 153, 161, 169, 177, 185, 193,
+ 201, 209, 217, 225, 233};
+ int allowed_80_6g[] = {1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177,
+ 193, 209};
+ int allowed_160_6g[] = {1, 33, 65, 97, 129, 161, 193};
+ int chan_idx_match = 0;
+ int i;
+
+ first_chan = &mode->channels[first_chan_idx];
+
+ if (!first_chan || !chan_pri_allowed(first_chan)) {
+ wpa_printf(MSG_DEBUG, "AWGN: primary channel not allowed");
+ return 0;
+ }
+
+ /* 20Mhz channel, so no need to check the range */
+ if (num_chans == 1)
+ return 1;
+
+ if (num_chans == 2) { /* 40Mhz channel */
+ for (i = 0; i < ARRAY_SIZE(allowed_40_6g); i++) {
+ if (first_chan->chan == allowed_40_6g[i]) {
+ chan_idx_match = 1;
+ break;
+ }
+ }
+ } else if (num_chans == 4) { /* 80Mhz channel */
+ for (i = 0; i < ARRAY_SIZE(allowed_80_6g); i++) {
+ if (first_chan->chan == allowed_80_6g[i]) {
+ chan_idx_match = 1;
+ break;
+ }
+ }
+ } else if (num_chans == 8) { /* 160Mhz channel */
+ for (i = 0; i < ARRAY_SIZE(allowed_160_6g); i++) {
+ if (first_chan->chan == allowed_160_6g[i]) {
+ chan_idx_match = 1;
+ break;
+ }
+ }
+ }
+
+ if (chan_idx_match == 1)
+ return 1;
+
+ return 0;
+}
+
+static int is_in_chanlist(struct hostapd_iface *iface,
+ struct hostapd_channel_data *chan)
+{
+ if (!iface->conf->acs_ch_list.num)
+ return 1;
+
+ return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan);
+}
+
+/*
+ *intf_awgn_find_channel - find the channel that can operate with bandwidth chan_width.
+ If idx doesn't match with index of any of the existing channel, then the api
+ returns the total number of available chandefs that supports the provided bandwidth
+ * @idx - index of the channel
+ * @chan_width - bandwidth of the channel
+ */
+static int intf_awgn_find_channel(struct hostapd_iface *iface,
+ struct hostapd_channel_data **ret_chan,
+ int idx, int chan_width)
+{
+ struct hostapd_hw_modes *mode = iface->current_mode;
+ struct hostapd_channel_data *chan;
+ int i, channel_idx = 0, n_chans;
+
+ switch (chan_width) {
+ case CHAN_WIDTH_20_NOHT:
+ case CHAN_WIDTH_20:
+ n_chans = 1;
+ break;
+ case CHAN_WIDTH_40:
+ n_chans = 2;
+ break;
+ case CHAN_WIDTH_80:
+ n_chans = 4;
+ break;
+ case CHAN_WIDTH_80P80:
+ case CHAN_WIDTH_160:
+ n_chans = 8;
+ break;
+ default:
+ n_chans = 1;
+ break;
+ }
+
+ for (i = 0; i < mode->num_channels; i++) {
+ chan = &mode->channels[i];
+
+ /* Skip incompatible chandefs */
+ if (!intf_awgn_chan_range_available(mode, i, n_chans)) {
+ wpa_printf(MSG_DEBUG,
+ "AWGN: range not available for %d (%d)",
+ chan->freq, chan->chan);
+ continue;
+ }
+
+ if (!is_in_chanlist(iface, chan)) {
+ wpa_printf(MSG_DEBUG,
+ "AWGN: channel %d (%d) not in chanlist",
+ chan->freq, chan->chan);
+ continue;
+ }
+
+ if (ret_chan && idx == channel_idx) {
+ wpa_printf(MSG_DEBUG, "AWGN: Selected channel %d (%d)",
+ chan->freq, chan->chan);
+ *ret_chan = chan;
+ return idx;
+ }
+
+ wpa_printf(MSG_DEBUG, "AWGN: Adding channel %d (%d)",
+ chan->freq, chan->chan);
+ channel_idx++;
+ }
+ return channel_idx;
+}
+
+enum chan_seg {
+ SEG_PRI20 = 0x1,
+ SEG_SEC20 = 0x2,
+ SEG_SEC40_LOWER = 0x4,
+ SEG_SEC40_UPPER = 0x8,
+ SEG_SEC40 = 0xC,
+ SEG_SEC80_LOWER = 0x10,
+ SEG_SEC80_LOWER_UPPER = 0x20,
+ SEG_SEC80_UPPER_LOWER = 0x40,
+ SEG_SEC80_UPPER = 0x80,
+ SEG_SEC80 = 0xF0,
+};
+
+#define BASE_6G_FREQ 5950
+
+int get_centre_freq_6g(int chan_idx, int chan_width, int *centre_freq)
+{
+ if (!centre_freq)
+ return -1;
+
+ *centre_freq = 0;
+
+ switch (chan_width) {
+ case CHAN_WIDTH_40:
+ if (chan_idx >= 1 && chan_idx <= 229)
+ *centre_freq = ((chan_idx / 8) * 8 + 3) * 5 + BASE_6G_FREQ;
+ break;
+ case CHAN_WIDTH_80:
+ if (chan_idx >= 1 && chan_idx <= 221)
+ *centre_freq = ((chan_idx / 16) * 16 + 7) * 5 + BASE_6G_FREQ;
+ break;
+ case CHAN_WIDTH_160:
+ if (chan_idx >= 1 && chan_idx <= 221)
+ *centre_freq = ((chan_idx / 32) * 32 + 15) * 5 + BASE_6G_FREQ;
+ break;
+ default:
+ break;
+ }
+
+ if (*centre_freq == 0)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * hostapd_intf_awgn_detected - awgn interference is detected in the operating channel.
+ * The interference channel information is available as a
+ * bitmap(chan_bw_interference_bitmap). If interference has occurred in the
+ * primary channel, do a complete channel switch to a different channel else
+ * reduce the operating bandwidth and continue ap operation in the same channel.
+ */
+int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_width,
+ int cf1, int cf2, u32 chan_bw_interference_bitmap)
+{
+ struct csa_settings settings;
+ struct hostapd_channel_data *chan_data = NULL;
+ struct hostapd_channel_data *chan_temp = NULL;
+ int ret;
+ unsigned int i;
+ u32 _rand;
+ u32 chan_idx;
+ int num_available_chandefs;
+ u8 channel_switch = 0;
+ int new_chan_width;
+ int new_centre_freq;
+ struct hostapd_hw_modes *mode = iface->current_mode;
+
+ wpa_printf(MSG_DEBUG,
+ "input freq=%d, chan_width=%d, cf1=%d cf2=%d"
+ " chan_bw_interference_bitmap=0x%x",
+ freq,
+ chan_width,
+ cf1, cf2, chan_bw_interference_bitmap);
+
+ if (iface->conf->discard_6g_awgn_event) {
+ wpa_printf(MSG_DEBUG, "discard_6g_awgn_event set ignoring"
+ "AWGN DETECT event from driver");
+ return 0;
+ }
+
+ /* check whether interference has occurred in primary 20Mhz channel */
+ if (!chan_bw_interference_bitmap || (chan_bw_interference_bitmap & SEG_PRI20))
+ channel_switch = 1;
+
+ if (channel_switch) {
+ /* Find a random channel to be switched */
+ num_available_chandefs = intf_awgn_find_channel(iface, NULL, 0,
+ chan_width);
+ if (num_available_chandefs == 0) {
+ wpa_printf(MSG_ERROR, "AWGN: no available_chandefs");
+ return 0;
+ }
+
+ if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0) {
+ wpa_printf(MSG_ERROR, "AWGN: couldn't get random number");
+ return 0;
+ }
+
+ chan_idx = _rand % num_available_chandefs;
+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width);
+
+ if (!chan_data) {
+ wpa_printf(MSG_ERROR, "AWGN: no random channel found, chan idx : %d",
+ chan_idx);
+ return 0;
+ }
+
+ if(chan_data->freq == freq) {
+ /* New random channel is same as operating channel
+ * so choose another channel
+ */
+ chan_data = NULL;
+ chan_idx = (chan_idx + 1) % num_available_chandefs;
+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width);
+ if (!chan_data) {
+ wpa_printf(MSG_ERROR,
+ "AWGN: random channel not found, chan idx : %d",
+ chan_idx);
+ return 0;
+ }
+ }
+
+ wpa_printf(MSG_DEBUG, "AWGN: got random channel %d (%d)",
+ chan_data->freq, chan_data->chan);
+ new_chan_width = chan_width;
+ } else {
+ /* interference is not present in the primary 20Mhz, so reduce bandwidth*/
+ for (i = 0; i < mode->num_channels; i++) {
+ chan_temp = &mode->channels[i];
+ if (chan_temp->freq == freq)
+ chan_data = chan_temp;
+ }
+ if (!chan_data) {
+ wpa_printf(MSG_ERROR, "AWGN : no channel found");
+ return 0;
+ }
+
+ if ((chan_width > CHAN_WIDTH_80) &&
+ !(chan_bw_interference_bitmap & SEG_SEC40) &&
+ !(chan_bw_interference_bitmap & SEG_SEC20))
+ new_chan_width = CHAN_WIDTH_80;
+ else if (chan_width > CHAN_WIDTH_40 &&
+ !(chan_bw_interference_bitmap & SEG_SEC20))
+ new_chan_width = CHAN_WIDTH_40;
+ else
+ new_chan_width = CHAN_WIDTH_20;
+ }
+
+ if (new_chan_width > CHAN_WIDTH_20) {
+ ret = get_centre_freq_6g(chan_data->chan, new_chan_width,
+ &new_centre_freq);
+ if (ret) {
+ wpa_printf(MSG_ERROR,
+ "AWGN : couldn't find centre freq for chan : %d"
+ " chan_width : %d", chan_data->chan, new_chan_width);
+ return 0;
+ }
+ } else {
+ new_centre_freq = chan_data->freq;
+ }
+
+ os_memset(&settings, 0, sizeof(settings));
+ settings.cs_count = 5;
+ settings.freq_params.freq = chan_data->freq;
+
+ switch (new_chan_width) {
+ case CHAN_WIDTH_40:
+ settings.freq_params.bandwidth = 40;
+ break;
+ case CHAN_WIDTH_80P80:
+ case CHAN_WIDTH_80:
+ settings.freq_params.bandwidth = 80;
+ break;
+ case CHAN_WIDTH_160:
+ settings.freq_params.bandwidth = 160;
+ break;
+ default:
+ settings.freq_params.bandwidth = 20;
+ break;
+ }
+
+ settings.freq_params.center_freq1 = new_centre_freq;
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
+
+ for (i = 0; i < iface->num_bss; i++) {
+ /* Save CHAN_SWITCH VHT and HE config */
+ hostapd_chan_switch_config(iface->bss[i],
+ &settings.freq_params);
+
+ wpa_printf(MSG_DEBUG,
+ "channel=%u, freq=%d, bw=%d, center_freq1=%d",
+ settings.freq_params.channel,
+ settings.freq_params.freq,
+ settings.freq_params.bandwidth,
+ settings.freq_params.center_freq1);
+
+ ret = hostapd_switch_channel(iface->bss[i], &settings);
+ if (ret) {
+ /* FIX: What do we do if CSA fails in the middle of
+ * submitting multi-BSS CSA requests?
+ */
+ return ret;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+++ b/src/ap/interference.h
@@ -0,0 +1,41 @@
+/*
+ * INTF - Interference
+ * AWGN - Additive white Gaussian Noise
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2013-2017, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided that
+ * the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq,
+ int chan_width,
+ int cf1, int cf2,
+ u32 chan_bw_interference_bitmap);
+
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -5264,6 +5264,7 @@ enum wpa_event_type {
* EVENT_CCA_NOTIFY - Notification that CCA has completed
*/
EVENT_CCA_NOTIFY,
+ EVENT_AWGN_DETECTED,
};
@@ -6173,6 +6174,18 @@ union wpa_event_data {
struct bss_color_collision {
u64 bitmap;
} bss_color_collision;
+
+ /**
+ * Data for EVENT_AWGN
+ */
+ struct awgn_event {
+ int freq;
+ enum chan_width chan_width;
+ int cf1;
+ int cf2;
+ u32 chan_bw_interference_bitmap;
+ } awgn_event;
+
};
/**
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -95,6 +95,7 @@ const char * event_to_string(enum wpa_ev
E2S(CCA_STARTED_NOTIFY);
E2S(CCA_ABORTED_NOTIFY);
E2S(CCA_NOTIFY);
+ E2S(AWGN_DETECTED);
}
return "UNKNOWN";
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -149,6 +149,7 @@ static const char * nl80211_command_to_s
C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_STARTED)
C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED)
C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED)
+ C2S(NL80211_CMD_AWGN_DETECT)
default:
return "NL80211_CMD_UNKNOWN";
}
@@ -1821,6 +1822,32 @@ static void nl80211_radar_event(struct w
}
}
+static void nl80211_awgn_event(struct wpa_driver_nl80211_data *drv,
+ struct nlattr **tb)
+{
+ union wpa_event_data data;
+
+ os_memset(&data, 0, sizeof(data));
+
+ if (tb[NL80211_ATTR_WIPHY_FREQ])
+ data.awgn_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
+
+ if (tb[NL80211_ATTR_CHANNEL_WIDTH])
+ data.awgn_event.chan_width =
+ convert2width(nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
+
+ if (tb[NL80211_ATTR_CENTER_FREQ1])
+ data.awgn_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
+
+ if (tb[NL80211_ATTR_CENTER_FREQ2])
+ data.awgn_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
+
+ if (tb[NL80211_ATTR_AWGN_INTERFERENCE_BITMAP])
+ data.awgn_event.chan_bw_interference_bitmap =
+ nla_get_u32(tb[NL80211_ATTR_AWGN_INTERFERENCE_BITMAP]);
+
+ wpa_supplicant_event(drv->ctx, EVENT_AWGN_DETECTED, &data);
+}
static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
int wds)
@@ -3077,6 +3104,9 @@ static void do_process_drv_event(struct
mlme_event_color_change_announcement_completed(drv);
break;
#endif
+ case NL80211_CMD_AWGN_DETECT:
+ nl80211_awgn_event(drv, tb);
+ break;
default:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
"(cmd=%d)", cmd);
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -1192,6 +1192,9 @@
*
* @NL80211_CMD_SET_UNSOL_BCAST_PROBE_RESP: Command to set unsolicited
* broadcast probe response transmission parameters.
+ * @NL80211_CMD_AWGN_DETECT: Once AWGN interference is detected on the operating
+ * channel, userspace is notified with the interference bitmap using
+ * %NL80211_ATTR_AWGN_INTERFERENCE_BITMAP
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
@@ -1437,6 +1440,7 @@ enum nl80211_commands {
NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED,
NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED,
+ NL80211_CMD_AWGN_DETECT,
/* add new commands above here */
@@ -2612,6 +2616,9 @@ enum nl80211_commands {
* staggered mode or burst mode in %NL80211_CMD_START_AP from
* user-space.
*
+ * @NL80211_ATTR_AWGN_INTERFERENCE_BITMAP: u32 attribute specifying the
+ * interference bitmap of operating bandwidth for %NL80211_CMD_AWGN_DETECT
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3127,6 +3134,12 @@ enum nl80211_attrs {
NL80211_ATTR_BEACON_TX_MODE,
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+
+ NL80211_ATTR_STA_MGMT_RTS_CTS_CONFIG,
+
+ NL80211_ATTR_AWGN_INTERFERENCE_BITMAP,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -964,6 +964,7 @@ OBJS += ../src/ap/ap_list.o
OBJS += ../src/ap/ieee802_11.o
OBJS += ../src/ap/hw_features.o
OBJS += ../src/ap/dfs.o
+OBJS += ../src/ap/interference.o
CFLAGS += -DNEED_AP_MLME
endif
ifdef CONFIG_WPS
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3536,6 +3536,8 @@ static int hostapd_config_fill(struct ho
bss->unsol_bcast_probe_resp_interval = val;
} else if (os_strcmp(buf, "he_co_locate") == 0) {
conf->he_co_locate = atoi(pos);
+ } else if (os_strcmp(buf, "discard_6g_awgn_event") == 0) {
+ conf->discard_6g_awgn_event = atoi(pos);
#endif /* CONFIG_IEEE80211AX */
} else if (os_strcmp(buf, "max_listen_interval") == 0) {
bss->max_listen_interval = atoi(pos);
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -277,6 +277,7 @@ struct hostapd_config * hostapd_config_d
conf->he_6ghz_max_ampdu_len_exp = 7;
conf->he_6ghz_rx_ant_pat = 1;
conf->he_6ghz_tx_ant_pat = 1;
+ conf->discard_6g_awgn_event = 0;
#endif /* CONFIG_IEEE80211AX */
/* The third octet of the country string uses an ASCII space character
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1077,6 +1077,7 @@ struct hostapd_config {
u8 he_6ghz_rx_ant_pat;
u8 he_6ghz_tx_ant_pat;
bool he_co_locate;
+ bool discard_6g_awgn_event;
#define AP_TYPE_6GHZ_INDOOR_AP 0
#define AP_TYPE_6GHZ_STANDARD_POWER_AP 1
#define AP_TYPE_6GHZ_VERY_LOW_POWER_AP 2

View File

@@ -0,0 +1,564 @@
From 404211da041eef5ddfc52515048b04c70ef8579c Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Thu, 21 Oct 2021 12:51:38 +0530
Subject: [PATCH] hostapd: add support for 6GHz operation
6 GHz gives users ability to select the AP mode from LPI, SP and
VLP modes. This mode needs to be passed on to the cfg80211
for further processing during AP bring up. Also, the regulatory
rules received by hostapd contains psd values for 6G rules.
Hostapd needs to store these values in order to later advertise
it in the tx power element in the beacon.
This patch adds the support to send the user configured 6g power
type during set_channel command and as well to get and store the
psd values from reg rules which will be later on used in tpe
advertisement during beacon formation.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
src/ap/ap_drv_ops.c | 9 ++++++---
src/ap/beacon.c | 9 +++++++--
src/ap/dfs.c | 6 ++++--
src/ap/hostapd.c | 2 +-
src/ap/ieee802_11.c | 13 ++++++++++++-
src/ap/ieee802_11_he.c | 10 ++++++++--
src/common/hw_features_common.c | 4 +++-
src/common/hw_features_common.h | 2 +-
src/common/ieee802_11_defs.h | 14 ++++++++++++++
src/drivers/driver.h | 20 +++++++++++++++++++-
src/drivers/driver_hostap.c | 3 ++-
src/drivers/driver_nl80211.c | 15 ++++++++++++++-
src/drivers/driver_nl80211.h | 2 +-
src/drivers/driver_nl80211_capa.c | 28 +++++++++++++++++++++++-----
src/drivers/driver_nl80211_event.c | 2 +-
src/drivers/nl80211_copy.h | 19 +++++++++++++++++++
wpa_supplicant/driver_i.h | 2 +-
wpa_supplicant/mesh.c | 2 +-
wpa_supplicant/wpa_supplicant.c | 2 +-
19 files changed, 138 insertions(+), 26 deletions(-)
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -563,7 +563,8 @@ int hostapd_set_freq(struct hostapd_data
center_segment0, center_segment1,
cmode ? cmode->vht_capab : 0,
cmode ?
- &cmode->he_capab[IEEE80211_MODE_AP] : NULL))
+ &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
+ hapd->iconf->he_6ghz_reg_pwr_type))
return -1;
if (hapd->driver == NULL)
@@ -636,7 +637,8 @@ hostapd_get_hw_feature_data(struct hosta
hapd->driver->get_hw_feature_data == NULL)
return NULL;
return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
- flags, dfs_domain);
+ flags, dfs_domain,
+ hapd->iconf->he_6ghz_reg_pwr_type);
}
@@ -836,7 +838,8 @@ int hostapd_start_dfs_cac(struct hostapd
oper_chwidth, center_segment0,
center_segment1,
cmode->vht_capab,
- &cmode->he_capab[IEEE80211_MODE_AP])) {
+ &cmode->he_capab[IEEE80211_MODE_AP],
+ hapd->iconf->he_6ghz_reg_pwr_type)) {
wpa_printf(MSG_ERROR, "Can't set freq params");
return -1;
}
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1571,7 +1571,11 @@ int ieee802_11_build_ap_params(struct ho
if (is_6ghz_op_class(hapd->iconf->op_class)) {
tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
3 + sizeof(struct ieee80211_he_6ghz_band_cap);
- /* Additional TX Power envelope for subordinate client */
+ /* Additional TX Power envelope for subordinate client
+ * Currently as per the spec, only AP LP mode should send
+ * the tpe for subordinate client. SP mode should not and
+ * no standard set yet for VLP mode.
+ */
if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) ==
AP_TYPE_6GHZ_INDOOR_AP)
tail_len += 4;
@@ -2012,7 +2016,8 @@ static int __ieee802_11_set_beacon(struc
hostapd_get_oper_centr_freq_seg0_idx(iconf),
hostapd_get_oper_centr_freq_seg1_idx(iconf),
cmode->vht_capab,
- &cmode->he_capab[IEEE80211_MODE_AP]) == 0)
+ &cmode->he_capab[IEEE80211_MODE_AP],
+ iconf->he_6ghz_reg_pwr_type) == 0)
params.freq = &freq;
res = hostapd_drv_set_ap(hapd, &params);
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1086,7 +1086,8 @@ static int hostapd_dfs_testmode_set_beac
vht_oper_centr_freq_seg0_idx,
vht_oper_centr_freq_seg1_idx,
iface->current_mode->vht_capab,
- &iface->current_mode->he_capab[IEEE80211_MODE_AP]);
+ &iface->current_mode->he_capab[IEEE80211_MODE_AP],
+ hapd->iconf->he_6ghz_reg_pwr_type);
if (err) {
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
@@ -1227,7 +1228,8 @@ 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]);
+ &cmode->he_capab[ieee80211_mode],
+ iface->conf->he_6ghz_reg_pwr_type);
if (err) {
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -3503,7 +3503,7 @@ static int hostapd_change_config_freq(st
hostapd_get_oper_centr_freq_seg1_idx(conf),
conf->vht_capab,
mode ? &mode->he_capab[IEEE80211_MODE_AP] :
- NULL))
+ NULL, hapd->iconf->he_6ghz_reg_pwr_type))
return -1;
switch (params->bandwidth) {
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -6927,6 +6927,8 @@ u8 * hostapd_eid_txpower_envelope(struct
int dfs, i;
u8 channel, tx_pwr_count, local_pwr_constraint;
u8 tx_pwr, tx_pwr_intrpn, tx_pwr_cat, ap_type;
+ s8 psd;
+
int max_tx_power;
if (!mode)
@@ -6963,15 +6965,24 @@ u8 * hostapd_eid_txpower_envelope(struct
*/
if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) {
tx_pwr_cat = REG_SUBORDINATE_CLIENT;
- /* TODO: extract psd limits from channel data */
+ psd = mode->psd_values[NL80211_REG_SUBORDINATE_CLIENT_LPI + ap_type];
+#ifdef REG_DOM_SUPPORT_TX_POWER
+ tx_pwr = psd * 2;
+#else
tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2);
+#endif /* REG_DOM_SUPPORT_TX_POWER */
eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn,
tx_pwr_cat, tx_pwr);
}
/* Default Tx Power envelope for Global Operating class */
tx_pwr_cat = REG_DEFAULT_CLIENT;
+ psd = mode->psd_values[NL80211_REG_REGULAR_CLIENT_LPI + ap_type];
+#ifdef REG_DOM_SUPPORT_TX_POWER
+ tx_pwr = psd * 2;
+#else
tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2);
+#endif /* REG_DOM_SUPPORT_TX_POWER */
eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr);
return eid;
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -235,10 +235,16 @@ u8 * hostapd_eid_he_operation(struct hos
* - 1 (Standard Power Access Point)
* - Reserved in 5GHz and 2Ghz bands
*/
+
+ u8 ap_type = hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf);
+
if (seg1)
- *pos++ = 3;
+ *pos++ = 3 | (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO &
+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB));
else
- *pos++ = center_idx_to_bw_6ghz(seg0);
+ *pos++ = center_idx_to_bw_6ghz(seg0) |
+ (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO &
+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB));
/* Channel Center Freq Seg0/Seg1 */
if (hapd->iconf->he_oper_chwidth == 2) {
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -403,7 +403,7 @@ int hostapd_set_freq_params(struct hosta
int sec_channel_offset,
int oper_chwidth, int center_segment0,
int center_segment1, u32 vht_caps,
- struct he_capabilities *he_cap)
+ struct he_capabilities *he_cap, u8 reg_6g_pwr_mode)
{
if (!he_cap)
he_enabled = 0;
@@ -486,6 +486,8 @@ int hostapd_set_freq_params(struct hosta
data->ht_enabled = 0;
data->vht_enabled = 0;
+ /* Append 6G reg power info */
+ data->he_6ghz_reg_pwr_type = reg_6g_pwr_mode;
return 0;
}
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -44,7 +44,7 @@ int hostapd_set_freq_params(struct hosta
int sec_channel_offset,
int oper_chwidth, int center_segment0,
int center_segment1, u32 vht_caps,
- struct he_capabilities *he_caps);
+ struct he_capabilities *he_caps, u8 reg_6g_pwr_mode);
void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps,
int disabled);
int ieee80211ac_cap_check(u32 hw, u32 conf);
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1963,6 +1963,17 @@ enum reg_6g_client_type {
/* same Max Tx Pwr for all 20MHz bands */
#define DEFAULT_MAX_TX_POWER_COUNT_6G 0
+
+/*
+ * REG_DOM_SUPPORT_TX_POWER - regulatory domain
+ * supports tx power values or not.
+ *
+ * If this macro is undefined, tx-power macros will be used to
+ * get the tx-power, otherwise psd values from regulatory domain
+ * will be taken
+ */
+#define REG_DOM_SUPPORT_TX_POWER 1
+
/*
* These tx-power macros are present till the 6G regdomains are defined to
* support tx-power values for various client types.
@@ -2350,6 +2361,9 @@ struct ieee80211_spatial_reuse {
#define HE_OPERATION_BSS_COLOR_OFFSET 24
#define HE_OPERATION_BSS_COLOR_MAX 64
+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO 0x38
+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB 3
+
/* Spatial Reuse defines */
#define SPATIAL_REUSE_SRP_DISALLOWED BIT(0)
#define SPATIAL_REUSE_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1)
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -299,6 +299,12 @@ struct hostapd_hw_modes {
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
+
+ /**
+ * This array is used to store the psd value of each power mode
+ * supported in 6G band.
+ */
+ s8 psd_values[NL80211_REG_NUM_POWER_MODES];
};
@@ -777,6 +783,17 @@ struct hostapd_freq_params {
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
+
+ /**
+ * he_6ghz_reg_pwr_type - 6G regulatory power mode
+ * Since many operation related to channel for 6G depends on the
+ * power mode, this parameter is added here.
+ *
+ * 0 - LPI_AP
+ * 1 - SP_AP
+ * 2 - VLP_AP
+ */
+ u8 he_6ghz_reg_pwr_type;
};
/**
@@ -2938,12 +2955,13 @@ struct wpa_driver_ops {
* @num_modes: Variable for returning the number of returned modes
* flags: Variable for returning hardware feature flags
* @dfs: Variable for returning DFS region (HOSTAPD_DFS_REGION_*)
+ * @pwr_mode: Variable required for processing the support data for 6G
* Returns: Pointer to allocated hardware data on success or %NULL on
* failure. Caller is responsible for freeing this.
*/
struct hostapd_hw_modes * (*get_hw_feature_data)(void *priv,
u16 *num_modes,
- u16 *flags, u8 *dfs);
+ u16 *flags, u8 *dfs, u8 pwr_mode);
/**
* send_mlme - Send management frame from MLME
--- a/src/drivers/driver_hostap.c
+++ b/src/drivers/driver_hostap.c
@@ -1099,7 +1099,8 @@ static int hostap_sta_disassoc(void *pri
static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv,
u16 *num_modes,
- u16 *flags, u8 *dfs)
+ u16 *flags, u8 *dfs,
+ u8 pwr_mode)
{
struct hostapd_hw_modes *mode;
int i, clen, rlen;
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5038,6 +5038,19 @@ static int nl80211_set_channel(struct i8
return -1;
}
+#ifdef CONFIG_IEEE80211AX
+ if (freq->freq && is_6ghz_freq(freq->freq)) {
+ wpa_printf(MSG_DEBUG, "%s: 6g_reg_pwr_mode=%d",
+ __func__, freq->he_6ghz_reg_pwr_type);
+ if (nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE,
+ freq->he_6ghz_reg_pwr_type)) {
+ wpa_printf(MSG_ERROR,
+ "%s: Failed to put 6g_reg_pwr_mode", __func__);
+ nlmsg_free(msg);
+ return -1;
+ }
+ }
+#endif /* CONFIG_IEEE80211AX */
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
if (ret == 0) {
bss->freq = freq->freq;
@@ -8303,7 +8316,7 @@ static int wpa_driver_nl80211_send_actio
int i;
modes = nl80211_get_hw_feature_data(bss, &num_modes,
- &flags, &dfs_domain);
+ &flags, &dfs_domain, 0);
if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
ieee80211_is_dfs(bss->freq, modes, num_modes))
offchanok = 0;
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -285,7 +285,7 @@ int nl80211_send_monitor(struct wpa_driv
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv);
struct hostapd_hw_modes *
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
- u8 *dfs_domain);
+ u8 *dfs_domain, u8 pwr_mode);
int process_global_event(struct nl_msg *msg, void *arg);
int process_bss_event(struct nl_msg *msg, void *arg);
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1454,6 +1454,7 @@ struct phy_info_arg {
int last_mode, last_chan_idx;
int failed;
u8 dfs_domain;
+ u8 pwr_mode;
};
static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
@@ -2102,7 +2103,9 @@ static void nl80211_set_ht40_mode_sec(st
static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
- struct phy_info_arg *results)
+ struct phy_info_arg *results,
+ u8 config_pwr_mode, u8 pwr_mode,
+ s8 psd)
{
u16 m;
@@ -2112,10 +2115,16 @@ static void nl80211_reg_rule_max_eirp(u3
for (c = 0; c < mode->num_channels; c++) {
struct hostapd_channel_data *chan = &mode->channels[c];
+
+ if (is_6ghz_freq(chan->freq) && config_pwr_mode != pwr_mode)
+ continue;
+
if ((u32) chan->freq - 10 >= start &&
(u32) chan->freq + 10 <= end)
chan->max_tx_power = max_eirp;
}
+ /* Update the psd rules */
+ mode->psd_values[pwr_mode] = psd;
}
}
@@ -2288,6 +2297,7 @@ static int nl80211_get_reg(struct nl_msg
[NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
};
+ u8 config_pwr_mode = results->pwr_mode;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
@@ -2312,6 +2322,8 @@ static int nl80211_get_reg(struct nl_msg
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
{
u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
+ u8 pwr_mode = 0;
+ s8 psd = 0;
nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
nla_data(nl_rule), nla_len(nl_rule), reg_policy);
if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
@@ -2325,9 +2337,13 @@ static int nl80211_get_reg(struct nl_msg
max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
+ if (tb_rule[NL80211_ATTR_REG_POWER_MODE])
+ pwr_mode = nla_get_u8(tb_rule[NL80211_ATTR_REG_POWER_MODE]);
+ if (tb_rule[NL80211_ATTR_POWER_RULE_PSD])
+ psd = (s8) nla_get_u8(tb_rule[NL80211_ATTR_POWER_RULE_PSD]);
- wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
- start, end, max_bw, max_eirp,
+ wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm pwr_mode: %u psd: %d%s%s%s%s%s%s%s%s",
+ start, end, max_bw, max_eirp, pwr_mode, psd,
flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
@@ -2341,7 +2357,8 @@ static int nl80211_get_reg(struct nl_msg
nl80211_reg_rule_ht40(start, end, results);
if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
nl80211_reg_rule_max_eirp(start, end, max_eirp,
- results);
+ results, config_pwr_mode,
+ pwr_mode, psd);
}
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
@@ -2441,7 +2458,7 @@ static void nl80211_dump_chan_list(struc
struct hostapd_hw_modes *
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
- u8 *dfs_domain)
+ u8 *dfs_domain, u8 pwr_mode)
{
u32 feat;
struct i802_bss *bss = priv;
@@ -2454,6 +2471,7 @@ nl80211_get_hw_feature_data(void *priv,
.last_mode = -1,
.failed = 0,
.dfs_domain = 0,
+ .pwr_mode = pwr_mode
};
*num_modes = 0;
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1919,7 +1919,7 @@ static unsigned int chan_to_freq(struct
int i;
modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
- &flags, &dfs_domain);
+ &flags, &dfs_domain, 0);
if (!modes) {
wpa_printf(MSG_DEBUG,
"nl80211: Fetching hardware mode failed");
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -3127,6 +3127,8 @@ enum nl80211_attrs {
NL80211_ATTR_BEACON_TX_MODE,
+ NL80211_ATTR_6G_REG_POWER_MODE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3791,6 +3797,20 @@ enum nl80211_band_attr {
#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+enum nl80211_regulatory_power_modes {
+ NL80211_REG_AP_LPI,
+ NL80211_REG_AP_SP,
+ NL80211_REG_AP_VLP,
+ NL80211_REG_REGULAR_CLIENT_LPI,
+ NL80211_REG_REGULAR_CLIENT_SP,
+ NL80211_REG_REGULAR_CLIENT_VLP,
+ NL80211_REG_SUBORDINATE_CLIENT_LPI,
+ NL80211_REG_SUBORDINATE_CLIENT_SP,
+ NL80211_REG_SUBORDINATE_CLIENT_VLP,
+
+ NL80211_REG_NUM_POWER_MODES,
+};
+
/**
* enum nl80211_wmm_rule - regulatory wmm rule
*
@@ -4015,6 +4035,9 @@ enum nl80211_reg_type {
* a given frequency range. The value is in mBm (100 * dBm).
* @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
* If not present or 0 default CAC time will be used.
+ * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm).
+ * This could be negative.
+ * @NL80211_ATTR_REG_POWER_MODE: the regulatory power mode for 6G rules
* @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
* currently defined
* @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
@@ -4032,6 +4055,10 @@ enum nl80211_reg_rule_attr {
NL80211_ATTR_DFS_CAC_TIME,
+ NL80211_ATTR_POWER_RULE_PSD,
+
+ NL80211_ATTR_REG_POWER_MODE,
+
/* keep last */
__NL80211_REG_RULE_ATTR_AFTER_LAST,
NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -305,7 +305,7 @@ wpa_drv_get_hw_feature_data(struct wpa_s
if (wpa_s->driver->get_hw_feature_data)
return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv,
num_modes, flags,
- dfs_domain);
+ dfs_domain, 0);
return NULL;
}
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -231,7 +231,7 @@ static int wpas_mesh_update_freq_params(
hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
ifmsh->conf->vht_capab,
- he_capab)) {
+ he_capab, ifmsh->conf->he_6ghz_reg_pwr_type)) {
wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
wpa_supplicant_mesh_deinit(wpa_s, true);
return -1;
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2788,7 +2788,7 @@ skip_to_6ghz:
vht_freq.vht_enabled, vht_freq.he_enabled,
freq->sec_channel_offset,
chwidth, seg0, seg1, vht_caps,
- &mode->he_capab[ieee80211_mode]) != 0)
+ &mode->he_capab[ieee80211_mode], 0) != 0)
return;
*freq = vht_freq;
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3510,6 +3510,15 @@ static int hostapd_config_fill(struct ho
}
} else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) {
conf->he_6ghz_reg_pwr_type = atoi(pos);
+ if (conf->he_6ghz_reg_pwr_type > AP_TYPE_6GHZ_VERY_LOW_POWER_AP ||
+ conf->he_6ghz_reg_pwr_type < AP_TYPE_6GHZ_INDOOR_AP) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid 6ghz regulatory power type('%s') "
+ "[min: %d and max: %d]",
+ line, pos, AP_TYPE_6GHZ_INDOOR_AP,
+ AP_TYPE_6GHZ_VERY_LOW_POWER_AP);
+ return 1;
+ }
} else if (os_strcmp(buf, "he_oper_chwidth") == 0) {
conf->he_oper_chwidth = atoi(pos);
} else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {

View File

@@ -1,350 +0,0 @@
From 24763e3cd0a564eb71f3c501bbb4fbb0d7070762 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Fri, 15 Apr 2022 17:31:48 +0300
Subject: [PATCH] RADIUS: Attributes with Extended Types (RFC 6929)
Supported extended types for RADIUS attributes for the cases defined in
RFC 6929.
Signed-off-by: Jouni Malinen <j@w1.fi>
---
src/radius/radius.c | 195 ++++++++++++++++++++++++++++++++++++++------
src/radius/radius.h | 26 +++++-
2 files changed, 193 insertions(+), 28 deletions(-)
diff --git a/src/radius/radius.c b/src/radius/radius.c
index be16e27b9..a64228067 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -1,6 +1,6 @@
/*
* RADIUS message processing
- * Copyright (c) 2002-2009, 2011-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2009, 2011-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -159,7 +159,8 @@ static const char *radius_code_string(u8 code)
struct radius_attr_type {
- u8 type;
+ u16 type; /* 0..255 for basic types;
+ * (241 << 8) | <ext-type> for extended types */
char *name;
enum {
RADIUS_ATTR_UNDIST, RADIUS_ATTR_TEXT, RADIUS_ATTR_IP,
@@ -260,11 +261,31 @@ static const struct radius_attr_type radius_attrs[] =
RADIUS_ATTR_HEXDUMP },
{ RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER, "WLAN-Group-Mgmt-Pairwise-Cipher",
RADIUS_ATTR_HEXDUMP },
+ { RADIUS_ATTR_EXT_TYPE_1, "Extended-Type-1", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_TYPE_2, "Extended-Type-2", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_TYPE_3, "Extended-Type-3", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_TYPE_4, "Extended-Type-4", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_LONG_EXT_TYPE_1, "Long-Extended-Type-1",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_LONG_EXT_TYPE_2, "Long-Extended-Type-2",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_1, "Extended-Vendor-Specific-1",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_2, "Extended-Vendor-Specific-2",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_3, "Extended-Vendor-Specific-3",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_4, "Extended-Vendor-Specific-4",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5, "Extended-Vendor-Specific-5",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_6, "Extended-Vendor-Specific-6",
+ RADIUS_ATTR_UNDIST },
};
#define RADIUS_ATTRS ARRAY_SIZE(radius_attrs)
-static const struct radius_attr_type *radius_get_attr_type(u8 type)
+static const struct radius_attr_type * radius_get_attr_type(u16 type)
{
size_t i;
@@ -277,23 +298,60 @@ static const struct radius_attr_type *radius_get_attr_type(u8 type)
}
+static bool radius_is_long_ext_type(u8 type)
+{
+ return type == RADIUS_ATTR_LONG_EXT_TYPE_1 ||
+ type == RADIUS_ATTR_LONG_EXT_TYPE_2;
+}
+
+
+static bool radius_is_ext_type(u8 type)
+{
+ return type >= RADIUS_ATTR_EXT_TYPE_1 &&
+ type <= RADIUS_ATTR_LONG_EXT_TYPE_2;
+}
+
+
static void radius_msg_dump_attr(struct radius_attr_hdr *hdr)
{
+ struct radius_attr_hdr_ext *ext = NULL;
const struct radius_attr_type *attr;
int len;
unsigned char *pos;
char buf[1000];
- attr = radius_get_attr_type(hdr->type);
+ if (hdr->length < sizeof(struct radius_attr_hdr))
+ return;
- wpa_printf(MSG_INFO, " Attribute %d (%s) length=%d",
- hdr->type, attr ? attr->name : "?Unknown?", hdr->length);
+ if (radius_is_ext_type(hdr->type)) {
+ if (hdr->length < 4) {
+ wpa_printf(MSG_INFO,
+ " Invalid attribute %d (too short for extended type)",
+ hdr->type);
+ return;
+ }
- if (attr == NULL || hdr->length < sizeof(struct radius_attr_hdr))
- return;
+ ext = (struct radius_attr_hdr_ext *) hdr;
+ }
+
+ if (ext) {
+ attr = radius_get_attr_type((ext->type << 8) | ext->ext_type);
+ wpa_printf(MSG_INFO, " Attribute %d.%d (%s) length=%d",
+ ext->type, ext->ext_type,
+ attr ? attr->name : "?Unknown?", ext->length);
+ pos = (unsigned char *) (ext + 1);
+ len = ext->length - sizeof(struct radius_attr_hdr_ext);
+ } else {
+ attr = radius_get_attr_type(hdr->type);
+ wpa_printf(MSG_INFO, " Attribute %d (%s) length=%d",
+ hdr->type, attr ? attr->name : "?Unknown?",
+ hdr->length);
+ pos = (unsigned char *) (hdr + 1);
+ len = hdr->length - sizeof(struct radius_attr_hdr);
+ }
- len = hdr->length - sizeof(struct radius_attr_hdr);
- pos = (unsigned char *) (hdr + 1);
+ if (!attr)
+ return;
switch (attr->data_type) {
case RADIUS_ATTR_TEXT:
@@ -627,22 +685,54 @@ static int radius_msg_add_attr_to_array(struct radius_msg *msg,
}
-struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
- const u8 *data, size_t data_len)
+struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u16 type,
+ const u8 *data, size_t data_len)
{
- size_t buf_needed;
- struct radius_attr_hdr *attr;
+ size_t buf_needed, max_len;
+ struct radius_attr_hdr *attr = NULL;
+ struct radius_attr_hdr_ext *ext;
+ u8 ext_type = 0;
if (TEST_FAIL())
return NULL;
- if (data_len > RADIUS_MAX_ATTR_LEN) {
- wpa_printf(MSG_ERROR, "radius_msg_add_attr: too long attribute (%lu bytes)",
- (unsigned long) data_len);
- return NULL;
+ if (type > 255) {
+ if (!radius_is_ext_type(type >> 8)) {
+ wpa_printf(MSG_ERROR,
+ "%s: Undefined extended type %d.%d",
+ __func__, type >> 8, type & 0xff);
+ return NULL;
+ }
+ ext_type = type & 0xff;
+ type >>= 8;
+ } else if (radius_is_ext_type(type)) {
+ wpa_printf(MSG_ERROR, "%s: Unexpected extended type use for %d",
+ __func__, type);
}
- buf_needed = sizeof(*attr) + data_len;
+ if (radius_is_long_ext_type(type)) {
+ size_t hdr_len = sizeof(struct radius_attr_hdr_ext) + 1;
+ size_t plen = 255 - hdr_len;
+ size_t num;
+
+ max_len = 4096;
+ num = (data_len + plen - 1) / plen;
+ if (num == 0)
+ num = 1;
+ buf_needed = num * hdr_len + data_len;
+ } else if (radius_is_ext_type(type)) {
+ max_len = RADIUS_MAX_EXT_ATTR_LEN;
+ buf_needed = sizeof(struct radius_attr_hdr_ext) + data_len;
+ } else {
+ max_len = RADIUS_MAX_ATTR_LEN;
+ buf_needed = sizeof(*attr) + data_len;
+ }
+ if (data_len > max_len) {
+ wpa_printf(MSG_ERROR,
+ "%s: too long attribute (%zu > %zu bytes)",
+ __func__, data_len, max_len);
+ return NULL;
+ }
if (wpabuf_tailroom(msg->buf) < buf_needed) {
/* allocate more space for message buffer */
@@ -651,13 +741,44 @@ struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
msg->hdr = wpabuf_mhead(msg->buf);
}
- attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
- attr->type = type;
- attr->length = sizeof(*attr) + data_len;
- wpabuf_put_data(msg->buf, data, data_len);
-
- if (radius_msg_add_attr_to_array(msg, attr))
- return NULL;
+ if (radius_is_long_ext_type(type)) {
+ size_t plen = 255 - sizeof(struct radius_attr_hdr_ext) - 1;
+ size_t alen;
+
+ do {
+ alen = data_len > plen ? plen : data_len;
+ ext = wpabuf_put(msg->buf,
+ sizeof(struct radius_attr_hdr_ext));
+ if (!attr)
+ attr = (struct radius_attr_hdr *) ext;
+ ext->type = type;
+ ext->length = sizeof(*ext) + 1 + alen;
+ ext->ext_type = ext_type;
+ wpabuf_put_u8(msg->buf, data_len > alen ? 0x80 : 0);
+ wpabuf_put_data(msg->buf, data, data_len);
+ data += alen;
+ data_len -= alen;
+ if (radius_msg_add_attr_to_array(
+ msg, (struct radius_attr_hdr *) ext))
+ return NULL;
+ } while (data_len > 0);
+ } else if (radius_is_ext_type(type)) {
+ ext = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr_ext));
+ attr = (struct radius_attr_hdr *) ext;
+ ext->type = type;
+ ext->length = sizeof(*ext) + data_len;
+ ext->ext_type = ext_type;
+ wpabuf_put_data(msg->buf, data, data_len);
+ if (radius_msg_add_attr_to_array(msg, attr))
+ return NULL;
+ } else {
+ attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
+ attr->type = type;
+ attr->length = sizeof(*attr) + data_len;
+ wpabuf_put_data(msg->buf, data, data_len);
+ if (radius_msg_add_attr_to_array(msg, attr))
+ return NULL;
+ }
return attr;
}
@@ -1285,6 +1406,28 @@ int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
}
+int radius_msg_add_ext_vs(struct radius_msg *msg, u16 type, u32 vendor_id,
+ u8 vendor_type, const u8 *data, size_t len)
+{
+ struct radius_attr_hdr *attr;
+ u8 *buf, *pos;
+ size_t alen;
+
+ alen = 4 + 1 + len;
+ buf = os_malloc(alen);
+ if (!buf)
+ return 0;
+ pos = buf;
+ WPA_PUT_BE32(pos, vendor_id);
+ pos += 4;
+ *pos++ = vendor_type;
+ os_memcpy(pos, data, len);
+ attr = radius_msg_add_attr(msg, type, buf, alen);
+ os_free(buf);
+ return attr != NULL;
+}
+
+
int radius_user_password_hide(struct radius_msg *msg,
const u8 *data, size_t data_len,
const u8 *secret, size_t secret_len,
diff --git a/src/radius/radius.h b/src/radius/radius.h
index fb8148180..490c8d1f6 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -1,6 +1,6 @@
/*
* RADIUS message processing
- * Copyright (c) 2002-2009, 2012, 2014-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2009, 2012, 2014-2022, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -46,7 +46,15 @@ struct radius_attr_hdr {
/* followed by length-2 octets of attribute value */
} STRUCT_PACKED;
+struct radius_attr_hdr_ext {
+ u8 type;
+ u8 length; /* including this header */
+ u8 ext_type;
+ /* followed by length-3 octets of attribute value */
+} STRUCT_PACKED;
+
#define RADIUS_MAX_ATTR_LEN (255 - sizeof(struct radius_attr_hdr))
+#define RADIUS_MAX_EXT_ATTR_LEN (255 - sizeof(struct radius_attr_hdr_ext))
enum { RADIUS_ATTR_USER_NAME = 1,
RADIUS_ATTR_USER_PASSWORD = 2,
@@ -113,6 +121,18 @@ enum { RADIUS_ATTR_USER_NAME = 1,
RADIUS_ATTR_WLAN_GROUP_CIPHER = 187,
RADIUS_ATTR_WLAN_AKM_SUITE = 188,
RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER = 189,
+ RADIUS_ATTR_EXT_TYPE_1 = 241,
+ RADIUS_ATTR_EXT_TYPE_2 = 242,
+ RADIUS_ATTR_EXT_TYPE_3 = 243,
+ RADIUS_ATTR_EXT_TYPE_4 = 244,
+ RADIUS_ATTR_LONG_EXT_TYPE_1 = 245,
+ RADIUS_ATTR_LONG_EXT_TYPE_2 = 246,
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_1 = (241 << 8) | 26,
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_2 = (242 << 8) | 26,
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_3 = (243 << 8) | 26,
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_4 = (244 << 8) | 26,
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5 = (245 << 8) | 26,
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_6 = (246 << 8) | 26,
};
@@ -257,7 +277,7 @@ int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret,
int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret,
size_t secret_len,
int require_message_authenticator);
-struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
+struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u16 type,
const u8 *data, size_t data_len);
struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
@@ -284,6 +304,8 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg,
const u8 *recv_key, size_t recv_key_len);
int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
size_t len);
+int radius_msg_add_ext_vs(struct radius_msg *msg, u16 type, u32 vendor_id,
+ u8 vendor_type, const u8 *data, size_t len);
int radius_user_password_hide(struct radius_msg *msg,
const u8 *data, size_t data_len,
const u8 *secret, size_t secret_len,
--
2.25.1

View File

@@ -0,0 +1,171 @@
From 2a556ebff47bebcda6a1c7c8cd760bd38de54ff4 Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Fri, 22 Oct 2021 22:50:37 +0530
Subject: [PATCH] hostapd: add support for 6g client type
IEEE Std 802.11ax™2021 introduces two types of client
namely DEFAULT and SUBORDINATE client for 6GHz device.
This patch -
* add u8 he_6ghz_reg_client_type member in struct wpa_config
to store the 6g configured mode.
* add new nl80211 ops - set_6gclient_type, which will be used
to send the 6G client type via existing NL80211_CMD_SET_INTERFACE
command.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
src/drivers/driver.h | 8 ++++++++
src/drivers/driver_nl80211.c | 26 ++++++++++++++++++++++++++
wpa_supplicant/config.c | 2 ++
wpa_supplicant/config.h | 11 +++++++++++
wpa_supplicant/driver_i.h | 8 ++++++++
wpa_supplicant/wpa_supplicant.c | 9 +++++++++
6 files changed, 64 insertions(+)
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4694,6 +4694,14 @@ struct wpa_driver_ops {
* explicitly allow reception of broadcast Public Action frames.
*/
int (*dpp_listen)(void *priv, bool enable);
+
+ /**
+ * set_6gclient_type - Set the client type for 6G interface
+ * @priv: Private driver interface data
+ * @client_type_6g: 0 - Default Client, 1 - Subordinate Client
+ * Returns: 0 on success, < 0 on failure
+ */
+ int (*set_6gclient_type)(void *priv, u8 client_type_6g);
};
/**
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -12173,6 +12173,31 @@ static int nl80211_dpp_listen(void *priv
}
#endif /* CONFIG_DPP */
+static int nl80211_set_6gclient_type(void *priv, u8 client_type_6g)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct nl_msg *msg;
+ int ret = -ENOBUFS;
+
+ wpa_printf(MSG_DEBUG, "nl80211: 6g client type: %d",
+ client_type_6g);
+
+ msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
+ if (!msg || nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE,
+ client_type_6g))
+ goto fail;
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+
+ if(ret)
+ wpa_printf(MSG_DEBUG, "nl80211: 6g client type could not be set (%d)",
+ ret);
+ return ret;
+fail:
+ nlmsg_free(msg);
+ return ret;
+}
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
@@ -12315,4 +12340,5 @@ const struct wpa_driver_ops wpa_driver_n
#ifdef CONFIG_DPP
.dpp_listen = nl80211_dpp_listen,
#endif /* CONFIG_DPP */
+ .set_6gclient_type = nl80211_set_6gclient_type,
};
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -5394,6 +5394,8 @@ static const struct global_parse_data gl
{ INT_RANGE(force_kdk_derivation, 0, 1), 0 },
#endif /* CONFIG_TESTING_OPTIONS */
#endif /* CONFIG_PASN */
+ { INT_RANGE(he_6ghz_reg_client_type, 1, 2),
+ CFG_CHANGED_HE_6GHZ_CLIENT_TYPE},
};
#undef FUNC
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -378,6 +378,7 @@ struct wpa_cred {
#define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18)
#define CFG_CHANGED_DISABLE_BTM BIT(19)
#define CFG_CHANGED_BGSCAN BIT(20)
+#define CFG_CHANGED_HE_6GHZ_CLIENT_TYPE BIT(21)
/**
* struct wpa_config - wpa_supplicant configuration data
@@ -1650,6 +1651,16 @@ struct wpa_config {
int force_kdk_derivation;
#endif /* CONFIG_TESTING_OPTIONS */
#endif /* CONFIG_PASN*/
+
+ /**
+ * he_6ghz_reg_client_type - Type of client in 6GHz band
+ *
+ * IEEE Std 802.11ax™2021 allows two kinds of client
+ *
+ * 1 = DEFAULT or REGULAR CLIENT
+ * 2 = SUBORDINATE CLIENT
+ */
+ u8 he_6ghz_reg_client_type;
};
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -1117,4 +1117,12 @@ static inline int wpa_drv_dpp_listen(str
return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable);
}
+static inline int wpa_drv_set_6gclient_type(struct wpa_supplicant *wpa_s,
+ u8 he_6ghz_reg_client_type)
+{
+ if (!wpa_s->driver->set_6gclient_type)
+ return -1;
+ return wpa_s->driver->set_6gclient_type(wpa_s->drv_priv,
+ he_6ghz_reg_client_type);
+}
#endif /* DRIVER_I_H */
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -5212,6 +5212,15 @@ int wpa_supplicant_driver_init(struct wp
wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
wpa_drv_flush_pmkid(wpa_s);
+ /* Before starting scan, for 6g interface, set the client type */
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_HE_6GHZ_CLIENT_TYPE) {
+ u8 he_6ghz_reg_client_type = wpa_s->conf->he_6ghz_reg_client_type;
+ /**
+ * Subtract 1 to map the client type with 0 indexing
+ */
+ wpa_drv_set_6gclient_type(wpa_s, he_6ghz_reg_client_type - 1);
+ }
+
wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
wpa_s->prev_scan_wildcard = 0;
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -589,6 +589,15 @@ fast_reauth=1
# 1 = Publish
#ftm_initiator=0
+# 6GHz regulatory client type
+# This sets the 6GHz client type. Possible options are
+# 1 = Default Client
+# 2 = Subordinate Client
+# Note that value 0 is reserved and can not be used. For 6GHz operation
+# user has to choose from either 1 or 2. If not mentioned, no type will
+# be set from user side. Wireless stack will handle its own default case.
+#he_6ghz_reg_client_type=1
+
# credential block
#
# Each credential used for automatic network selection is configured as a set

View File

@@ -1,102 +0,0 @@
From b94371af8402f60218716552e571ca72cff4e3c0 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Fri, 15 Apr 2022 17:36:25 +0300
Subject: [PATCH] RADIUS attributes for EAPOL-Key message details
Use vendor specific RADIUS attributes for sending ANonce and EAPOL-Key
msg 2/4 for the wpa_psk_radius=3 case. The vendor specific attributes
for this are defined in FreeRADIUS as follows:
BEGIN-VENDOR FreeRADIUS format=Extended-Vendor-Specific-5
ATTRIBUTE FreeRADIUS-802.1X-Anonce 1 octets[32]
ATTRIBUTE FreeRADIUS-802.1X-EAPoL-Key-Msg 2 octets
END-VENDOR FreeRADIUS
Signed-off-by: Jouni Malinen <j@w1.fi>
---
src/ap/ieee802_11_auth.c | 29 +++++++++++++++++++++++++++++
src/radius/radius.h | 7 +++++++
2 files changed, 36 insertions(+)
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index a54d7616e..4277d82cb 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -47,6 +47,9 @@ struct hostapd_acl_query_data {
struct hostapd_acl_query_data *next;
bool radius_psk;
int akm;
+ u8 *anonce;
+ u8 *eapol;
+ size_t eapol_len;
};
@@ -102,6 +105,8 @@ static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
if (!query)
return;
os_free(query->auth_msg);
+ os_free(query->anonce);
+ os_free(query->eapol);
os_free(query);
}
@@ -164,6 +169,24 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
goto fail;
}
+ if (query->anonce &&
+ !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
+ RADIUS_VENDOR_ID_FREERADIUS,
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE,
+ query->anonce, WPA_NONCE_LEN)) {
+ wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-Anonce");
+ goto fail;
+ }
+
+ if (query->eapol &&
+ !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
+ RADIUS_VENDOR_ID_FREERADIUS,
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG,
+ query->eapol, query->eapol_len)) {
+ wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-EAPoL-Key-Msg");
+ goto fail;
+ }
+
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
goto fail;
return 0;
@@ -703,6 +726,12 @@ void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
query->akm = key_mgmt;
os_get_reltime(&query->timestamp);
os_memcpy(query->addr, addr, ETH_ALEN);
+ if (anonce)
+ query->anonce = os_memdup(anonce, WPA_NONCE_LEN);
+ if (eapol) {
+ query->eapol = os_memdup(eapol, eapol_len);
+ query->eapol_len = eapol_len;
+ }
if (hostapd_radius_acl_query(hapd, addr, query)) {
wpa_printf(MSG_DEBUG,
"Failed to send Access-Request for RADIUS PSK/ACL query");
diff --git a/src/radius/radius.h b/src/radius/radius.h
index 490c8d1f6..177c64a66 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -208,6 +208,13 @@ enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
};
+/* FreeRADIUS vendor-specific attributes */
+#define RADIUS_VENDOR_ID_FREERADIUS 11344
+/* Extended-Vendor-Specific-5 (245.26; long extended header) */
+enum {
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE = 1,
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG = 2,
+};
/* Hotspot 2.0 - WFA Vendor-specific RADIUS Attributes */
#define RADIUS_VENDOR_ID_WFA 40808
--
2.25.1

View File

@@ -0,0 +1,53 @@
From bd267ee2e6c1ce5165bf8be9411b398709f83a8f Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Fri, 19 Nov 2021 19:51:04 +0530
Subject: [PATCH] hostapd: fix 6GHz chan switch issue
If user doesnt provide HE parameter in the hostapd_cli chan_switch
command, by default HE should be enabled for 6 GHz frequency range.
This is because, 6 GHz does not support legacy mode. Similarly, if
bandwidth isnt provided, 20 MHz should be taken as default bandwidth.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
hostapd/ctrl_iface.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 664711d..3c2d51c 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -2530,12 +2530,24 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
{
int idx, bw, bw_idx[] = { 20, 40, 80, 160 };
- if (is_6ghz_freq(params->freq) && params->center_freq1) {
- idx = (params->center_freq1 - 5950) / 5;
- bw = center_idx_to_bw_6ghz(idx);
-
- if (bw < 0 || (bw_idx[bw] != params->bandwidth))
- return -1;
+ if (is_6ghz_freq(params->freq)) {
+ /* Verify if HE was enabled by user or not. 6 GHz does not
+ * support legacy mode. Hence, enable HE if not given */
+ if (!params->he_enabled)
+ params->he_enabled = 1;
+
+ /* By default in 6 GHz, HE 20 mode should be selected */
+ if (!params->center_freq1 && params->bandwidth == 0) {
+ params->center_freq1 = params->freq;
+ /* If bw is not given by user, by default assuming 20 */
+ params->bandwidth = 20;
+ } else {
+ idx = (params->center_freq1 - 5950) / 5;
+ bw = center_idx_to_bw_6ghz(idx);
+
+ if (bw < 0 || (bw_idx[bw] != params->bandwidth))
+ return -1;
+ }
}
switch (params->bandwidth) {
--
2.7.4

View File

@@ -0,0 +1,47 @@
From 473175ab3030092aa75c9e4e3daf81eb50da0278 Mon Sep 17 00:00:00 2001
From: Thiraviyam Mariyappan <quic_tmariyap@quicinc.com>
Date: Tue, 4 Jan 2022 13:22:18 +0530
Subject: [PATCH] wpa_supplicant: support 5.9 channels in mesh 160mhz
currently, mesh supported 5.9 channels on 80Mhz. This patch supports
5.9 channels to bring up at 160mhz based on channel availability.
Signed-off-by: Thiraviyam Mariyappan <quic_tmariyap@quicinc.com>
---
wpa_supplicant/wpa_supplicant.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
@@ -2511,7 +2511,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
unsigned int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955,
6035, 6115, 6195, 6275, 6355, 6435, 6515,
6595, 6675, 6755, 6835, 6915, 6995 };
- unsigned int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
+ unsigned int bw160[] = { 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
u8 channel;
int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan);
@@ -2767,9 +2767,9 @@ skip_to_6ghz:
seg0 = freq->channel + 6;
seg1 = 0;
-/* setup center_freq1 for 6G 160MHz */
+ /* setup center_freq1 for 160MHz */
if ((mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) {
for (j = 0; j < ARRAY_SIZE(bw160); j++) {
if (freq->freq == bw160[j]) {
@@ -2779,7 +2779,7 @@ skip_to_6ghz:
int channel = freq->channel + 16;
if (!ibss_mesh_is_80mhz_avail(channel, mode))
- return;
+ break;
chwidth = CHANWIDTH_160MHZ;
seg0 = freq->channel + 14;

View File

@@ -0,0 +1,250 @@
From d6e52c4ef2bb8e915cae088564c412583f1794c9 Mon Sep 17 00:00:00 2001
From: P Praneesh <quic_ppranees@quicinc.com>
Date: Fri, 21 Jan 2022 09:44:15 +0530
Subject: [PATCH] mesh: enable more 160MHz channels in 6GHz
Current 160MHz implementation supports mesh bringup in limited channels.
Allow all the 6GHz 80MHz channels to support 160MHz if the secondary 80MHz
is available.
Ex: User can bringup 160MHz in 49th channel (primary 80MHz) based on 33rd
channel(secondary 80MHz) availablity.
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
---
wpa_supplicant/wpa_supplicant.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
@@ -2508,12 +2508,20 @@ void ibss_mesh_setup_freq(struct wpa_sup
struct hostapd_hw_modes *mode = NULL;
int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
165, 173, 184, 192 };
- unsigned int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955,
- 6035, 6115, 6195, 6275, 6355, 6435, 6515,
- 6595, 6675, 6755, 6835, 6915, 6995 };
- unsigned int bw160[] = { 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
+ /* bw_80_160 array members are 80MHz start freq, 80MHz end freq and so on
+ */
+ unsigned int bw_80_160[] = { 5180, 5240, 5260, 5320,
+ 5500, 5560, 5580, 5660,
+ 5745, 5805, 5825, 5885,
+ 5955, 6015, 6035, 6095,
+ 6115, 6175, 6195, 6255,
+ 6275, 6335, 6355, 6415,
+ 6435, 6495, 6515, 6575,
+ 6595, 6655, 6675, 6735,
+ 6755, 6815, 6835, 6895,
+ 6915, 6975, 6995, 7055 };
struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
- u8 channel;
+ u8 channel, chan_80mhz;
int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan);
unsigned int j, k;
struct hostapd_freq_params vht_freq;
@@ -2752,49 +2760,72 @@ skip_to_6ghz:
#endif /* CONFIG_HE_OVERRIDES */
/* setup center_freq1, bandwidth */
- for (j = 0; j < ARRAY_SIZE(bw80); j++)
- if (freq->freq == bw80[j])
+ for (j = 0; j < ARRAY_SIZE(bw_80_160); j+=2) {
+ /* If the config provided freq available between any of two indices
+ * get the starting range of the channel to check chan availability
+ */
+ if (freq->freq >= bw_80_160[j] && freq->freq <= bw_80_160[j+1]) {
+ ieee80211_freq_to_chan(bw_80_160[j], &chan_80mhz);
+ seg0 = chan_80mhz + 6;
break;
+ }
+ }
- if (j == ARRAY_SIZE(bw80))
+ if (j == ARRAY_SIZE(bw_80_160))
return;
/* Back to HT configuration if channel not usable */
- if (!ibss_mesh_is_80mhz_avail(freq->channel, mode))
+ if (!ibss_mesh_is_80mhz_avail(chan_80mhz, mode))
return;
chwidth = CHANWIDTH_80MHZ;
- seg0 = freq->channel + 6;
seg1 = 0;
/* setup center_freq1 for 160MHz */
if ((mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) {
-
- for (j = 0; j < ARRAY_SIZE(bw160); j++) {
- if (freq->freq == bw160[j]) {
- /* In 160MHz, Initial four 20MHz channels validated before,
- * check remaining four 20MHz channels in total 160MHz bandwidth
- */
- int channel = freq->channel + 16;
-
- if (!ibss_mesh_is_80mhz_avail(channel, mode))
- break;
-
- chwidth = CHANWIDTH_160MHZ;
- seg0 = freq->channel + 14;
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && (ssid->enable_160mhz_bw)) {
+ chan_80mhz = freq->channel + 16;
+ for (j = 0; j < ARRAY_SIZE(bw_80_160); j+=2) {
+ if (freq->freq >= bw_80_160[j] && freq->freq <= bw_80_160[j+1]) {
+ if (j % 4 == 0) {
+ ieee80211_freq_to_chan(bw_80_160[j],
+ &chan_80mhz);
+ seg0 = chan_80mhz + 14;
+
+ /* Get secondary 80MHz channel using freq by
+ * adding 16*5 ie., 80MHz.
+ */
+ ieee80211_freq_to_chan((bw_80_160[j] + 16*5),
+ &chan_80mhz);
+ } else {
+ ieee80211_freq_to_chan(bw_80_160[j],
+ &chan_80mhz);
+ seg0 = chan_80mhz - 2;
+ /* Get secondary 80MHz channel using freq by
+ * subtracting 16*5 ie., 80MHz.
+ */
+ ieee80211_freq_to_chan((bw_80_160[j] - 16*5),
+ &chan_80mhz);
+ }
+
+ if (!ibss_mesh_is_80mhz_avail(chan_80mhz, mode))
+ seg0 = freq->channel + 6;
+ else
+ chwidth = CHANWIDTH_160MHZ;
+ break;
}
}
}
if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) {
/* setup center_freq2, bandwidth */
- for (k = 0; k < ARRAY_SIZE(bw80); k++) {
+ for (k = 0; k < ARRAY_SIZE(bw_80_160); k++) {
/* Only accept 80 MHz segments separated by a gap */
- if (j == k || abs(bw80[j] - bw80[k]) == 80)
+ if (j == k || abs(bw_80_160[j] - bw_80_160[k]) == 80)
continue;
- if (ieee80211_freq_to_chan(bw80[k], &channel) == NUM_HOSTAPD_MODES)
+ if (ieee80211_freq_to_chan(bw_80_160[k],
+ &channel) == NUM_HOSTAPD_MODES)
return;
for (i = channel; i < channel + 16; i += 4) {
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
@@ -4245,6 +4245,8 @@ static int hostapd_config_fill(struct ho
} else if (os_strcmp(buf, "wowlan_triggers") == 0) {
os_free(bss->wowlan_triggers);
bss->wowlan_triggers = os_strdup(pos);
+ } else if (os_strcmp(buf, "enable_160mhz_bw") == 0) {
+ conf->enable_160mhz_bw = atoi(pos);
} else if (os_strcmp(buf, "disable_40mhz_scan") == 0) {
conf->disable_40mhz_scan = atoi(pos);
#ifdef CONFIG_FST
Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h
+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
@@ -1067,6 +1067,7 @@ struct hostapd_config {
} *acs_chan_bias;
unsigned int num_acs_chan_bias;
#endif /* CONFIG_ACS */
+ int enable_160mhz_bw;
int disable_40mhz_scan;
struct wpabuf *lci;
Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver.h
+++ hostapd-2021-02-20-59e9794c/src/drivers/driver.h
@@ -1229,6 +1229,10 @@ struct wpa_driver_associate_params {
* 2 = BURST beacon tx mode
*/
int beacon_tx_mode;
+ /**
+ * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G
+ */
+ int enable_160mhz_bw;
};
enum hide_ssid {
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/config.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/config.c
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/config.c
@@ -2742,6 +2742,7 @@ static const struct parse_data ssid_fiel
{ INT_RANGE(sae_pk, 0, 2) },
{ INT_RANGE(disable_40mhz_scan, 0, 1)},
{ INT_RANGE(beacon_tx_mode, 1, 2)},
+ { INT_RANGE(enable_160mhz_bw, 0, 1)},
};
#undef OFFSET
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/config_file.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/config_file.c
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/config_file.c
@@ -889,6 +889,7 @@ static void wpa_config_write_network(FIL
#endif /* CONFIG_HE_OVERRIDES */
INT(disable_40mhz_scan);
INT(beacon_tx_mode);
+ INT(enable_160mhz_bw);
#undef STR
#undef INT
#undef INT_DEF
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/config_ssid.h
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/config_ssid.h
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/config_ssid.h
@@ -1192,6 +1192,11 @@ struct wpa_ssid {
* 2 = BURST MODE
*/
int beacon_tx_mode;
+
+ /**
+ * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G
+ */
+ int enable_160mhz_bw;
};
#endif /* CONFIG_SSID_H */
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_cli.c
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_cli.c
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_cli.c
@@ -1490,6 +1490,7 @@ static const char *network_fields[] = {
"mac_addr", "pbss", "wps_disabled",
"disable_40mhz_scan",
"beacon_tx_mode",
+ "enable_160mhz_bw",
};
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.conf
===================================================================
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.conf
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.conf
@@ -1699,6 +1699,11 @@ fast_reauth=1
# In STA mode it defines the EDMG channel for connection (if supported by AP).
#edmg_channel=9
+#To configure 80MHz and 160MHz in Mesh mode.
+#Set 0 to enable 80MHz in Mesh mode
+#Set 1 to enable 160MHz in Mesh mode
+#enable_160mhz_bw=1
+
# Example blocks:
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers

View File

@@ -0,0 +1,65 @@
From 29818cbd2d4fc8aee50d632335a31028b614ae1a Mon Sep 17 00:00:00 2001
From: Sowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
Date: Thu, 10 Feb 2022 12:30:25 +0530
Subject: [PATCH] hostapd:Fix race condition in four way handshake
When there is multiple delayed m2 from the station,
after ap has tried m3 multiple times, ap tends to
send m3 again for the later received m2 incrementing
the replay counter. Here station replies with m4 only
for the first m3, but replay counter would have advanced
to higher number due to multiple m3 retries. Due to
replay counter mismatch m4 is discarded and station
association fails.
Added a flag to stop processing m2 if state machine has
already advanced to m3 state, this prevent m3 triggered
in response for m2 there by preventing the race condition
with respect to replay counter
Signed-off-by: Sowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
---
src/ap/wpa_auth.c | 3 ++-
src/ap/wpa_auth_i.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1150,7 +1150,7 @@ void wpa_receive(struct wpa_authenticato
!wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) {
int i;
- if (msg == PAIRWISE_2 &&
+ if (msg == PAIRWISE_2 && !sm->m3_retried &&
wpa_replay_counter_valid(sm->prev_key_replay,
key->replay_counter) &&
sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
@@ -3753,6 +3753,7 @@ SM_STEP(WPA_PTK)
}
break;
case WPA_PTK_INITPSK:
+ sm->m3_retried = 0;
if (wpa_auth_get_psk(wpa_auth, sm->addr, sm->p2p_dev_addr,
NULL, NULL, NULL)) {
SM_ENTER(WPA_PTK, PTKSTART);
@@ -3811,8 +3812,10 @@ SM_STEP(WPA_PTK)
sm->disconnect_reason =
WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT;
SM_ENTER(WPA_PTK, DISCONNECT);
- } else if (sm->TimeoutEvt)
+ } else if (sm->TimeoutEvt) {
+ sm->m3_retried = 1;
SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
+ }
break;
case WPA_PTK_PTKINITDONE:
break;
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -95,6 +95,7 @@ struct wpa_state_machine {
#endif /* CONFIG_IEEE80211R_AP */
unsigned int is_wnmsleep:1;
unsigned int pmkid_set:1;
+ unsigned int m3_retried:1;
#ifdef CONFIG_OCV
int ocv_enabled;

View File

@@ -0,0 +1,369 @@
From daf67e765bcfa6ff6affb1a916696271014303b2 Mon Sep 17 00:00:00 2001
From: P Praneesh <quic_ppranees@quicinc.com>
Date: Mon, 21 Feb 2022 11:49:50 +0530
Subject: [PATCH] hostapd: add acs_exclude_6ghz_non_psc option for acs non
offload driver
Hostapd configuration "acs_exclude_6ghz_non_psc" is supported for ACS
offloaded driver alone. Extend the support to ACS non offload driver
by adding 6G Preferred Scan Channel check and hostapd config flag
during scan and survey dump.
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
---
src/ap/acs.c | 141 ++++++++++++++++++++++++++++++++++++++++---
src/ap/ap_drv_ops.h | 6 +-
src/ap/bss_load.c | 3 +-
src/drivers/driver.h | 4 +-
src/drivers/driver_nl80211.c | 30 ++++++---
5 files changed, 166 insertions(+), 18 deletions(-)
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -641,6 +641,112 @@ static int is_common_24ghz_chan(int chan
#endif /* ACS_24GHZ_PREFER_1_6_11 */
static void
+acs_find_6g_psc_chan_mode(struct hostapd_iface *iface,
+ struct hostapd_hw_modes *mode,
+ int n_chans, u32 bw,
+ struct hostapd_channel_data **rand_chan,
+ struct hostapd_channel_data **ideal_chan,
+ long double *ideal_factor)
+{
+ struct hostapd_channel_data *chan, *adj_chan = NULL;
+ long double factor;
+ int i, j;
+ unsigned int k;
+
+ for (i = 0; i < mode->num_channels; i++) {
+ double total_weight;
+ struct acs_bias *bias;
+
+ chan = &mode->channels[i];
+ if (!chan_pri_allowed(chan))
+ continue;
+
+ if (!is_in_chanlist(iface, chan))
+ continue;
+
+ if (!is_in_freqlist(iface, chan))
+ continue;
+
+ if (!is_6ghz_psc_frequency(chan->freq))
+ continue;
+
+ if (!chan_bw_allowed(chan, bw, 1, 1)) {
+ wpa_printf(MSG_DEBUG,
+ "ACS: Channel %d: BW %u is not supported",
+ chan->chan, bw);
+ continue;
+ }
+
+ factor = 0;
+ if (acs_usable_chan(chan))
+ factor = chan->interference_factor;
+ total_weight = 1;
+
+ /* Start index from -1 because all the PSC channels are located in
+ * secondary 20MHz of primary 40MHz. Ex: CH33 - CH61 has 160MHz BW, PSC
+ * CH37 which is secondary 20MHz of primary 40MHz.
+ */
+
+ for (j = -1; j < n_chans; j++) {
+ adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
+ if (!adj_chan)
+ break;
+
+ if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
+ wpa_printf(MSG_DEBUG,
+ "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
+ chan->chan, adj_chan->chan, bw);
+ break;
+ }
+
+ if (acs_usable_chan(adj_chan)) {
+ factor += adj_chan->interference_factor;
+ total_weight += 1;
+ }
+ }
+
+ if (j != n_chans) {
+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
+ chan->chan);
+ continue;
+ }
+
+ factor /= total_weight;
+
+ bias = NULL;
+ if (iface->conf->acs_chan_bias) {
+ for (k = 0; k < iface->conf->num_acs_chan_bias; k++) {
+ bias = &iface->conf->acs_chan_bias[k];
+ if (bias->channel == chan->chan)
+ break;
+ bias = NULL;
+ }
+ }
+
+ if (bias) {
+ factor *= bias->bias;
+ wpa_printf(MSG_DEBUG,
+ "ACS: * channel %d: total interference = %Lg (%f bias)",
+ chan->chan, factor, bias->bias);
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "ACS: * channel %d: total interference = %Lg",
+ chan->chan, factor);
+ }
+
+ if (acs_usable_chan(chan) &&
+ (!*ideal_chan || factor < *ideal_factor)) {
+ *ideal_factor = factor;
+ *ideal_chan = chan;
+ }
+
+ /* This channel would at least be usable */
+ if (!(*rand_chan))
+ *rand_chan = chan;
+ }
+}
+
+static void
acs_find_ideal_chan_mode(struct hostapd_iface *iface,
struct hostapd_hw_modes *mode,
int n_chans, u32 bw,
@@ -874,10 +980,17 @@ bw_selected:
for (i = 0; i < iface->num_hw_features; i++) {
mode = &iface->hw_features[i];
- if (!hostapd_hw_skip_mode(iface, mode))
- acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
- &rand_chan, &ideal_chan,
- &ideal_factor);
+ if (!hostapd_hw_skip_mode(iface, mode)) {
+ if (iface->conf->acs_exclude_6ghz_non_psc) {
+ acs_find_6g_psc_chan_mode(iface, mode, n_chans, bw,
+ &rand_chan, &ideal_chan,
+ &ideal_factor);
+ } else {
+ acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
+ &rand_chan, &ideal_chan,
+ &ideal_factor);
+ }
+ }
}
if (ideal_chan) {
@@ -892,19 +1005,42 @@ bw_selected:
static void acs_adjust_center_freq(struct hostapd_iface *iface)
{
- int offset;
+ int psc_chan[] = {37, 53, 69, 85, 101, 117,
+ 133, 149, 165, 181, 197, 213} ;
+ int offset, i;
+ u8 bw = hostapd_get_oper_chwidth(iface->conf);
+ bool acs_exclude_6ghz_non_psc = iface->conf->acs_exclude_6ghz_non_psc;
+ bool is_sec_psc_chan = false;
wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
- switch (hostapd_get_oper_chwidth(iface->conf)) {
+ if (acs_exclude_6ghz_non_psc && (bw == CHANWIDTH_160MHZ)) {
+ for (i = 0; i < ARRAY_SIZE(psc_chan); i++) {
+ if (psc_chan[i] == iface->conf->channel) {
+ is_sec_psc_chan = (i%2) ? true : false;
+ break;
+ }
+ }
+ }
+
+ switch (bw) {
case CHANWIDTH_USE_HT:
offset = 2 * iface->conf->secondary_channel;
break;
case CHANWIDTH_80MHZ:
- offset = 6;
+ if (acs_exclude_6ghz_non_psc)
+ offset = 2;
+ else
+ offset = 6;
break;
case CHANWIDTH_160MHZ:
- offset = 14;
+ /* In 160MHz, if primary 20MHz present in secondary 80MHz, then
+ * subtract with -6 to find the center frequency of the 160MHz
+ */
+ if (acs_exclude_6ghz_non_psc)
+ offset = is_sec_psc_chan ? -6 : 10;
+ else
+ offset = 14;
break;
default:
/* TODO: How can this be calculated? Adjust
@@ -1001,7 +1137,8 @@ static void acs_scan_complete(struct hos
wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)",
iface->conf->acs_num_scans);
- err = hostapd_drv_get_survey(iface->bss[0], 0);
+ err = hostapd_drv_get_survey(iface->bss[0], 0,
+ iface->conf->acs_exclude_6ghz_non_psc);
if (err) {
wpa_printf(MSG_ERROR, "ACS: Failed to get survey data");
goto fail;
@@ -1043,6 +1180,11 @@ static int * acs_request_scan_add_freqs(
if (!is_in_freqlist(iface, chan))
continue;
+ if (is_6ghz_freq(chan->freq) &&
+ iface->conf->acs_exclude_6ghz_non_psc &&
+ !is_6ghz_psc_frequency(chan->freq))
+ continue;
+
*freq++ = chan->freq;
}
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -266,13 +266,15 @@ static inline void hostapd_drv_poll_clie
}
static inline int hostapd_drv_get_survey(struct hostapd_data *hapd,
- unsigned int freq)
+ unsigned int freq,
+ bool acs_exclude_6ghz_non_psc)
{
if (hapd->driver == NULL)
return -1;
if (!hapd->driver->get_survey)
return -1;
- return hapd->driver->get_survey(hapd->drv_priv, freq);
+ return hapd->driver->get_survey(hapd->drv_priv, freq,
+ acs_exclude_6ghz_non_psc);
}
static inline int hostapd_get_country(struct hostapd_data *hapd, char *alpha2)
--- a/src/ap/bss_load.c
+++ b/src/ap/bss_load.c
@@ -49,7 +49,8 @@ static void update_channel_utilization(v
if (!(hapd->beacon_set_done && hapd->started))
return;
- err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
+ err = hostapd_drv_get_survey(hapd, hapd->iface->freq,
+ hapd->iface->conf->acs_exclude_6ghz_non_psc);
if (err) {
wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
return;
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4186,6 +4186,8 @@ struct wpa_driver_ops {
* @priv: Private driver interface data
* @freq: If set, survey data for the specified frequency is only
* being requested. If not set, all survey data is requested.
+ * @acs_exclude_6ghz_non_psc: If set Include only preferred scan
+ * channels from 6 GHz band for ACS
* Returns: 0 on success, -1 on failure
*
* Use this to retrieve:
@@ -4204,7 +4206,7 @@ struct wpa_driver_ops {
* for each survey. The min_nf of the channel is updated for each
* survey.
*/
- int (*get_survey)(void *priv, unsigned int freq);
+ int (*get_survey)(void *priv, unsigned int freq, bool acs_exclude_6ghz_non_psc);
/**
* status - Get driver interface status information
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9033,6 +9033,10 @@ static int check_survey_ok(struct nlattr
return freq_filter == surveyed_freq;
}
+struct nl80211_get_survey_arg {
+ struct survey_results *survey_results;
+ bool acs_exclude_6ghz_non_psc;
+};
static int survey_handler(struct nl_msg *msg, void *arg)
{
@@ -9040,15 +9044,19 @@ static int survey_handler(struct nl_msg
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
struct survey_results *survey_results;
+ struct nl80211_get_survey_arg *arg_survey =
+ (struct nl80211_get_survey_arg *)arg;
u32 surveyed_freq = 0;
u32 ifidx;
+ bool acs_exclude_6ghz_non_psc;
static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
};
- survey_results = (struct survey_results *) arg;
+ survey_results = arg_survey->survey_results;
+ acs_exclude_6ghz_non_psc = arg_survey->acs_exclude_6ghz_non_psc;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
@@ -9077,6 +9085,11 @@ static int survey_handler(struct nl_msg
survey_results->freq_filter))
return NL_SKIP;
+ if (is_6ghz_freq(surveyed_freq) &&
+ acs_exclude_6ghz_non_psc &&
+ !is_6ghz_psc_frequency(surveyed_freq))
+ return NL_SKIP;
+
if (survey_results->freq_filter &&
survey_results->freq_filter != surveyed_freq) {
wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
@@ -9090,19 +9103,22 @@ static int survey_handler(struct nl_msg
}
-static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
+static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq,
+ bool acs_exclude_6ghz_non_psc)
{
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
struct nl_msg *msg;
int err;
union wpa_event_data data;
- struct survey_results *survey_results;
+ struct nl80211_get_survey_arg arg;
os_memset(&data, 0, sizeof(data));
- survey_results = &data.survey_results;
+ os_memset(&arg, 0, sizeof(arg));
+ arg.survey_results = &data.survey_results;
+ arg.acs_exclude_6ghz_non_psc = acs_exclude_6ghz_non_psc;
- dl_list_init(&survey_results->survey_list);
+ dl_list_init(&arg.survey_results->survey_list);
msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
if (!msg)
@@ -9114,7 +9130,7 @@ static int wpa_driver_nl80211_get_survey
do {
wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
err = send_and_recv_msgs(drv, msg, survey_handler,
- survey_results, NULL, NULL);
+ &arg, NULL, NULL);
} while (err > 0);
if (err)
@@ -9122,7 +9138,7 @@ static int wpa_driver_nl80211_get_survey
else
wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
- clean_survey_results(survey_results);
+ clean_survey_results(arg.survey_results);
return err;
}