[PATCH 4/9] BSS: Parse ML information when updating the BSS

Benjamin Berg benjamin at sipsolutions.net
Wed Jun 18 05:35:26 PDT 2025


From: Benjamin Berg <benjamin.berg at intel.com>

There is no point in re-parsing the ML element all the time if the
relevant information is being cached in the BSS anyway. As such, move
the parsing part to be done when adding/updating the BSS and add a
separate function to retrieve the links that are usable or missing in
the BSS cache.

Overall, this is not going to save work, but it means that the
multi-link information in the BSS is always up-to-date and also
detangles the RNR/ML parsing from the later runtime checks whether the
links are valid for the selected SSID.

Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
---
 tests/test-bss.c        |  10 +-
 wpa_supplicant/bss.c    | 282 +++++++++++++++++++---------------------
 wpa_supplicant/bss.h    |  13 +-
 wpa_supplicant/events.c |   9 +-
 wpa_supplicant/sme.c    |   3 +-
 5 files changed, 150 insertions(+), 167 deletions(-)

diff --git a/tests/test-bss.c b/tests/test-bss.c
index 10bcd17787..058cc1fad7 100644
--- a/tests/test-bss.c
+++ b/tests/test-bss.c
@@ -62,9 +62,8 @@ void test_parse_basic_ml(struct wpa_supplicant *wpa_s, u8 mld_id,
 		u8 ies[sizeof(rnr_ie) + sizeof(ml_ie_mld_id) +
 		       sizeof(mbssid_idx_ie)];
 	} bss;
-	u16 missing_links;
+	u16 missing_links = 0;
 	u8 ret;
-	bool nontransmitted;
 
 	memcpy(bss.bss.ies, rnr_ie, sizeof(rnr_ie));
 	bss.bss.ie_len = sizeof(rnr_ie);
@@ -84,14 +83,13 @@ void test_parse_basic_ml(struct wpa_supplicant *wpa_s, u8 mld_id,
 		bss.bss.ie_len += sizeof(mbssid_idx_ie);
 	}
 
-	ret = wpa_bss_parse_basic_ml_element(wpa_s, &bss.bss,
-					     &missing_links, NULL,
-					     &nontransmitted);
+	wpa_bss_parse_basic_ml_element(wpa_s, &bss.bss);
+	ret = wpa_bss_get_usable_links(wpa_s, &bss.bss, NULL, &missing_links);
 
 	ASSERT_CMP_INT(ret, ==, 1);
 	ASSERT_CMP_INT(bss.bss.valid_links, ==, 3);
 	ASSERT_CMP_INT(missing_links, ==, 0x0002);
-	ASSERT_CMP_INT(nontransmitted, ==, mbssid_idx > 0);
+	ASSERT_CMP_INT(bss.bss.mld_bss_non_transmitted, ==, mbssid_idx > 0);
 }
 
 #define RUN_TEST(func, ...) do {			\
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index b8fe141935..b5b6305f13 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -590,10 +590,8 @@ static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
 {
 	struct wpa_bss *bss;
 	char extra[100];
-	const u8 *ml_ie;
 	char *pos, *end;
 	int ret = 0;
-	const u8 *mld_addr;
 
 	bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len);
 	if (bss == NULL)
@@ -608,13 +606,7 @@ static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
 	os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len);
 	wpa_bss_set_hessid(bss);
 
-	os_memset(bss->mld_addr, 0, ETH_ALEN);
-	ml_ie = wpa_scan_get_ml_ie(res, MULTI_LINK_CONTROL_TYPE_BASIC);
-	if (ml_ie) {
-		mld_addr = get_basic_mle_mld_addr(&ml_ie[3], ml_ie[1] - 1);
-		if (mld_addr)
-			os_memcpy(bss->mld_addr, mld_addr, ETH_ALEN);
-	}
+	wpa_bss_parse_basic_ml_element(wpa_s, bss);
 
 	if (wpa_s->num_bss + 1 > wpa_s->conf->bss_max_count &&
 	    wpa_bss_remove_oldest(wpa_s) != 0) {
@@ -905,17 +897,9 @@ wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
 		dl_list_add(prev, &bss->list_id);
 	}
 	if (changes & WPA_BSS_IES_CHANGED_FLAG) {
-		const u8 *ml_ie, *mld_addr;
-
 		wpa_bss_set_hessid(bss);
-		os_memset(bss->mld_addr, 0, ETH_ALEN);
-		ml_ie = wpa_scan_get_ml_ie(res, MULTI_LINK_CONTROL_TYPE_BASIC);
-		if (ml_ie) {
-			mld_addr = get_basic_mle_mld_addr(&ml_ie[3],
-							  ml_ie[1] - 1);
-			if (mld_addr)
-				os_memcpy(bss->mld_addr, mld_addr, ETH_ALEN);
-		}
+
+		wpa_bss_parse_basic_ml_element(wpa_s, bss);
 	}
 	dl_list_add_tail(&wpa_s->bss, &bss->list);
 
@@ -1639,8 +1623,7 @@ static void
 wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
 			     struct wpa_bss *bss, u8 ap_mld_id,
 			     const struct ieee80211_neighbor_ap_info *ap_info,
-			     size_t len, u16 *seen, u16 *usable, u16 *missing,
-			     struct wpa_ssid *ssid)
+			     size_t len, u16 *seen)
 {
 	const u8 *pos, *end;
 	const u8 *mld_params;
@@ -1677,16 +1660,8 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
 			wpa_printf(MSG_DEBUG,
 				   "MLD: Reported link not part of MLD");
 		} else if (!(BIT(link_id) & *seen)) {
-			struct wpa_bss *neigh_bss;
 			struct mld_link *l;
 
-			if (ssid && ssid->ssid_len)
-				neigh_bss = wpa_bss_get(wpa_s, pos + 1,
-							ssid->ssid,
-							ssid->ssid_len);
-			else
-				neigh_bss = wpa_bss_get_bssid(wpa_s, pos + 1);
-
 			*seen |= BIT(link_id);
 			wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u",
 				   *mld_params, link_id);
@@ -1699,17 +1674,6 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
 			l->freq = ieee80211_chan_to_freq(NULL,
 							 ap_info->op_class,
 							 ap_info->channel);
-
-			if (!neigh_bss) {
-				*missing |= BIT(link_id);
-			} else if ((!ssid ||
-				    wpa_scan_res_match(wpa_s, 0, neigh_bss,
-						       ssid, 1, 0, true)) &&
-				   !wpa_bssid_ignore_is_listed(
-					   wpa_s, neigh_bss->bssid)) {
-				l->freq = neigh_bss->freq;
-				*usable |= BIT(link_id);
-			}
 		}
 	}
 }
@@ -1792,15 +1756,93 @@ wpa_bss_validate_rsne_ml(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 
 
 /**
- * wpa_bss_parse_basic_ml_element - Parse the Basic Multi-Link element
+ * wpa_bss_get_usable_links - Retrieve the usable links of the AP MLD
  * @wpa_s: Pointer to wpa_supplicant data
  * @bss: BSS table entry
- * @link_info: Array to store link information (or %NULL),
- *   should be initialized and #MAX_NUM_MLD_LINKS elements long
- * @missing_links: Result bitmask of links that were not discovered (or %NULL)
  * @ssid: Target SSID (or %NULL)
- * @nontransmitted: Out parameter denoting whether the BSSID is nontransmitted
- *    (or %NULL)
+ * @missing_links: Result bitmask of links that were not discovered (or %NULL)
+ * Returns: bitmap of links that are usable, or 0 for non-MLD or failure
+ *
+ * Validate each link of the MLD to verify that it is compatible and connection
+ * to each of the links is allowed.
+ */
+u16 wpa_bss_get_usable_links(struct wpa_supplicant *wpa_s,
+			     struct wpa_bss *bss,
+			     struct wpa_ssid *ssid,
+			     u16 *missing_links)
+{
+	int rsne_type, key_mgmt;
+	u16 usable_links = 0;
+	u8 link_id;
+
+	if (!bss->valid_links)
+		return 0;
+
+	rsne_type = -1;
+	if (ssid &&
+	    !wpa_bss_validate_rsne_ml(wpa_s, ssid, bss, &key_mgmt,
+				      &rsne_type)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
+		return 0;
+	}
+
+	usable_links = BIT(bss->mld_link_id);
+
+	for_each_link(bss->valid_links, link_id) {
+		struct wpa_bss *neigh_bss;
+
+		if (link_id == bss->mld_link_id)
+			continue;
+
+		if (ssid && ssid->ssid_len)
+			neigh_bss = wpa_bss_get(wpa_s,
+						bss->mld_links[link_id].bssid,
+						ssid->ssid,
+						ssid->ssid_len);
+		else
+			neigh_bss = wpa_bss_get_bssid(wpa_s,
+						      bss->mld_links[link_id].bssid);
+
+		if (!neigh_bss) {
+			if (missing_links)
+				*missing_links |= BIT(link_id);
+			continue;
+		}
+
+		if (ssid) {
+			int neigh_key_mgmt;
+
+			/* As per IEEE P802.11be/D7.0, 12.6.2 (RSNA selection), all APs
+			 * affiliated with an AP MLD shall advertise at least one common
+			 * AKM suite selector in the AKM Suite List field of an RSNE or
+			 * RSNXE. Discard links that do not have compatibility
+			 * configuration with the association link.
+			 */
+			if (!wpa_bss_validate_rsne_ml(wpa_s, ssid, neigh_bss,
+						      &neigh_key_mgmt, &rsne_type) ||
+			    !(key_mgmt & neigh_key_mgmt)) {
+				wpa_printf(MSG_DEBUG,
+					   "MLD: Discard link %u due to RSN parameter mismatch",
+					   link_id);
+				continue;
+			}
+		}
+
+		if ((!ssid ||
+		     wpa_scan_res_match(wpa_s, 0, neigh_bss, ssid, 1, 0, true)) &&
+		    !wpa_bssid_ignore_is_listed(wpa_s, neigh_bss->bssid)) {
+			usable_links |= BIT(link_id);
+		}
+	}
+
+	return usable_links;
+}
+
+
+/**
+ * wpa_bss_parse_basic_ml_element - Parse the Basic Multi-Link element
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bss: BSS table entry
  * Returns: Usable links bitmask, or 0 for non-MLD or parsing failures
  *
  * Parses the Basic Multi-Link element of the BSS into @link_info using the scan
@@ -1813,11 +1855,8 @@ wpa_bss_validate_rsne_ml(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
  * AP MLD ID should not be included in an ML Probe Request sent to its BSSID,
  * otherwise it should be included and set to zero.
  */
-u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
-				   struct wpa_bss *bss,
-				   u16 *missing_links,
-				   struct wpa_ssid *ssid,
-				   bool *nontransmitted)
+void wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
+				    struct wpa_bss *bss)
 {
 	struct ieee802_11_elems elems;
 	struct wpabuf *mlbuf = NULL;
@@ -1825,6 +1864,7 @@ u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
 	size_t ml_ie_len;
 	const struct ieee80211_eht_ml *eht_ml;
 	const struct eht_ml_basic_common_info *ml_basic_common_info;
+	const u8 *mbssid_idx_elem;
 	u8 i, pos, link_id, ap_mld_id;
 	const u16 control_mask =
 		MULTI_LINK_CONTROL_TYPE_MASK |
@@ -1836,11 +1876,9 @@ u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
 		BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
 		BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT |
 		BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA;
-	u16 missing = 0;
-	u16 seen, usable = 0;
+	u16 seen;
 	const u8 *ies_pos = wpa_bss_ie_ptr(bss);
 	size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
-	int rsne_type, key_mgmt;
 	struct mld_link *l;
 
 	if (ieee802_11_parse_elems(ies_pos, ies_len, &elems, 1) ==
@@ -1857,14 +1895,6 @@ u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
 
 	ml_ie_len = wpabuf_len(mlbuf);
 
-	rsne_type = -1;
-	if (ssid &&
-	    !wpa_bss_validate_rsne_ml(wpa_s, ssid, bss, &key_mgmt,
-				      &rsne_type)) {
-		wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
-		goto out;
-	}
-
 	/*
 	 * for ext ID + 2 control + common info len
 	 */
@@ -1922,59 +1952,51 @@ u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
 
 	link_id = ml_basic_common_info->variable[0] & EHT_ML_LINK_ID_MSK;
 
+	os_memcpy(bss->mld_addr, ml_basic_common_info->mld_addr, ETH_ALEN);
+
 	bss->mld_link_id = link_id;
 	bss->valid_links = BIT(link_id);
-	usable = seen = bss->valid_links;
+	seen = bss->valid_links;
 
 	l = &bss->mld_links[link_id];
 	os_memcpy(l->bssid, bss->bssid, ETH_ALEN);
 	l->freq = bss->freq;
 
+	bss->mld_bss_non_transmitted = false;
 
-	/* Read Multiple BSSID Index for *nontransmitted and AP MLD ID */
-	if (nontransmitted || !(le_to_host16(eht_ml->ml_control) &
-				BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID)) {
-		const u8 *mbssid_idx_elem;
-
-		/*
-		 * We should be able to rely on the Multiple BSSID Index element
-		 * to be included if the BSS is nontransmitted. Both if it was
-		 * extracted from a beacon and if it came from an ML probe
-		 * response (i.e. not listed in Draft P802.11be_D4.1, 35.3.3.4).
-		 *
-		 * Note that the AP MLD ID and the Multiple-BSSID Index will be
-		 * identical if the information was reported by the
-		 * corresponding transmitting AP (P802.11be_D4.1, 9.4.2.169.2).
-		 * As an AP MLD ID will not be explicitly provided we need to
-		 * rely on the Multiple-BSSID Index. This is generally the case
-		 * when the BSS information was read from a
-		 * Multiple-BSSID Element.
-		 *
-		 * The alternative scenario is a BSS discovered using a
-		 * Multi-Link Probe Response. In that case, we can still
-		 * determine whether the BSS is nontransmitted or not using the
-		 * Multiple BSSID Index Element. However, the AP MLD ID may be
-		 * different inside the ML Probe Response and the driver also
-		 * needs to deal with this during inheritance.
-		 *
-		 * We assume the driver either
-		 *  - includes the appropriate AP MLD ID in the ML Element
-		 *    it generates (see above), or
-		 *  - rewrites the RNR so that the AP MLD ID matches the
-		 *    Multiple-BSSID Index.
-		 */
-		mbssid_idx_elem = wpa_bss_get_ie(bss,
-						 WLAN_EID_MULTIPLE_BSSID_INDEX);
-		if (mbssid_idx_elem && mbssid_idx_elem[1] >= 1) {
-			if (!(le_to_host16(eht_ml->ml_control) &
-			    BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID))
-				ap_mld_id = mbssid_idx_elem[2];
-			if (nontransmitted)
-				*nontransmitted = !!mbssid_idx_elem[2];
-		} else {
-			if (nontransmitted)
-				*nontransmitted = false;
-		}
+	/*
+	 * We should be able to rely on the Multiple BSSID Index element
+	 * to be included if the BSS is nontransmitted. Both if it was
+	 * extracted from a beacon and if it came from an ML probe
+	 * response (i.e. not listed in Draft P802.11be_D4.1, 35.3.3.4).
+	 *
+	 * Note that the AP MLD ID and the Multiple-BSSID Index will be
+	 * identical if the information was reported by the
+	 * corresponding transmitting AP (P802.11be_D4.1, 9.4.2.169.2).
+	 * As an AP MLD ID will not be explicitly provided we need to
+	 * rely on the Multiple-BSSID Index. This is generally the case
+	 * when the BSS information was read from a
+	 * Multiple-BSSID Element.
+	 *
+	 * The alternative scenario is a BSS discovered using a
+	 * Multi-Link Probe Response. In that case, we can still
+	 * determine whether the BSS is nontransmitted or not using the
+	 * Multiple BSSID Index Element. However, the AP MLD ID may be
+	 * different inside the ML Probe Response and the driver also
+	 * needs to deal with this during inheritance.
+	 *
+	 * We assume the driver either
+	 *  - includes the appropriate AP MLD ID in the ML Element
+	 *    it generates (see above), or
+	 *  - rewrites the RNR so that the AP MLD ID matches the
+	 *    Multiple-BSSID Index.
+	 */
+	mbssid_idx_elem = wpa_bss_get_ie(bss, WLAN_EID_MULTIPLE_BSSID_INDEX);
+	if (mbssid_idx_elem && mbssid_idx_elem[1] >= 1) {
+		if (!(le_to_host16(eht_ml->ml_control) &
+		      BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID))
+			ap_mld_id = mbssid_idx_elem[2];
+		bss->mld_bss_non_transmitted = !!mbssid_idx_elem[2];
 	}
 
 	for_each_element_id(elem, WLAN_EID_REDUCED_NEIGHBOR_REPORT,
@@ -1998,64 +2020,28 @@ u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
 				goto out;
 
 			wpa_bss_parse_ml_rnr_ap_info(wpa_s, bss, ap_mld_id,
-						     ap_info, ap_info_len,
-						     &seen, &usable, &missing,
-						     ssid);
+						     ap_info, len, &seen);
 
 			ap_info_pos += ap_info_len;
 			len -= ap_info_len;
 		}
 	}
 
-	for_each_link(usable, i) {
-		struct wpa_bss *neigh_bss;
-		int neigh_key_mgmt;
-
-		if (!ssid)
-			break;
-
-		if (i == link_id)
-			continue;
-
-		neigh_bss = wpa_bss_get_bssid(wpa_s, bss->mld_links[i].bssid);
-		if (!neigh_bss) /* cannot be NULL at this point */
-			continue;
-
-		/* As per IEEE P802.11be/D7.0, 12.6.2 (RSNA selection), all APs
-		 * affiliated with an AP MLD shall advertise at least one common
-		 * AKM suite selector in the AKM Suite List field of an RSNE or
-		 * RSNXE. Discard links that do not have compatibility
-		 * configuration with the association link.
-		 */
-		if (!wpa_bss_validate_rsne_ml(wpa_s, ssid, neigh_bss,
-					      &neigh_key_mgmt, &rsne_type) ||
-		    !(key_mgmt & neigh_key_mgmt)) {
-			wpa_printf(MSG_DEBUG,
-				   "MLD: Discard link %u due to RSN parameter mismatch",
-				   i);
-			usable &= ~BIT(i);
-			continue;
-		}
-	}
-
-	wpa_printf(MSG_DEBUG, "MLD: valid_links=0x%04hx usable=0x%04hx (unresolved: 0x%04hx)",
-		   bss->valid_links, usable, missing);
+	wpa_printf(MSG_DEBUG, "MLD: valid_links=0x%04hx",
+		   bss->valid_links);
 
 	for_each_link(bss->valid_links, i) {
 		wpa_printf(MSG_DEBUG, "MLD: link=%u, bssid=" MACSTR,
 			   i, MAC2STR(bss->mld_links[i].bssid));
 	}
 
-	if (missing_links)
-		*missing_links = missing;
-
 	wpabuf_free(mlbuf);
-	return usable;
+	return;
 
 out:
+	os_memset(bss->mld_addr, 0, ETH_ALEN);
 	bss->valid_links = 0;
 	wpabuf_free(mlbuf);
-	return 0;
 }
 
 
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index f01accc50b..4bd752fda2 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -125,6 +125,8 @@ struct wpa_bss {
 	u8 mld_addr[ETH_ALEN];
 	/** Link ID of this affiliated AP of the AP MLD */
 	u8 mld_link_id;
+	/** For MLD, denotes if BSS is non-TX; useful for ML probe */
+	bool mld_bss_non_transmitted;
 
 	/** An array of MLD links, any link found in the RNR is "valid" */
 	u16 valid_links;
@@ -217,11 +219,12 @@ void calculate_update_time(const struct os_reltime *fetch_time,
 			   unsigned int age_ms,
 			   struct os_reltime *update_time);
 
-u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
-				   struct wpa_bss *bss,
-				   u16 *missing_links,
-				   struct wpa_ssid *ssid,
-				   bool *nontransmitted);
+u16 wpa_bss_get_usable_links(struct wpa_supplicant *wpa_s,
+			     struct wpa_bss *bss,
+			     struct wpa_ssid *ssid,
+			     u16 *missing_links);
+void wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
+				    struct wpa_bss *bss);
 u16 wpa_bss_parse_reconf_ml_element(struct wpa_supplicant *wpa_s,
 				    struct wpa_bss *bss);
 
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index b8db56921d..a411ea8f37 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1176,7 +1176,6 @@ static bool wpas_valid_ml_bss(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
 	u16 removed_links;
 
-	wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, NULL, NULL);
 	if (!bss->valid_links)
 		return true;
 
@@ -1887,15 +1886,13 @@ static int wpa_supplicant_connect_ml_missing(struct wpa_supplicant *wpa_s,
 {
 	int *freqs;
 	u16 missing_links = 0, removed_links, usable_links;
-	bool nontransmitted;
 
 	if (!((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) &&
 	      (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)))
 		return 0;
 
-	usable_links = wpa_bss_parse_basic_ml_element(wpa_s, selected,
-						      &missing_links, ssid,
-						      &nontransmitted);
+	usable_links = wpa_bss_get_usable_links(wpa_s, selected, NULL,
+						&missing_links);
 	if (!usable_links || !missing_links)
 		return 0;
 
@@ -1935,7 +1932,7 @@ static int wpa_supplicant_connect_ml_missing(struct wpa_supplicant *wpa_s,
 	 * In case the ML probe requested is intended to retrieve information
 	 * from a non-transmitted BSS, the AP MLD ID should not be included.
 	 */
-	if (nontransmitted)
+	if (selected->mld_bss_non_transmitted)
 		wpa_s->ml_probe_mld_id = -1;
 	else
 		wpa_s->ml_probe_mld_id = 0;
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 50b3d635df..55dcf41efc 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -534,8 +534,7 @@ static void wpas_sme_set_mlo_links(struct wpa_supplicant *wpa_s,
 	if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO))
 		return;
 
-	usable_links = wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL,
-						      ssid, NULL);
+	usable_links = wpa_bss_get_usable_links(wpa_s, bss, ssid, NULL);
 	if (!usable_links)
 		return;
 
-- 
2.49.0




More information about the Hostap mailing list