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