[PATCH v4 09/15] mbssid: process known BSSID element
Aloka Dixit
quic_alokad at quicinc.com
Wed Nov 30 19:18:41 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 | 26 ++++++++++++++++----------
src/ap/ieee802_11.c | 31 +++++++++++++++++++++++++------
src/ap/ieee802_11.h | 7 ++++---
src/common/ieee802_11_common.c | 4 ++++
src/common/ieee802_11_common.h | 2 ++
src/common/ieee802_11_defs.h | 1 +
6 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index c5283adb135e..bfb954aaf465 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -479,7 +479,8 @@ static int ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd,
goto fail;
tx_bss = hostapd_mbssid_get_tx_bss(hapd);
- len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count);
+ len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count,
+ NULL, 0);
if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
elem_count > iface->ema_max_periodicity))
goto fail;
@@ -493,7 +494,7 @@ static int ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd,
goto fail;
end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON,
- elem_count, elem_offset);
+ elem_count, elem_offset, NULL, 0);
params->mbssid_tx_iface = tx_bss->conf->iface;
params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
@@ -523,7 +524,8 @@ fail:
static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
const struct ieee80211_mgmt *req,
int is_p2p, size_t *resp_len,
- bool bcast_probe_resp)
+ bool bcast_probe_resp, const u8 *known_bss,
+ u8 known_bss_len)
{
struct ieee80211_mgmt *resp;
u8 *pos, *epos, *csa_pos, *ext_cap_pos;
@@ -577,7 +579,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
}
#endif /* CONFIG_IEEE80211BE */
- buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL);
+ buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, 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);
@@ -650,13 +653,15 @@ 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, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0,
- NULL);
+ NULL, known_bss, known_bss_len);
ext_cap_pos = pos;
pos = hostapd_eid_ext_capab(hapd, pos);
- if (hapd->iconf->mbssid >= MBSSID_ENABLED)
+ if (hapd->iconf->mbssid >= MBSSID_ENABLED && !known_bss_len)
ext_cap_pos[12] |= 0x01; /* Probe responses always include all
- * non-tx profiles */
+ * non-tx profiles except when a list
+ * of known BSSes is included in the
+ * probe request. */
pos = hostapd_eid_time_adv(hapd, pos);
pos = hostapd_eid_time_zone(hapd, pos);
@@ -1217,7 +1222,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, false);
+ &resp_len, false, elems.mbssid_known_bss,
+ elems.mbssid_known_bss_len);
if (resp == NULL)
return;
@@ -1287,7 +1293,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, false);
+ return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, false, NULL, 0);
}
#endif /* NEED_AP_MLME */
@@ -1306,7 +1312,7 @@ static u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
return hostapd_gen_probe_resp(hapd, NULL, 0,
¶ms->unsol_bcast_probe_resp_tmpl_len,
- true);
+ true, NULL, 0);
}
#endif /* CONFIG_IEEE80211AX */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index b64cc00de884..55175dc6dc5c 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -6725,7 +6725,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;
@@ -6736,6 +6738,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;
@@ -6786,7 +6794,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;
@@ -6806,7 +6815,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;
@@ -6817,7 +6827,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;
@@ -6836,6 +6847,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;
@@ -6923,7 +6940,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;
@@ -6951,7 +6969,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 1c545eff23e6..bb454bbd63a6 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -215,8 +215,9 @@ u16 copy_sta_eht_capab(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *he_capab, size_t he_capab_len,
const u8 *eht_capab, size_t eht_capab_len);
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);
#endif /* IEEE802_11_H */
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 924fe24f01c1..7080412bc31a 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -387,6 +387,10 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
show_errors))
return -1;
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 0d258dfb8709..9a1dbdda884e 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -108,6 +108,7 @@ struct ieee802_11_elems {
const u8 *reconf_mle;
const u8 *tdls_mle;
const u8 *prior_access_mle;
+ const u8 *mbssid_known_bss;
u8 ssid_len;
u8 supp_rates_len;
@@ -169,6 +170,7 @@ struct ieee802_11_elems {
size_t reconf_mle_len;
size_t tdls_mle_len;
size_t prior_access_mle_len;
+ u8 mbssid_known_bss_len;
struct mb_ies_info mb_ies;
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 5851ea942677..8a3556187c2f 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -483,6 +483,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.25.1
More information about the Hostap
mailing list