mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 02:43:38 +00:00
713 lines
22 KiB
Diff
713 lines
22 KiB
Diff
From 78bf22c80ae49d8721283b683fce8e86a75ec03d Mon Sep 17 00:00:00 2001
|
|
From: Aloka Dixit <alokad@codeaurora.org>
|
|
Date: Thu, 10 Dec 2020 15:13:11 -0800
|
|
Subject: [PATCH] hostad: RNR for EMA AP
|
|
|
|
(1) Enable RNR by default for EMA AP.
|
|
(2) Only for EMA AP, split reduced neighbor report in as many groups as
|
|
number of multiple BSSID offset groups.
|
|
Each RNR group skips the profiles already include in the corresponding
|
|
MBSSID groups.
|
|
The last additional group will have data common for all EMA beacons.
|
|
(3) Enable reduced neighbor report by default in 5GHz/2.4GHz beacons
|
|
and probe responses if one or more 6GHz APs are co-located.
|
|
|
|
Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
|
|
---
|
|
src/ap/beacon.c | 38 ++++++--
|
|
src/ap/ieee802_11.c | 222 +++++++++++++++++++++++++++++++++----------
|
|
src/ap/ieee802_11.h | 14 +--
|
|
src/drivers/driver.h | 23 +++++
|
|
4 files changed, 230 insertions(+), 67 deletions(-)
|
|
|
|
--- a/src/ap/beacon.c
|
|
+++ b/src/ap/beacon.c
|
|
@@ -482,9 +482,11 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
buflen += hostapd_eid_owe_trans_len(hapd);
|
|
buflen += hostapd_eid_dpp_cc_len(hapd);
|
|
if (hapd->iconf->multiple_bssid)
|
|
- buflen += hostapd_eid_multiple_bssid_len(hapd, req_bss, 0,
|
|
+ buflen += hostapd_eid_multiple_bssid_len(hapd, req_bss,
|
|
+ WLAN_FC_STYPE_PROBE_RESP,
|
|
known_bssids,
|
|
- known_bssids_len);
|
|
+ known_bssids_len,
|
|
+ NULL);
|
|
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
|
|
|
|
resp = os_zalloc(buflen);
|
|
@@ -556,9 +558,11 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
pos = hostapd_get_mde(hapd, pos, epos - pos);
|
|
|
|
if (hapd->iconf->multiple_bssid)
|
|
- pos = hostapd_eid_multiple_bssid(hapd, req_bss, pos, epos, 0,
|
|
- NULL, 0, 0, 0, known_bssids,
|
|
- known_bssids_len);
|
|
+ pos = hostapd_eid_multiple_bssid(hapd, req_bss, pos, epos,
|
|
+ NULL, NULL, NULL, NULL, NULL,
|
|
+ 0, known_bssids,
|
|
+ known_bssids_len, 0,
|
|
+ WLAN_FC_STYPE_PROBE_RESP);
|
|
|
|
/* eCSA IE */
|
|
csa_pos = hostapd_eid_ecsa(hapd, pos);
|
|
@@ -1824,18 +1828,32 @@ int ieee802_11_build_ap_params(struct ho
|
|
if (hapd != hapd->iface->bss[0])
|
|
params->multiple_bssid_parent = hapd->iface->bss[0]->conf->iface;
|
|
|
|
- len = hostapd_eid_multiple_bssid_len(hapd, NULL, 1, NULL, 0);
|
|
+ len = hostapd_eid_multiple_bssid_len(hapd, NULL,
|
|
+ WLAN_FC_STYPE_BEACON,
|
|
+ NULL, 0,
|
|
+ ¶ms->rnr_ie_len);
|
|
params->multiple_bssid_ies = os_zalloc(len);
|
|
if (params->multiple_bssid_ies == NULL)
|
|
return -1;
|
|
+ if (params->rnr_ie_len) {
|
|
+ params->rnr_ies = os_zalloc(params->rnr_ie_len);
|
|
+ if (params->rnr_ies == NULL) {
|
|
+ os_free(params->multiple_bssid_ies);
|
|
+ params->multiple_bssid_ies = NULL;
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
end = hostapd_eid_multiple_bssid(hapd, NULL,
|
|
params->multiple_bssid_ies,
|
|
params->multiple_bssid_ies + len,
|
|
- 1, params->multiple_bssid_ie_offsets,
|
|
+ params->multiple_bssid_ie_offsets,
|
|
¶ms->multiple_bssid_ie_count,
|
|
+ params->rnr_ies,
|
|
+ params->rnr_ie_offsets,
|
|
+ ¶ms->rnr_ie_count,
|
|
+ params->rnr_ie_len, NULL, 0,
|
|
MULTIPLE_BSSID_IE_MAX,
|
|
- hapd->iconf->ema_beacon, NULL,
|
|
- 0);
|
|
+ WLAN_FC_STYPE_BEACON);
|
|
params->multiple_bssid_ie_len = end - params->multiple_bssid_ies;
|
|
if ((params->multiple_bssid_ie_count > 1) &&
|
|
(ext_cap_len >= 13) && (ext_cap_pos[12] & 0x08))
|
|
@@ -1857,6 +1875,8 @@ void ieee802_11_free_ap_params(struct wp
|
|
params->proberesp = NULL;
|
|
os_free(params->multiple_bssid_ies);
|
|
params->multiple_bssid_ies = NULL;
|
|
+ os_free(params->rnr_ies);
|
|
+ params->rnr_ies = NULL;
|
|
#ifdef CONFIG_FILS
|
|
os_free(params->fd_frame_tmpl);
|
|
params->fd_frame_tmpl = NULL;
|
|
--- a/src/ap/ieee802_11.c
|
|
+++ b/src/ap/ieee802_11.c
|
|
@@ -89,6 +89,26 @@ static void handle_auth(struct hostapd_d
|
|
int rssi, int from_queue,
|
|
struct hostapd_frame_info *fi);
|
|
|
|
+enum colocation_mode {
|
|
+ NO_COLOCATED_6GHZ,
|
|
+ STANDALONE_6GHZ,
|
|
+ COLOCATED_6GHZ,
|
|
+ COLOCATED_LOWER_BAND,
|
|
+};
|
|
+
|
|
+static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *reporting_hapd,
|
|
+ size_t *current_len,
|
|
+ int skip_ssid_start, int skip_ssid_end);
|
|
+static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
|
+ struct hostapd_data *reporting_hapd,
|
|
+ u8 *eid, size_t *current_len,
|
|
+ int skip_ssid_start, int skip_ssid_end);
|
|
+static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
|
|
+ size_t *current_len);
|
|
+static u8 * hostapd_eid_neighbor_report_db(struct hostapd_data *hapd, u8 *eid,
|
|
+ size_t *current_len);
|
|
+static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd);
|
|
|
|
u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
|
|
{
|
|
@@ -161,6 +181,33 @@ u8 * hostapd_eid_supp_rates(struct hosta
|
|
}
|
|
|
|
|
|
+size_t hostapd_eid_ext_supp_rates_len(struct hostapd_data *hapd)
|
|
+{
|
|
+ int num, h2e_required;
|
|
+
|
|
+ if (hapd->iface->current_rates == NULL)
|
|
+ return 0;
|
|
+
|
|
+ num = hapd->iface->num_rates;
|
|
+ if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
|
|
+ num++;
|
|
+
|
|
+ if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
|
|
+ num++;
|
|
+
|
|
+ h2e_required = (hapd->conf->sae_pwe == 1 ||
|
|
+ hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
|
|
+ hapd->conf->sae_pwe != 3 &&
|
|
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
|
|
+ if (h2e_required)
|
|
+ num++;
|
|
+
|
|
+ if (num <= 8)
|
|
+ return 0;
|
|
+ return (2 + num - 8);
|
|
+}
|
|
+
|
|
+
|
|
u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
|
|
{
|
|
u8 *pos = eid;
|
|
@@ -7052,20 +7099,27 @@ int hostapd_config_read_maclist(const ch
|
|
|
|
static size_t hostapd_eid_multiple_bssid_chunk_len(struct hostapd_data *hapd,
|
|
struct hostapd_data *req_bss,
|
|
- int *count, u8 is_beacon,
|
|
+ int *count, u32 type,
|
|
const u8 *known_bssids,
|
|
u8 known_bssids_len)
|
|
{
|
|
/* ID + size + count */
|
|
int i, j;
|
|
size_t ies_len = 0, len = 3, nontx_profile_len;
|
|
- u8 mask;
|
|
- struct hostapd_data *bss;
|
|
+ u8 mask, ie_count;
|
|
+ struct hostapd_data *bss, *primary = hostapd_get_primary_bss(hapd);
|
|
struct hostapd_bss_config *conf;
|
|
|
|
+ if (!primary || !primary->conf)
|
|
+ return 0;
|
|
+
|
|
for (i = *count; i < hapd->iface->num_bss; i++) {
|
|
bss = hapd->iface->bss[i];
|
|
+ if (!bss || !bss->conf || !bss->started)
|
|
+ continue;
|
|
+
|
|
conf = bss->conf;
|
|
+ ie_count = 0;
|
|
|
|
j = i / 8;
|
|
mask = (u8)1 << (i % 8);
|
|
@@ -7086,18 +7140,25 @@ static size_t hostapd_eid_multiple_bssid
|
|
conf->ignore_broadcast_ssid == 2 || bss == req_bss)
|
|
nontx_profile_len += conf->ssid.ssid_len;
|
|
|
|
- if (is_beacon)
|
|
+ if (type == WLAN_FC_STYPE_BEACON)
|
|
nontx_profile_len += 2;
|
|
|
|
if (wpa_auth_get_wpa_ie(bss->wpa_auth, &ies_len))
|
|
nontx_profile_len += ies_len;
|
|
- else if (wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len))
|
|
- nontx_profile_len += 8; /* Non-inheritance element */
|
|
+ if (hostapd_wpa_ie(primary, WLAN_EID_RSN) &&
|
|
+ !hostapd_wpa_ie(bss, WLAN_EID_RSN))
|
|
+ ie_count++;
|
|
+ if (hostapd_wpa_ie(primary, WLAN_EID_RSNX) &&
|
|
+ !hostapd_wpa_ie(bss, WLAN_EID_RSNX))
|
|
+ ie_count++;
|
|
+
|
|
+ if (bss->iface->current_rates && bss->iface->num_rates > 8)
|
|
+ nontx_profile_len += hostapd_eid_ext_supp_rates_len(bss);
|
|
+ else if (primary->conf->xrates_supported)
|
|
+ ie_count++;
|
|
|
|
- if (bss->conf->xrates_supported)
|
|
- nontx_profile_len += 8; /*ext supp rates*/
|
|
- else if (hapd->conf->xrates_supported)
|
|
- nontx_profile_len += 3; /* Non-inheritance element for xrates */
|
|
+ if (ie_count)
|
|
+ nontx_profile_len += (4 + ie_count);
|
|
|
|
if (len + nontx_profile_len > 255) {
|
|
goto multiple_bssid_too_big;
|
|
@@ -7113,18 +7174,33 @@ multiple_bssid_too_big:
|
|
|
|
|
|
size_t hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd,
|
|
- struct hostapd_data *req_bss,
|
|
- u8 is_beacon, const u8 *known_bssids,
|
|
- u8 known_bssids_len)
|
|
+ struct hostapd_data *req_bss, u32 type,
|
|
+ const u8 *known_bssids, u8 known_bssids_len,
|
|
+ size_t *rnr_len)
|
|
{
|
|
- int count = 1;
|
|
- size_t len = 0;
|
|
+ int count = 1, rnr_count;
|
|
+ size_t len = 0, rnr_current_len = 0;
|
|
+
|
|
+ while (count < hapd->iface->num_bss) {
|
|
+ rnr_count = count;
|
|
|
|
- while (count < hapd->iface->num_bss)
|
|
len += hostapd_eid_multiple_bssid_chunk_len(hapd, req_bss,
|
|
- &count, is_beacon,
|
|
+ &count, type,
|
|
known_bssids,
|
|
known_bssids_len);
|
|
+ if (hapd->iconf->ema_beacon && rnr_len) {
|
|
+ rnr_current_len = 0;
|
|
+ (*rnr_len) += hostapd_eid_rnr_iface_len(hapd,
|
|
+ hostapd_get_primary_bss(hapd),
|
|
+ &rnr_current_len,
|
|
+ rnr_count,
|
|
+ count);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (hapd->iconf->ema_beacon && rnr_len)
|
|
+ (*rnr_len) += hostapd_eid_rnr_len(hapd, type);
|
|
+
|
|
return len;
|
|
}
|
|
|
|
@@ -7132,16 +7208,19 @@ size_t hostapd_eid_multiple_bssid_len(st
|
|
static u8 * hostapd_eid_multiple_bssid_chunk(struct hostapd_data *hapd,
|
|
struct hostapd_data *req_bss,
|
|
u8 *eid, u8 *end, int *count,
|
|
- u8 is_beacon, u8 *dtim_offset[],
|
|
+ u32 type, u8 *dtim_offset[],
|
|
const u8 *known_bssids,
|
|
u8 known_bssids_len)
|
|
{
|
|
- struct hostapd_data *bss;
|
|
+ struct hostapd_data *bss, *primary = hostapd_get_primary_bss(hapd);
|
|
struct hostapd_bss_config *conf;
|
|
u8 *size_offset, *num_offset, mask;
|
|
int i, j, ie_count = 0;
|
|
u8 non_inherit_ie[3] = {0};
|
|
|
|
+ if (!primary || !primary->conf)
|
|
+ return eid;
|
|
+
|
|
*eid++ = WLAN_EID_MULTIPLE_BSSID;
|
|
size_offset = eid++;
|
|
num_offset = eid++;
|
|
@@ -7149,9 +7228,13 @@ static u8 * hostapd_eid_multiple_bssid_c
|
|
for (i = *count; i < hapd->iface->num_bss; i++) {
|
|
u8 *bss_size_offset, *index_size_offset, *pos = eid;
|
|
u16 capab_info;
|
|
- ie_count = 0;
|
|
+
|
|
bss = hapd->iface->bss[i];
|
|
+ if (!bss || !bss->conf || !bss->started)
|
|
+ continue;
|
|
+
|
|
conf = bss->conf;
|
|
+ ie_count = 0;
|
|
|
|
j = i / 8;
|
|
mask = (u8)1 << (i % 8);
|
|
@@ -7184,7 +7267,7 @@ static u8 * hostapd_eid_multiple_bssid_c
|
|
*eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX;
|
|
index_size_offset = eid++;
|
|
*eid++ = i;
|
|
- if (is_beacon) {
|
|
+ if (type == WLAN_FC_STYPE_BEACON) {
|
|
dtim_offset[i] = eid;
|
|
*eid++ = conf->dtim_period;
|
|
*eid++ = 0xFF;
|
|
@@ -7198,19 +7281,19 @@ static u8 * hostapd_eid_multiple_bssid_c
|
|
/* Add non inheritance ie for capabalities that
|
|
* are not inherited by non tx vap from tx vap
|
|
*/
|
|
-
|
|
- if (hostapd_wpa_ie(hapd, WLAN_EID_RSN) &&
|
|
+ if (hostapd_wpa_ie(primary, WLAN_EID_RSN) &&
|
|
!hostapd_wpa_ie(bss, WLAN_EID_RSN)) {
|
|
non_inherit_ie[ie_count] = WLAN_EID_RSN;
|
|
ie_count++;
|
|
}
|
|
|
|
- if (hapd->conf->xrates_supported &&
|
|
+ if (primary->conf->xrates_supported &&
|
|
!bss->conf->xrates_supported) {
|
|
non_inherit_ie[ie_count] = WLAN_EID_EXT_SUPP_RATES;
|
|
ie_count++;
|
|
}
|
|
- if (hostapd_wpa_ie(hapd, WLAN_EID_RSNX) &&
|
|
+
|
|
+ if (hostapd_wpa_ie(primary, WLAN_EID_RSNX) &&
|
|
!hostapd_wpa_ie(bss, WLAN_EID_RSNX)) {
|
|
non_inherit_ie[ie_count] = WLAN_EID_RSNX;
|
|
ie_count++;
|
|
@@ -7246,30 +7329,62 @@ multiple_bssid_too_big:
|
|
|
|
u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd,
|
|
struct hostapd_data *req_bss, u8 *eid, u8 *end,
|
|
- u8 is_beacon, u8 **eid_offsets, int *eid_count,
|
|
- int eid_max, u8 ema_beacon,
|
|
- const u8 *known_bssids, u8 known_bssids_len)
|
|
+ u8 **eid_offsets, int *eid_count, u8 *rnr_eid,
|
|
+ u8 **rnr_offsets, int *rnr_count, int rnr_len,
|
|
+ const u8 *known_bssids, u8 known_bssids_len,
|
|
+ int eid_max, u32 type)
|
|
{
|
|
int count = 1, dtim_period;
|
|
+ size_t current_len = 0;
|
|
u8 remainder, **dtim_offset = NULL;
|
|
- struct hostapd_bss_config *conf;
|
|
struct hostapd_iface *iface = hapd->iface;
|
|
+ u8 *rnr_start_eid = rnr_eid;
|
|
+ bool add_rnr = false;
|
|
|
|
if (eid_count &&
|
|
!(dtim_offset = os_zalloc(iface->num_bss * sizeof(eid))))
|
|
return eid;
|
|
|
|
+ if (hapd->iconf->ema_beacon && type == WLAN_FC_STYPE_BEACON && rnr_len)
|
|
+ add_rnr = true;
|
|
+
|
|
while (count < iface->num_bss) {
|
|
+ int rnr_start_count = count;
|
|
+
|
|
if (eid_offsets && eid_count && (*eid_count < eid_max) &&
|
|
- (ema_beacon || count == 1)) {
|
|
+ (hapd->iconf->ema_beacon || count == 1)) {
|
|
eid_offsets[*eid_count] = eid;
|
|
*eid_count = *eid_count + 1;
|
|
}
|
|
eid = hostapd_eid_multiple_bssid_chunk(hapd, req_bss, eid, end,
|
|
- &count, is_beacon,
|
|
+ &count, type,
|
|
dtim_offset,
|
|
known_bssids,
|
|
known_bssids_len);
|
|
+
|
|
+ if (add_rnr == true) {
|
|
+ rnr_offsets[*rnr_count] = rnr_eid;
|
|
+ *rnr_count = *rnr_count + 1;
|
|
+ current_len = 0;
|
|
+
|
|
+ rnr_eid = hostapd_eid_rnr_iface(hapd,
|
|
+ hostapd_get_primary_bss(hapd),
|
|
+ rnr_eid, ¤t_len,
|
|
+ rnr_start_count, count);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ((add_rnr == true) && ((rnr_eid - rnr_start_eid) < rnr_len)) {
|
|
+ rnr_offsets[*rnr_count] = rnr_eid;
|
|
+ *rnr_count = *rnr_count + 1;
|
|
+ current_len = 0;
|
|
+
|
|
+ if (hapd->conf->rnr_beacon)
|
|
+ rnr_eid = hostapd_eid_neighbor_report_db(hapd, rnr_eid,
|
|
+ ¤t_len);
|
|
+ if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND)
|
|
+ rnr_eid = hostapd_eid_rnr_colocation(hapd, rnr_eid,
|
|
+ ¤t_len);
|
|
}
|
|
|
|
if (!eid_count || !(*eid_count)) {
|
|
@@ -7283,7 +7398,14 @@ u8 * hostapd_eid_multiple_bssid(struct h
|
|
break;
|
|
|
|
for (count = 0; count < iface->num_bss; count++) {
|
|
- conf = iface->bss[count]->conf;
|
|
+ struct hostapd_data *bss;
|
|
+ struct hostapd_bss_config *conf;
|
|
+
|
|
+ bss = iface->bss[count];
|
|
+ if (!bss || !bss->conf || !bss->started)
|
|
+ continue;
|
|
+
|
|
+ conf = bss->conf;
|
|
dtim_period = conf->dtim_period;
|
|
remainder = dtim_period % (*eid_count);
|
|
if (remainder) {
|
|
@@ -7304,9 +7426,10 @@ u8 * hostapd_eid_multiple_bssid(struct h
|
|
}
|
|
|
|
|
|
-size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
|
+static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
|
struct hostapd_data *reporting_hapd,
|
|
- size_t *current_len)
|
|
+ size_t *current_len,
|
|
+ int skip_ssid_start, int skip_ssid_end)
|
|
{
|
|
size_t total_len = 0;
|
|
int i, tbtt_count = 0, start = 0;
|
|
@@ -7323,8 +7446,17 @@ size_t hostapd_eid_rnr_iface_len(struct
|
|
total_len += TBTT_HEADER_LENGTH;
|
|
|
|
for (i = start; i < hapd->iface->num_bss; i++) {
|
|
- if (hapd->iface->bss[i] == reporting_hapd ||
|
|
- hapd->conf->ignore_broadcast_ssid)
|
|
+ struct hostapd_data *bss = hapd->iface->bss[i];
|
|
+
|
|
+ if (!bss || !bss->conf || !bss->started)
|
|
+ continue;
|
|
+
|
|
+ if (bss == reporting_hapd ||
|
|
+ bss->conf->ignore_broadcast_ssid)
|
|
+ continue;
|
|
+
|
|
+ if ((skip_ssid_start != -1) && (skip_ssid_end != -1) &&
|
|
+ (i >= skip_ssid_start) && (i < skip_ssid_end))
|
|
continue;
|
|
|
|
if ((*current_len + TBTT_INFO_LENGTH > 255) ||
|
|
@@ -7362,7 +7494,7 @@ static size_t hostapd_eid_rnr_colocation
|
|
continue;
|
|
|
|
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
|
|
- current_len);
|
|
+ current_len, -1, -1);
|
|
}
|
|
return len;
|
|
}
|
|
@@ -7395,48 +7527,71 @@ static size_t hostapd_eid_neighbor_repor
|
|
}
|
|
|
|
|
|
-static bool is_6ghz_colocated(struct hostapd_data *hapd)
|
|
+static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
|
|
{
|
|
u8 i;
|
|
- struct hostapd_iface *iface;
|
|
+ bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class);
|
|
|
|
if ((hapd->iface == NULL) || (hapd->iface->interfaces == NULL))
|
|
- return false;
|
|
+ return NO_COLOCATED_6GHZ;
|
|
|
|
- if (is_6ghz_op_class(hapd->iconf->op_class) ||
|
|
- hapd->iface->interfaces->count == 1)
|
|
- return false;
|
|
+ if (is_6ghz && (hapd->iface->interfaces->count == 1))
|
|
+ return STANDALONE_6GHZ;
|
|
|
|
for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
|
+ struct hostapd_iface *iface;
|
|
+ bool is_colocated_6ghz;
|
|
+
|
|
iface = hapd->iface->interfaces->iface[i];
|
|
- if (iface == hapd->iface)
|
|
+ if (iface == hapd->iface || !iface || !iface->conf)
|
|
continue;
|
|
|
|
- if (is_6ghz_op_class(iface->bss[0]->iconf->op_class) &&
|
|
- iface->conf->he_co_locate)
|
|
- return true;
|
|
+ is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class);
|
|
+ if (!is_6ghz && is_colocated_6ghz)
|
|
+ return COLOCATED_LOWER_BAND;
|
|
+ else if (is_6ghz && !is_colocated_6ghz)
|
|
+ return COLOCATED_6GHZ;
|
|
}
|
|
- return false;
|
|
+
|
|
+ if (is_6ghz)
|
|
+ return STANDALONE_6GHZ;
|
|
+
|
|
+ return NO_COLOCATED_6GHZ;
|
|
}
|
|
|
|
|
|
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
|
{
|
|
size_t len = 0, current_len = 0;
|
|
+ enum colocation_mode mode = get_colocation_mode(hapd);
|
|
|
|
- if (hapd->conf->rnr_beacon) {
|
|
- if (hapd->iface->num_bss > 1)
|
|
- len += hostapd_eid_rnr_iface_len(hapd, hapd,
|
|
- ¤t_len);
|
|
-
|
|
- if ((type == WLAN_FC_STYPE_BEACON) &&
|
|
- !dl_list_empty(&hapd->nr_db))
|
|
+ switch (type) {
|
|
+ case WLAN_FC_STYPE_BEACON:
|
|
+ if (hapd->conf->rnr_beacon && !dl_list_empty(&hapd->nr_db))
|
|
len += hostapd_eid_neighbor_report_db_len(hapd,
|
|
¤t_len);
|
|
- }
|
|
+ /* fallthrough */
|
|
+
|
|
+ case WLAN_FC_STYPE_PROBE_RESP:
|
|
+ if (mode == COLOCATED_LOWER_BAND)
|
|
+ len += hostapd_eid_rnr_colocation_len(hapd,
|
|
+ ¤t_len);
|
|
+
|
|
+ if (hapd->conf->rnr_beacon && hapd->iface->num_bss > 1 &&
|
|
+ !hapd->iconf->multiple_bssid)
|
|
+ len += hostapd_eid_rnr_iface_len(hapd, hapd,
|
|
+ ¤t_len, -1, -1);
|
|
+ break;
|
|
|
|
- if ((true == is_6ghz_colocated(hapd)) && type != WLAN_FC_STYPE_ACTION)
|
|
- len += hostapd_eid_rnr_colocation_len(hapd, ¤t_len);
|
|
+ case WLAN_FC_STYPE_ACTION:
|
|
+ if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
|
|
+ len += hostapd_eid_rnr_iface_len(hapd, hapd,
|
|
+ ¤t_len, -1, -1);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ return 0;
|
|
+ }
|
|
|
|
return len;
|
|
}
|
|
@@ -7444,7 +7599,8 @@ size_t hostapd_eid_rnr_len(struct hostap
|
|
|
|
static u8 *hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
|
struct hostapd_data *reporting_hapd,
|
|
- u8 *eid, size_t *current_len)
|
|
+ u8 *eid, size_t *current_len,
|
|
+ int skip_ssid_start, int skip_ssid_end)
|
|
{
|
|
u8 *eid_start = eid, *tbtt_count_pos = NULL;
|
|
u8 tbtt_count = 0, op_class, channel, bss_param;
|
|
@@ -7483,9 +7639,15 @@ static u8 *hostapd_eid_rnr_iface(struct
|
|
for (i = start; i < iface->num_bss; i++) {
|
|
bss_param = 0;
|
|
bss = iface->bss[i];
|
|
+ if (!bss || !bss->conf || !bss->started)
|
|
+ continue;
|
|
|
|
if (bss == reporting_hapd ||
|
|
- hapd->conf->ignore_broadcast_ssid)
|
|
+ bss->conf->ignore_broadcast_ssid)
|
|
+ continue;
|
|
+
|
|
+ if ((skip_ssid_start != -1) && (skip_ssid_end != -1) &&
|
|
+ (i >= skip_ssid_start) && (i < skip_ssid_end))
|
|
continue;
|
|
|
|
if ((*current_len + TBTT_INFO_LENGTH > 255) ||
|
|
@@ -7547,7 +7709,7 @@ static u8 * hostapd_eid_rnr_colocation(s
|
|
continue;
|
|
|
|
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
|
|
- current_len);
|
|
+ current_len, -1, -1);
|
|
}
|
|
return eid;
|
|
}
|
|
@@ -7600,19 +7762,38 @@ u8 * hostapd_eid_rnr(struct hostapd_data
|
|
{
|
|
u8 *eid_start = eid;
|
|
size_t current_len = 0;
|
|
+ enum colocation_mode mode = get_colocation_mode(hapd);
|
|
|
|
- if (hapd->conf->rnr_beacon) {
|
|
- if (hapd->iface->num_bss > 1)
|
|
- eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
|
|
- ¤t_len);
|
|
+ switch (type) {
|
|
+ case WLAN_FC_STYPE_BEACON:
|
|
+ if (hapd->iconf->ema_beacon)
|
|
+ return eid_start;
|
|
|
|
- if (type == WLAN_FC_STYPE_BEACON)
|
|
+ if (hapd->conf->rnr_beacon)
|
|
eid = hostapd_eid_neighbor_report_db(hapd, eid,
|
|
¤t_len);
|
|
- }
|
|
+ /* fallthrough */
|
|
+
|
|
+ case WLAN_FC_STYPE_PROBE_RESP:
|
|
+ if (mode == COLOCATED_LOWER_BAND)
|
|
+ eid = hostapd_eid_rnr_colocation(hapd, eid,
|
|
+ ¤t_len);
|
|
+
|
|
+ if (hapd->conf->rnr_beacon && hapd->iface->num_bss > 1 &&
|
|
+ !hapd->iconf->multiple_bssid)
|
|
+ eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
|
|
+ ¤t_len, -1, -1);
|
|
+ break;
|
|
|
|
- if ((true == is_6ghz_colocated(hapd)) && type != WLAN_FC_STYPE_ACTION)
|
|
- eid = hostapd_eid_rnr_colocation(hapd, eid, ¤t_len);
|
|
+ case WLAN_FC_STYPE_ACTION:
|
|
+ if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
|
|
+ eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
|
|
+ ¤t_len, -1, -1);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ return eid_start;
|
|
+ }
|
|
|
|
if (eid == (eid_start + 2))
|
|
return eid_start;
|
|
--- a/src/ap/ieee802_11.h
|
|
+++ b/src/ap/ieee802_11.h
|
|
@@ -129,15 +129,17 @@ u8 * hostapd_eid_time_zone(struct hostap
|
|
int hostapd_update_time_adv(struct hostapd_data *hapd);
|
|
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
|
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
|
+u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
|
|
u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd,
|
|
struct hostapd_data *req_bss, u8 *eid, u8 *end,
|
|
- u8 is_beacon, u8 **eid_offsets, int *eid_count,
|
|
- int eid_max, u8 ema_beacon,
|
|
- const u8 *known_bssids, u8 known_bssids_len);
|
|
+ u8 **eid_offsets, int *eid_count, u8 *rnr_eid,
|
|
+ u8 **rnr_offsets, int *rnr_count, int rnr_len,
|
|
+ const u8 *known_bssids, u8 known_bssids_len,
|
|
+ int eid_max, u32 type);
|
|
size_t hostapd_eid_multiple_bssid_len(struct hostapd_data *hapd,
|
|
- struct hostapd_data *req_bss, u8 is_beacon,
|
|
- const u8 *known_bssids, u8 known_bssids_len);
|
|
-u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
|
|
+ struct hostapd_data *req_bss, u32 type,
|
|
+ const u8 *known_bssids,
|
|
+ u8 known_bssids_len, size_t *rnr_len);
|
|
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
|
|
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|
|
#ifdef CONFIG_SAE
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -1232,6 +1232,7 @@ struct wowlan_triggers {
|
|
};
|
|
|
|
#define MULTIPLE_BSSID_IE_MAX 8
|
|
+#define RNR_BSSID_IE_MAX (MULTIPLE_BSSID_IE_MAX + 1)
|
|
|
|
struct wpa_driver_ap_params {
|
|
/**
|
|
@@ -1630,6 +1631,27 @@ struct wpa_driver_ap_params {
|
|
*/
|
|
int ema_beacon;
|
|
|
|
+ /**
|
|
+ * rnr_ies - This buffer contains all of RNR elements
|
|
+ */
|
|
+ u8 *rnr_ies;
|
|
+
|
|
+ /**
|
|
+ * rnr_ie_len - Length of RNR IE buffer
|
|
+ */
|
|
+ size_t rnr_ie_len;
|
|
+
|
|
+ /**
|
|
+ * rnr_ie_offsets - The offsets to the elements inside rnr_ies.
|
|
+ * Each MBSSID IE has corresponding RNR IE offset.
|
|
+ * The extra offset is for the common part of RNR
|
|
+ */
|
|
+ u8 *rnr_ie_offsets[MULTIPLE_BSSID_IE_MAX+1];
|
|
+
|
|
+ /**
|
|
+ * rnr_ie_count - Number of offsets in rnr_ie_offsets
|
|
+ */
|
|
+ int rnr_ie_count;
|
|
};
|
|
|
|
struct wpa_driver_mesh_bss_params {
|
|
@@ -2291,6 +2313,7 @@ struct wpa_bss_params {
|
|
int wpa_key_mgmt;
|
|
int rsn_preauth;
|
|
enum mfp_options ieee80211w;
|
|
+
|
|
};
|
|
|
|
#define WPA_STA_AUTHORIZED BIT(0)
|