]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Fix max number of simultaneous links in MLE during CAC
authorYuvarani V <quic_yuvarani@quicinc.com>
Mon, 23 Sep 2024 14:27:27 +0000 (19:57 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 4 Dec 2024 10:50:36 +0000 (12:50 +0200)
The Maximum Number Of Simultaneous Links field in MLD Capabilities And
Operations subfield in MLE is currently advertised as `num_links - 1`,
where `num_links` is the number of links added to the AP MLD. However,
when the 5 GHz band link is waiting for CAC timeout, this results in an
incorrect value being advertised for the maximum number of simultaneous
links in MLE, as the 5 GHz link is not active.

For example, an AP MLD with 3 links (2.4 GHz, 5 GHz (waiting for CAC
timeout), and 6 GHz) during bringup has `num_links` set to 3.
Consequently, the maximum number of simultaneous links in MLE is
advertised as 2 according to the current code, despite the 5 GHz link
being in CAC timeout. The field should have been set to 1 to indicate
maximum of 2 links.

Fix this issue by determining the number of currently active links of
the AP MLD (instead of hapd->num_links which may include currently
inactive links) and use it to set the value for the maximum number of
simultaneous links in MLE.

Signed-off-by: Yuvarani V <quic_yuvarani@quicinc.com>
src/ap/hostapd.c
src/ap/hostapd.h
src/ap/ieee802_11_eht.c

index 1ce80d066885f2bb3c8441ffa4118725b8370b68..c6d3c315a417f5b39bfc4e260adcf7e723698d9e 100644 (file)
@@ -5061,6 +5061,28 @@ void hostapd_mld_interface_freed(struct hostapd_data *hapd)
                link_bss->drv_priv = NULL;
 }
 
+
+/* Return the number of currently active links, not counting the calling link
+ * (i.e., a value that is suitable to be used as-is in fields that use encoding
+ * of the value minus 1). */
+u8 hostapd_get_active_links(struct hostapd_data *hapd)
+{
+       struct hostapd_data *link_bss;
+       u8 active_links = 0;
+
+       if (!hapd || !hapd->conf->mld_ap)
+               return 0;
+
+       for_each_mld_link(link_bss, hapd) {
+               if (link_bss == hapd || !link_bss->started)
+                       continue;
+
+               active_links++;
+       }
+
+       return active_links;
+}
+
 #endif /* CONFIG_IEEE80211BE */
 
 
index 7e72863af75ed97efbbc5f3f4ce943139d473174..0862d5dfd9330331394d7641809f83cd97399716 100644 (file)
@@ -857,6 +857,7 @@ bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
 u8 hostapd_get_mld_id(struct hostapd_data *hapd);
 int hostapd_mld_add_link(struct hostapd_data *hapd);
 int hostapd_mld_remove_link(struct hostapd_data *hapd);
+u8 hostapd_get_active_links(struct hostapd_data *hapd);
 struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd);
 
 void free_beacon_data(struct beacon_data *beacon);
index 89f8ffde94ae20c7909bbca275b5be4b081f9615..47526a836379cd57bebfa8e6e335796319982767 100644 (file)
@@ -503,7 +503,7 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
 
        mld_cap = hapd->iface->mld_mld_capa;
        max_simul_links = mld_cap & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
-       active_links = hapd->mld->num_links - 1;
+       active_links = hostapd_get_active_links(hapd);
 
        if (active_links > max_simul_links) {
                wpa_printf(MSG_ERROR,