diff mbox series

[v2,03/11] mbssid: configure all BSSes before beacon setup

Message ID 20220511204931.25069-4-quic_alokad@quicinc.com
State Superseded
Headers show
Series hostapd: MBSSID and EMA support | expand

Commit Message

Aloka Dixit May 11, 2022, 8:49 p.m. UTC
When multiple BSSID advertisements feature is enabled in 802.11ax
mode or later, beacons are not transmitted per interface, instead
only one of the interfaces transmits beacon(s) which include one
or more multiple BSSID elements with configuration for the remaining
interfaces on the same radio.

Change the existing logic such that all configuration details for
all the interfaces is available while building the beacon for the
transmitting interface itself.

Do not change the flow for the cases where multiple BSSID advertisements
are not enabled.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
---
v2: Kept only beacon start related code in the new function.

 src/ap/hostapd.c | 49 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index f6fe8a8a03b5..39340864edc4 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1103,19 +1103,37 @@  static int db_table_create_radius_attributes(sqlite3 *db)
 
 #endif /* CONFIG_NO_RADIUS */
 
+static int hostapd_start_beacon(struct hostapd_data *hapd)
+{
+	struct hostapd_bss_config *conf = hapd->conf;
+
+	if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
+		return -1;
+
+	if (hapd->driver && hapd->driver->set_operstate)
+		hapd->driver->set_operstate(hapd->drv_priv, 1);
+
+	return 0;
+}
 
 /**
  * hostapd_setup_bss - Per-BSS setup (initialization)
  * @hapd: Pointer to BSS data
  * @first: Whether this BSS is the first BSS of an interface; -1 = not first,
  *	but interface may exist
+ * @start_beacon: Whether beacons should be configured and transmission started
+ *	at this time. This is used when MBSSID IE is enabled where the
+ *	information regarding all BSSes should be retrieved before configuring
+ *	the beacons. The calling functions are responsible to configure the
+ *	beacon explicitly if this is set to 'false'.
  *
  * This function is used to initialize all per-BSS data structures and
  * resources. This gets called in a loop for each BSS when an interface is
  * initialized. Most of the modules that are initialized here will be
  * deinitialized in hostapd_cleanup().
  */
-static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
+static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
+			     bool start_beacon)
 {
 	struct hostapd_bss_config *conf = hapd->conf;
 	u8 ssid[SSID_MAX_LEN + 1];
@@ -1387,9 +1405,6 @@  static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
 		return -1;
 	}
 
-	if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
-		return -1;
-
 	if (flush_old_stations && !conf->start_disabled &&
 	    conf->broadcast_deauth) {
 		u8 addr[ETH_ALEN];
@@ -1408,8 +1423,8 @@  static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
 	if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
 		return -1;
 
-	if (hapd->driver && hapd->driver->set_operstate)
-		hapd->driver->set_operstate(hapd->drv_priv, 1);
+	if (start_beacon)
+		return hostapd_start_beacon(hapd);
 
 	return 0;
 }
@@ -2134,7 +2149,7 @@  static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
 		hapd = iface->bss[j];
 		if (j)
 			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
-		if (hostapd_setup_bss(hapd, j == 0)) {
+		if (hostapd_setup_bss(hapd, j == 0, !iface->conf->mbssid)) {
 			for (;;) {
 				hapd = iface->bss[j];
 				hostapd_bss_deinit_no_free(hapd);
@@ -2148,6 +2163,24 @@  static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
 		if (is_zero_ether_addr(hapd->conf->bssid))
 			prev_addr = hapd->own_addr;
 	}
+
+	if (hapd->iconf->mbssid) {
+		for (j = 0; j < iface->num_bss; j++) {
+			hapd = iface->bss[j];
+			if (hostapd_start_beacon(hapd)) {
+				for (;;) {
+					hapd = iface->bss[j];
+					hostapd_bss_deinit_no_free(hapd);
+					hostapd_free_hapd_data(hapd);
+					if (j == 0)
+						break;
+					j--;
+				}
+				goto fail;
+			}
+		}
+	}
+
 	hapd = iface->bss[0];
 
 	hostapd_tx_queue_params(iface);
@@ -3029,7 +3062,7 @@  int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
 
 			if (start_ctrl_iface_bss(hapd) < 0 ||
 			    (hapd_iface->state == HAPD_IFACE_ENABLED &&
-			     hostapd_setup_bss(hapd, -1))) {
+			     hostapd_setup_bss(hapd, -1, true))) {
 				hostapd_cleanup(hapd);
 				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
 				hapd_iface->conf->num_bss--;