]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MBSSID: Calculate length for MLE in Beacon and Probe Response frames
authorRameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Mon, 5 May 2025 17:37:07 +0000 (10:37 -0700)
committerJouni Malinen <j@w1.fi>
Tue, 6 May 2025 12:59:47 +0000 (15:59 +0300)
While building the MLE for Beacon and Probe Response frames, length of
256 is allocated statically but for EMA length of MBSSID IE determines
the periodicity and hence considering a static length for the non
transmitting profile's MLE affects the whole EMA logic.

Fix this by calculating the exact length of the MLE that is to be added
for a BSS.

Signed-off-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Signed-off-by: Muna Sinada <muna.sinada@oss.qualcomm.com>
Signed-off-by: Aloka Dixit <aloka.dixit@oss.qualcomm.com>
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/ap/ieee802_11_eht.c

index 0cca68c1c7b1c77db53bf2965a8b086e06318cc0..e888d0b355142618b78b0dc85bd3d75563f9ab81 100644 (file)
@@ -8466,6 +8466,17 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
                        nontx_profile_len += xrate_len;
                else if (tx_xrate_len)
                        ie_count++;
+
+#ifdef CONFIG_IEEE80211BE
+               /* For ML Probe Response frame, the solicited hapd's MLE will
+                * be in the frame body */
+               if (bss->conf->mld_ap &&
+                   (bss != hapd || frame_type != WLAN_FC_STYPE_PROBE_RESP))
+                       nontx_profile_len += hostapd_eid_eht_basic_ml_len(bss,
+                                                                         NULL,
+                                                                         true);
+#endif /* CONFIG_IEEE80211BE */
+
                if (ie_count)
                        nontx_profile_len += 4 + ie_count + 1;
 
@@ -8633,6 +8644,14 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
                        non_inherit_ie[ie_count++] = WLAN_EID_EXT_SUPP_RATES;
                if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX))
                        non_inherit_ie[ie_count++] = WLAN_EID_RSNX;
+#ifdef CONFIG_IEEE80211BE
+               /* For ML Probe Response frame, the solicited hapd's MLE will
+                * be in the frame body */
+               if (bss->conf->mld_ap &&
+                   (bss != hapd || frame_type != WLAN_FC_STYPE_PROBE_RESP))
+                       eid = hostapd_eid_eht_basic_ml_common(bss, eid, NULL,
+                                                             true);
+#endif /* CONFIG_IEEE80211BE */
                if (ie_count) {
                        *eid++ = WLAN_EID_EXTENSION;
                        *eid++ = 2 + ie_count + 1;
index 2bcc29eb1a3ee8502f91949d6a4db78200bfa64c..da97c25e3f271ad26878380c7c10d99d785a9a2f 100644 (file)
@@ -94,6 +94,12 @@ u8 * hostapd_eid_eht_ml_beacon(struct hostapd_data *hapd,
                               u8 *eid, bool include_mld_id);
 u8 * hostapd_eid_eht_ml_assoc(struct hostapd_data *hapd, struct sta_info *info,
                              u8 *eid);
+u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
+                                    u8 *eid, struct mld_info *mld_info,
+                                    bool include_mld_id);
+size_t hostapd_eid_eht_basic_ml_len(struct hostapd_data *hapd,
+                                   struct sta_info *info,
+                                   bool include_mld_id);
 size_t hostapd_eid_eht_ml_beacon_len(struct hostapd_data *hapd,
                                     struct mld_info *info,
                                     bool include_mld_id);
index b61a94fa8a2fa9eab7ff1dea7c782c6180dde8ec..07b6727f3eba2be22131ec231dfb0224b1874181 100644 (file)
@@ -439,9 +439,15 @@ void hostapd_get_eht_capab(struct hostapd_data *hapd,
 }
 
 
-static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
-                                           u8 *eid, struct mld_info *mld_info,
-                                           bool include_mld_id)
+/* Beacon or a non ML Probe Response frame should include
+ * Common Info Length(1) + MLD MAC Address(6) +
+ * Link ID Info(1) + BSS Parameters Change count(1) +
+ * EML Capabilities (2) + MLD Capabilities (2)
+ */
+#define EHT_ML_COMMON_INFO_LEN 13
+u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
+                                    u8 *eid, struct mld_info *mld_info,
+                                    bool include_mld_id)
 {
        struct wpabuf *buf;
        u16 control;
@@ -475,7 +481,6 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
         * BSS Parameters Change Count (1) + EML Capabilities (2) +
         * MLD Capabilities and Operations (2)
         */
-#define EHT_ML_COMMON_INFO_LEN 13
        common_info_len = EHT_ML_COMMON_INFO_LEN;
 
        if (include_mld_id) {
@@ -667,6 +672,76 @@ out:
 }
 
 
+/*
+ * control (2) + station info length (1) + MAC address (6) +
+ * beacon interval (2) + TSF offset (8) + DTIM info (2) + BSS
+ * parameters change counter (1)
+ */
+#define EHT_ML_STA_INFO_LENGTH 22
+size_t hostapd_eid_eht_basic_ml_len(struct hostapd_data *hapd,
+                                   struct sta_info *info,
+                                   bool include_mld_id)
+{
+       int link_id;
+       size_t len, num_frags;
+
+       if (!hapd->conf->mld_ap)
+               return 0;
+
+       /* Include WLAN_EID_EXT_MULTI_LINK (1) */
+       len = 1;
+       /* control field */
+       len += 2;
+       /* Common info len for Basic MLE */
+       len += EHT_ML_COMMON_INFO_LEN;
+       if (include_mld_id)
+               len++;
+
+       if (!info)
+               goto out;
+
+       /* Add link info for the other links */
+       for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
+               struct mld_link_info *link = &info->mld_info.links[link_id];
+               struct hostapd_data *link_bss;
+               size_t sta_prof_len = EHT_ML_STA_INFO_LENGTH +
+                       link->resp_sta_profile_len;
+
+               /* Skip the local one */
+               if (link_id == hapd->mld_link_id || !link->valid)
+                       continue;
+
+               link_bss = hostapd_mld_get_link_bss(hapd, link_id);
+               if (!link_bss) {
+                       wpa_printf(MSG_ERROR,
+                                  "MLD: Couldn't find link BSS - skip it");
+                       continue;
+               }
+
+               /* Per-STA Profile Subelement(1), Length (1) */
+               len += 2;
+               len += sta_prof_len;
+               /* Consider Fragment EID(1) and Length (1) for each subelement
+                * fragment. */
+               if (sta_prof_len > 255) {
+                       num_frags = (sta_prof_len / 255 - 1) +
+                               !!(sta_prof_len % 255);
+                       len += num_frags * 2;
+               }
+
+       }
+
+out:
+       if (len > 255) {
+               num_frags = (len / 255 - 1) + !!(len % 255);
+               len += num_frags * 2;
+       }
+
+       /* WLAN_EID_EXTENSION (1) + length (1) */
+       return len + 2;
+}
+
+
 static u8 * hostapd_eid_eht_reconf_ml(struct hostapd_data *hapd, u8 *eid)
 {
 #ifdef CONFIG_TESTING_OPTIONS