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@xxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap