[PATCH 12/13] mbssid: process known BSSID element
Aloka Dixit
quic_alokad at quicinc.com
Wed Mar 2 14:26:33 PST 2022
Process the known BSSID elements if included by non-AP stations.
The format is described in IEEE Std 802.11ax-2021 9.4.2.261.
Non-AP stations may include this element in directed probe requests
to indicate which of the multiple BSSIDs they have already discovered.
AP should exclude these profiles from the probe response.
Signed-off-by: Aloka Dixit <quic_alokad at quicinc.com>
---
src/ap/beacon.c | 21 +++++++++++++--------
src/ap/ieee802_11.c | 31 +++++++++++++++++++++++++------
src/ap/ieee802_11.h | 6 ++++--
src/common/ieee802_11_common.c | 4 ++++
src/common/ieee802_11_common.h | 2 ++
src/common/ieee802_11_defs.h | 1 +
6 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 5f22dfc8cde2..76b93f5ef6ce 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -456,7 +456,8 @@ static u8 * hostapd_set_mbssid_beacon(struct hostapd_data *hapd,
params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
params->mbssid_count = iface->num_bss;
- len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &num_mbssid);
+ len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &num_mbssid,
+ NULL, 0);
if (hapd->iconf->ema) {
if (!iface->ema_max_periodicity) {
wpa_printf(MSG_DEBUG,
@@ -497,7 +498,7 @@ static u8 * hostapd_set_mbssid_beacon(struct hostapd_data *hapd,
params->mbssid_elem + len,
WLAN_FC_STYPE_BEACON,
params->mbssid_elem_count,
- params->mbssid_elem_offset);
+ params->mbssid_elem_offset, NULL, 0);
params->mbssid_elem_len = end - params->mbssid_elem;
if (hapd->iconf->ema) {
@@ -542,7 +543,8 @@ static u8 * hostapd_ext_capab_mbssid(struct hostapd_data *hapd, u8 *eid,
static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
const struct ieee80211_mgmt *req,
- int is_p2p, size_t *resp_len)
+ int is_p2p, size_t *resp_len,
+ const u8 *known_bss, u8 known_bss_len)
{
struct ieee80211_mgmt *resp;
u8 *pos, *epos, *csa_pos, *ext_cap_pos;
@@ -586,7 +588,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AX */
buflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP,
- NULL);
+ NULL, known_bss, known_bss_len);
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
buflen += hostapd_mbo_ie_len(hapd);
buflen += hostapd_eid_owe_trans_len(hapd);
@@ -667,7 +669,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
pos = hostapd_eid_ht_capabilities(hapd, pos);
pos = hostapd_eid_ht_operation(hapd, pos);
pos = hostapd_eid_mbssid(hapd_probed, pos, epos,
- WLAN_FC_STYPE_PROBE_RESP, 0, NULL);
+ WLAN_FC_STYPE_PROBE_RESP, 0, NULL,
+ known_bss, known_bss_len);
ext_cap_pos = pos;
pos = hostapd_eid_ext_capab(hapd, pos);
@@ -1214,7 +1217,8 @@ void handle_probe_req(struct hostapd_data *hapd,
" signal=%d", MAC2STR(mgmt->sa), ssi_signal);
resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
- &resp_len);
+ &resp_len, elems.mbssid_known_bss,
+ elems.mbssid_known_bss_len);
if (resp == NULL)
return;
@@ -1284,7 +1288,7 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
"this");
/* Generate a Probe Response template for the non-P2P case */
- return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len);
+ return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, NULL, 0);
}
#endif /* NEED_AP_MLME */
@@ -1301,7 +1305,8 @@ static u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
hapd->conf->unsol_bcast_probe_resp_interval;
return hostapd_gen_probe_resp(hapd, NULL, 0,
- ¶ms->unsol_bcast_probe_resp_tmpl_len);
+ ¶ms->unsol_bcast_probe_resp_tmpl_len,
+ NULL, 0);
}
#endif /* CONFIG_IEEE80211AX */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 36d6831b2376..9a189d733487 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -7472,7 +7472,9 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
- u32 frame_type, size_t *bss_index)
+ u32 frame_type, size_t *bss_index,
+ const u8 *known_bss,
+ size_t known_bss_len)
{
struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd);
size_t len = 3, i;
@@ -7483,6 +7485,12 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
size_t nontx_profile_len, auth_len;
u8 ie_count = 0;
+ if (known_bss && (known_bss_len > (i / 8))) {
+ known_bss = &known_bss[i / 8];
+ if (*known_bss & (u8)(BIT(i % 8)))
+ continue;
+ }
+
if (!bss || !bss->conf || !bss->started)
continue;
@@ -7534,7 +7542,8 @@ mbssid_too_big:
size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
- u8 *elem_count)
+ u8 *elem_count, const u8 *known_bss,
+ size_t known_bss_len)
{
size_t len = 0, bss_index = 1;
@@ -7554,7 +7563,8 @@ size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
while (bss_index < hapd->iface->num_bss) {
len += hostapd_eid_mbssid_elem_len(hapd, frame_type,
- &bss_index);
+ &bss_index, known_bss,
+ known_bss_len);
if (frame_type == WLAN_FC_STYPE_BEACON)
*elem_count += 1;
@@ -7565,7 +7575,8 @@ size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
u32 frame_type, u8 max_bssid_indicator,
- size_t *bss_index, u8 elem_count)
+ size_t *bss_index, u8 elem_count,
+ const u8 *known_bss, size_t known_bss_len)
{
struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd);
size_t i;
@@ -7584,6 +7595,12 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
size_t auth_len = 0;
u16 capab_info;
+ if (known_bss && (known_bss_len > (i / 8))) {
+ known_bss = &known_bss[i / 8];
+ if (*known_bss & (u8)(BIT(i % 8)))
+ continue;
+ }
+
if (!bss || !bss->conf || !bss->started)
continue;
conf = bss->conf;
@@ -7675,7 +7692,8 @@ mbssid_too_big:
u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
- u32 frame_type, u8 elem_count, u8 **elem_offset)
+ u32 frame_type, u8 elem_count, u8 **elem_offset,
+ const u8 *known_bss, size_t known_bss_len)
{
size_t bss_index = 1;
u8 elem_index = 0;
@@ -7703,7 +7721,8 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
}
eid = hostapd_eid_mbssid_elem(hapd, eid, end, frame_type,
hostapd_max_bssid_indicator(hapd),
- &bss_index, elem_count);
+ &bss_index, elem_count,
+ known_bss, known_bss_len);
}
return eid;
}
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 37df3faa724c..e75ff4ee861f 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -121,9 +121,11 @@ 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);
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
- u8 *elem_count);
+ u8 *elem_count, const u8 *known_bss,
+ size_t known_bss_len);
u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
- u32 frame_type, u8 elem_count, u8 **elem_offset);
+ u32 frame_type, u8 elem_count, u8 **elem_offset,
+ const u8 *known_bss, size_t known_bss_len);
#ifdef CONFIG_SAE
void sae_clear_retransmit_timer(struct hostapd_data *hapd,
struct sta_info *sta);
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 5b74ddcdf62b..3ff111ce3fa7 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -307,6 +307,10 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
elems->pasn_params = pos;
elems->pasn_params_len = elen;
break;
+ case WLAN_EID_EXT_KNOWN_BSSID:
+ elems->mbssid_known_bss = pos;
+ elems->mbssid_known_bss_len = elen;
+ break;
default:
if (show_errors) {
wpa_printf(MSG_MSGDUMP,
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index e4e4c613e9c6..a62ea5901f82 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -117,6 +117,7 @@ struct ieee802_11_elems {
const u8 *sae_pk;
const u8 *s1g_capab;
const u8 *pasn_params;
+ const u8 *mbssid_known_bss;
u8 ssid_len;
u8 supp_rates_len;
@@ -171,6 +172,7 @@ struct ieee802_11_elems {
u8 short_ssid_list_len;
u8 sae_pk_len;
u8 pasn_params_len;
+ u8 mbssid_known_bss_len;
struct mb_ies_info mb_ies;
struct frag_ies_info frag_ies;
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 4747714e3219..8657ce697d7c 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -482,6 +482,7 @@
#define WLAN_EID_EXT_OCV_OCI 54
#define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55
#define WLAN_EID_EXT_NON_INHERITANCE 56
+#define WLAN_EID_EXT_KNOWN_BSSID 57
#define WLAN_EID_EXT_SHORT_SSID_LIST 58
#define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59
#define WLAN_EID_EXT_EDMG_CAPABILITIES 61
--
2.31.1
More information about the Hostap
mailing list