[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,
-				      &params->unsol_bcast_probe_resp_tmpl_len);
+				      &params->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