[PATCH v2 06/11] mbssid: configure parameters and element data

Aloka Dixit quic_alokad at quicinc.com
Wed May 11 13:49:26 PDT 2022


From: John Crispin <john at phrozen.org>

Add helper functions to retrieve the context for the transmitting
interfaces of the MBSSID set and the index of a given BSS.

Set device parameters - BSS index and the transmitting BSS.

Include multiple BSSID elements in beacon and probe response frames.

Signed-off-by: John Crispin <john at phrozen.org>
Co-developed-by: Aloka Dixit <quic_alokad at quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad at quicinc.com>
---
v2: Checks for error conditions before setting any
driver parameters.

 src/ap/beacon.c      | 80 ++++++++++++++++++++++++++++++++++++++++++--
 src/ap/hostapd.c     | 23 +++++++++++++
 src/ap/hostapd.h     |  2 ++
 src/drivers/driver.h | 36 ++++++++++++++++++++
 4 files changed, 138 insertions(+), 3 deletions(-)

diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 58872bfdab71..b2619bf40fe8 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -462,6 +462,55 @@ static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
 }
 
 
+static int ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd,
+					     struct wpa_driver_ap_params *params)
+{
+	struct hostapd_iface *iface = hapd->iface;
+	struct hostapd_data *tx_bss;
+	size_t len;
+	u8 elem_count = 0, *elem = NULL, **elem_offset = NULL, *end;
+
+	if (!iface->mbssid_max_interfaces ||
+	    iface->num_bss > iface->mbssid_max_interfaces ||
+	    (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
+	     !iface->ema_max_periodicity))
+		goto fail;
+
+	tx_bss = hostapd_mbssid_get_tx_bss(hapd);
+	len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count);
+	if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
+		     elem_count > iface->ema_max_periodicity))
+		goto fail;
+
+	elem = os_zalloc(len);
+	if (!elem)
+		goto fail;
+
+	elem_offset = os_zalloc(elem_count * sizeof(u8 *));
+	if (!elem_offset)
+		goto fail;
+
+	end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON,
+				 elem_count, elem_offset);
+
+	params->mbssid_tx_iface = tx_bss->conf->iface;
+	params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
+	params->mbssid_elem = elem;
+	params->mbssid_elem_len = end - elem;
+	params->mbssid_elem_count = elem_count;
+	params->mbssid_elem_offset = elem_offset;
+	if (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED)
+		params->ema = true;
+
+	return 0;
+
+fail:
+	os_free(elem);
+	wpa_printf(MSG_ERROR, "MBSSID: Configuration failed");
+	return -1;
+}
+
+
 static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 				   const struct ieee80211_mgmt *req,
 				   int is_p2p, size_t *resp_len,
@@ -471,6 +520,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 	u8 *pos, *epos, *csa_pos;
 	size_t buflen;
 
+	hapd = hostapd_mbssid_get_tx_bss(hapd);
+
 #define MAX_PROBERESP_LEN 768
 	buflen = MAX_PROBERESP_LEN;
 #ifdef CONFIG_WPS
@@ -517,6 +568,7 @@ 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_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
 	buflen += hostapd_mbo_ie_len(hapd);
 	buflen += hostapd_eid_owe_trans_len(hapd);
@@ -588,6 +640,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 	pos = hostapd_eid_supported_op_classes(hapd, pos);
 	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);
 
 	pos = hostapd_eid_ext_capab(hapd, pos);
 
@@ -1141,6 +1195,11 @@ void handle_probe_req(struct hostapd_data *hapd,
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
+	/* Do not send probe response from a non-transmitting multiple BSSID
+	 * profile unless the probe request is directed at that paticular BSS */
+	if (hapd != hostapd_mbssid_get_tx_bss(hapd) && res != EXACT_SSID_MATCH)
+		return;
+
 	wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR
 		     " signal=%d", MAC2STR(mgmt->sa), ssi_signal);
 
@@ -1167,7 +1226,8 @@ void handle_probe_req(struct hostapd_data *hapd,
 				hapd->cs_c_off_ecsa_proberesp;
 	}
 
-	ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack,
+	ret = hostapd_drv_send_mlme(hostapd_mbssid_get_tx_bss(hapd), resp,
+				    resp_len, noack,
 				    csa_offs_len ? csa_offs : NULL,
 				    csa_offs_len, 0);
 
@@ -1512,7 +1572,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 #ifdef NEED_AP_MLME
 	u16 capab_info;
 	u8 *pos, *tailpos, *tailend, *csa_pos;
+#endif /* NEED_AP_MLME */
+
+	os_memset(params, 0, sizeof(*params));
 
+#ifdef NEED_AP_MLME
 #define BEACON_HEAD_BUF_SIZE 256
 #define BEACON_TAIL_BUF_SIZE 512
 	head = os_zalloc(BEACON_HEAD_BUF_SIZE);
@@ -1649,9 +1713,16 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	tailpos = hostapd_eid_supported_op_classes(hapd, tailpos);
 	tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
 	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
-
 	tailpos = hostapd_eid_ext_capab(hapd, tailpos);
 
+	if (hapd->iconf->mbssid && hapd->iconf->num_bss > 1 &&
+	    ieee802_11_build_ap_params_mbssid(hapd, params)) {
+		os_free(head);
+		os_free(tail);
+		wpa_printf(MSG_ERROR, "Failed to set beacon data");
+		return -1;
+	}
+
 	/*
 	 * TODO: Time Advertisement element should only be included in some
 	 * DTIM Beacon frames.
@@ -1772,7 +1843,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 	resp = hostapd_probe_resp_offloads(hapd, &resp_len);
 #endif /* NEED_AP_MLME */
 
-	os_memset(params, 0, sizeof(*params));
 	params->head = (u8 *) head;
 	params->head_len = head_len;
 	params->tail = tail;
@@ -1875,6 +1945,10 @@ void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
 	params->head = NULL;
 	os_free(params->proberesp);
 	params->proberesp = NULL;
+	os_free(params->mbssid_elem);
+	params->mbssid_elem = NULL;
+	os_free(params->mbssid_elem_offset);
+	params->mbssid_elem_offset = NULL;
 #ifdef CONFIG_FILS
 	os_free(params->fd_frame_tmpl);
 	params->fd_frame_tmpl = NULL;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 39340864edc4..eb059c508fbc 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -91,6 +91,29 @@ int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
 }
 
 
+struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd)
+{
+	if (hapd->iconf->mbssid)
+		return hapd->iface->bss[0];
+
+	return hapd;
+}
+
+
+int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd)
+{
+	if (hapd->iconf->mbssid) {
+		size_t i;
+
+		for (i = 1; i < hapd->iface->num_bss; i++)
+			if (hapd->iface->bss[i] == hapd)
+				return i;
+	}
+
+	return 0;
+}
+
+
 void hostapd_reconfig_encryption(struct hostapd_data *hapd)
 {
 	if (hapd->wpa_auth)
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 36c6a8b21d08..a210a5f68da1 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -723,6 +723,8 @@ struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
 void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
 				      enum smps_mode smps_mode,
 				      enum chan_width chan_width, u8 rx_nss);
+struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd);
+int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd);
 
 #ifdef CONFIG_FST
 void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 39a2e6387d8a..d7511130ee18 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1618,6 +1618,42 @@ struct wpa_driver_ap_params {
 	 * Unsolicited broadcast Probe Response template length
 	 */
 	size_t unsol_bcast_probe_resp_tmpl_len;
+
+	/**
+	 * mbssid_tx_iface - Transmitting interface of the MBSSID set
+	 */
+	const char *mbssid_tx_iface;
+
+	/**
+	 * mbssid_index - The index of this BSS in the MBSSID set
+	 */
+	unsigned int mbssid_index;
+
+	/**
+	 * mbssid_elem - Buffer containing all MBSSID elements
+	 */
+	u8 *mbssid_elem;
+
+	/**
+	 * mbssid_elem_len - Total length of all MBSSID elements
+	 */
+	size_t mbssid_elem_len;
+
+	/**
+	 * mbssid_elem_count - The number of MBSSID elements
+	 */
+	u8 mbssid_elem_count;
+
+	/**
+	 * mbssid_elem_offset - Offsets to elements in mbssid_elem.
+	 * Kernel will use these offsets to generate multiple BSSID beacons.
+	 */
+	u8 **mbssid_elem_offset;
+
+	/**
+	 * ema - Enhanced MBSSID advertisements support.
+	 */
+	bool ema;
 };
 
 struct wpa_driver_mesh_bss_params {
-- 
2.31.1




More information about the Hostap mailing list