]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MBSSID: Allow BSS Index and maximum number of BSSs to be configured
authorBaligh Gasmi <gasmibal@gmail.com>
Wed, 11 Dec 2024 20:37:38 +0000 (21:37 +0100)
committerJouni Malinen <j@w1.fi>
Fri, 27 Dec 2024 21:03:14 +0000 (23:03 +0200)
Configuring hostapd's BSSs with a custom BSSID via the `bssid` parameter
in the config file can lead to a misconfigured Multiple BSSID element
consequently leading to stations failing to calculate the correct BSSID
for non-transmitting BSSs, as specified in IEEE Std 802.11-2020,
9.4.2.45.

To ensure consistency, the configuration need to include critical
parameters: `MaxBSSID Indicator` and `Multiple BSSID Index` to customize
the Multiple BSSID element following the custom BSSIDs as well.

Add a new global parameter, `mbssid_max`, to set the `MaxBSSID
Indicator` and a per-BSS parameter, `mbssid_index`, to explicitly set
the `Multiple BSSID Index`. If these are not set, the previous behavior
of determining these values automatically is maintained (with its limits
to dynamic addition of BSSs to a Multiple BSSID set).

Signed-off-by: Baligh Gasmi <gasmibal@gmail.com>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/ieee802_11.c

index e59e98d7c0b3d0b5329a36ba519762027a5c20d9..0139d5bde4ef7d86846ccdeb8c8a4f39a837fcaa 100644 (file)
@@ -3964,6 +3964,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        return 1;
                }
                conf->mbssid = mbssid;
+       } else if (os_strcmp(buf, "mbssid_index") == 0) {
+               bss->mbssid_index = atoi(pos);
+       } else if (os_strcmp(buf, "mbssid_max") == 0) {
+               conf->mbssid_max = atoi(pos);
 #endif /* CONFIG_IEEE80211AX */
        } else if (os_strcmp(buf, "max_listen_interval") == 0) {
                bss->max_listen_interval = atoi(pos);
index b8d7d341223446580703c876764b479596288a6c..b1e8ac5bba4022b4989a3159a4f5208fe621e015 100644 (file)
@@ -3423,6 +3423,18 @@ own_ip_addr=127.0.0.1
 # 2 = Enhanced multiple BSSID advertisement enabled.
 #mbssid=0
 #
+# Maximum number of BSSs that can be added into a Multiple BSSID set
+# This is a radio level parameter. If not set (or 0), the maximum is determined
+# automatically based on the configured BSSs which may limit dynamic addition
+# of new BSSs.
+#mbssid_max=0
+#
+# Multiple BSSID Index override
+# This is a BSS level parameter. If not set (or 0), the BSSID index is
+# determined automatically based on the configured BSSs which may limit dynamic
+# addition of new BSSs.
+#mbssid_index=0
+#
 # The transmitting interface should be added with the 'interface' option while
 # the non-transmitting interfaces should be added using the 'bss' option.
 # Security configuration should be added separately per interface, if required.
index b0ae71e1edd2b46dd201ba396e24dda4693c2b3d..8ed07b68c899b269797c914c279a5278d43f12af 100644 (file)
@@ -995,6 +995,7 @@ struct hostapd_bss_config {
        bool mld_indicate_disabled;
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_IEEE80211BE */
+       int mbssid_index;
 };
 
 /**
@@ -1246,6 +1247,7 @@ struct hostapd_config {
                MBSSID_ENABLED = 1,
                ENHANCED_MBSSID_ENABLED = 2,
        } mbssid;
+       unsigned int mbssid_max;
 
        /* Whether to enable TWT responder in HT and VHT modes */
        bool ht_vht_twt_responder;
index 409f39916b91d04ea8f0f7af7170b64a49ee982f..a9ed6eb0fabce7a3c56a233cde79b381d823f591 100644 (file)
@@ -3414,7 +3414,10 @@ static u8 hostapd_max_bssid_indicator(struct hostapd_data *hapd)
        if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1)
                return 0;
 
-       num_bss_nontx = hapd->iface->num_bss - 1;
+       if (hapd->iface->conf->mbssid_max > 0)
+               num_bss_nontx = hapd->iface->conf->mbssid_max - 1;
+       else
+               num_bss_nontx = hapd->iface->conf->num_bss - 1;
        while (num_bss_nontx > 0) {
                max_bssid_ind++;
                num_bss_nontx >>= 1;
@@ -8345,11 +8348,13 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
        for (i = *bss_index; i < hapd->iface->num_bss; i++) {
                struct hostapd_data *bss = hapd->iface->bss[i];
                struct hostapd_bss_config *conf;
+               struct hostapd_bss_config *tx_conf = tx_bss->conf;
                u8 *eid_len_pos, *nontx_bss_start = eid;
                const u8 *auth, *rsn = NULL, *rsnx = NULL;
                u8 ie_count = 0, non_inherit_ie[3];
                size_t auth_len = 0;
                u16 capab_info;
+               u8 mbssindex = i;
 
                if (!bss || !bss->conf || !bss->started ||
                    mbssid_known_bss(i, known_bss, known_bss_len))
@@ -8370,10 +8375,14 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
                os_memcpy(eid, conf->ssid.ssid, conf->ssid.ssid_len);
                eid += conf->ssid.ssid_len;
 
+               if (conf->mbssid_index &&
+                   conf->mbssid_index > tx_conf->mbssid_index)
+                       mbssindex = conf->mbssid_index - tx_conf->mbssid_index;
+
                *eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX;
                if (frame_type == WLAN_FC_STYPE_BEACON) {
                        *eid++ = 3;
-                       *eid++ = i; /* BSSID Index */
+                       *eid++ = mbssindex; /* BSSID Index */
                        if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
                            (conf->dtim_period % elem_count))
                                conf->dtim_period = elem_count;
@@ -8389,7 +8398,7 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
                        /* Probe Request frame does not include DTIM Period and
                         * DTIM Count fields. */
                        *eid++ = 1;
-                       *eid++ = i; /* BSSID Index */
+                       *eid++ = mbssindex; /* BSSID Index */
                }
 
                auth = wpa_auth_get_wpa_ie(bss->wpa_auth, &auth_len);