From: Rameshkumar Sundaram Date: Mon, 5 May 2025 17:37:07 +0000 (-0700) Subject: MBSSID: Calculate length for MLE in Beacon and Probe Response frames X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c793224102c6c1098c6c76406d3cdafc8b6262ca;p=thirdparty%2Fhostap.git MBSSID: Calculate length for MLE in Beacon and Probe Response frames 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 Signed-off-by: Muna Sinada Signed-off-by: Aloka Dixit --- diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 0cca68c1c..e888d0b35 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -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; diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 2bcc29eb1..da97c25e3 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -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); diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index b61a94fa8..07b6727f3 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -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