From: Benjamin Berg <benjamin.berg@xxxxxxxxx> This commit is a preparation to better define valid_links in the bss structure and move parsing to wpa_bss_update. Before this, the value of valid_links would depend on whether a neighbor is known and if an SSID struct was passed to the parser. With this change, valid_links is purely defined on whether there is an entry in the RNR for the corresponding link. Signed-off-by: Benjamin Berg <benjamin.berg@xxxxxxxxx> --- tests/test-bss.c | 4 +-- wpa_supplicant/bss.c | 62 ++++++++++++++++++++--------------------- wpa_supplicant/bss.h | 4 +-- wpa_supplicant/events.c | 14 ++++------ wpa_supplicant/sme.c | 21 ++++++++++---- 5 files changed, 56 insertions(+), 49 deletions(-) diff --git a/tests/test-bss.c b/tests/test-bss.c index 0b82bd6e9d..10bcd17787 100644 --- a/tests/test-bss.c +++ b/tests/test-bss.c @@ -88,8 +88,8 @@ void test_parse_basic_ml(struct wpa_supplicant *wpa_s, u8 mld_id, &missing_links, NULL, &nontransmitted); - ASSERT_CMP_INT(ret, ==, 0); - ASSERT_CMP_INT(bss.bss.valid_links, ==, 1); + 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); } diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 711dc7db26..b8fe141935 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -1639,7 +1639,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 *missing, + size_t len, u16 *seen, u16 *usable, u16 *missing, struct wpa_ssid *ssid) { const u8 *pos, *end; @@ -1678,6 +1678,7 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s, "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, @@ -1690,6 +1691,15 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s, wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u", *mld_params, link_id); + bss->valid_links |= BIT(link_id); + l = &bss->mld_links[link_id]; + os_memcpy(l->bssid, pos + 1, ETH_ALEN); + l->disabled = mld_params[2] & + RNR_TBTT_INFO_MLD_PARAM2_LINK_DISABLED; + l->freq = ieee80211_chan_to_freq(NULL, + ap_info->op_class, + ap_info->channel); + if (!neigh_bss) { *missing |= BIT(link_id); } else if ((!ssid || @@ -1697,14 +1707,8 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s, ssid, 1, 0, true)) && !wpa_bssid_ignore_is_listed( wpa_s, neigh_bss->bssid)) { - struct mld_link *l; - - bss->valid_links |= BIT(link_id); - l = &bss->mld_links[link_id]; - os_memcpy(l->bssid, pos + 1, ETH_ALEN); l->freq = neigh_bss->freq; - l->disabled = mld_params[2] & - RNR_TBTT_INFO_MLD_PARAM2_LINK_DISABLED; + *usable |= BIT(link_id); } } } @@ -1797,7 +1801,7 @@ wpa_bss_validate_rsne_ml(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, * @ssid: Target SSID (or %NULL) * @nontransmitted: Out parameter denoting whether the BSSID is nontransmitted * (or %NULL) - * Returns: 0 on success or -1 for non-MLD or parsing failures + * 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 * information stored in the wpa_supplicant data to fill in information for @@ -1809,14 +1813,14 @@ 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. */ -int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, +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) { struct ieee802_11_elems elems; - struct wpabuf *mlbuf; + struct wpabuf *mlbuf = NULL; const struct element *elem; size_t ml_ie_len; const struct ieee80211_eht_ml *eht_ml; @@ -1833,23 +1837,22 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT | BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA; u16 missing = 0; - u16 seen; + u16 seen, usable = 0; const u8 *ies_pos = wpa_bss_ie_ptr(bss); size_t ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len; - int ret = -1, rsne_type, key_mgmt; + int rsne_type, key_mgmt; struct mld_link *l; - u16 valid_links; if (ieee802_11_parse_elems(ies_pos, ies_len, &elems, 1) == ParseFailed) { wpa_dbg(wpa_s, MSG_DEBUG, "MLD: Failed to parse elements"); - return ret; + goto out; } mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true); if (!mlbuf) { wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No Multi-Link element"); - return ret; + goto out; } ml_ie_len = wpabuf_len(mlbuf); @@ -1920,7 +1923,8 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, link_id = ml_basic_common_info->variable[0] & EHT_ML_LINK_ID_MSK; bss->mld_link_id = link_id; - seen = bss->valid_links = BIT(link_id); + bss->valid_links = BIT(link_id); + usable = seen = bss->valid_links; l = &bss->mld_links[link_id]; os_memcpy(l->bssid, bss->bssid, ETH_ALEN); @@ -1995,18 +1999,15 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, wpa_bss_parse_ml_rnr_ap_info(wpa_s, bss, ap_mld_id, ap_info, ap_info_len, - &seen, &missing, ssid); + &seen, &usable, &missing, + ssid); ap_info_pos += ap_info_len; len -= ap_info_len; } } - wpa_printf(MSG_DEBUG, "MLD: valid_links=%04hx (unresolved: 0x%04hx)", - bss->valid_links, missing); - - valid_links = bss->valid_links; - for_each_link(bss->valid_links, i) { + for_each_link(usable, i) { struct wpa_bss *neigh_bss; int neigh_key_mgmt; @@ -2032,16 +2033,13 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, wpa_printf(MSG_DEBUG, "MLD: Discard link %u due to RSN parameter mismatch", i); - valid_links &= ~BIT(i); + usable &= ~BIT(i); continue; } } - if (valid_links != bss->valid_links) { - wpa_printf(MSG_DEBUG, "MLD: Updated valid links=%04hx", - valid_links); - bss->valid_links = valid_links; - } + wpa_printf(MSG_DEBUG, "MLD: valid_links=0x%04hx usable=0x%04hx (unresolved: 0x%04hx)", + bss->valid_links, usable, missing); for_each_link(bss->valid_links, i) { wpa_printf(MSG_DEBUG, "MLD: link=%u, bssid=" MACSTR, @@ -2051,11 +2049,13 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, if (missing_links) *missing_links = missing; + wpabuf_free(mlbuf); + return usable; - ret = 0; out: + bss->valid_links = 0; wpabuf_free(mlbuf); - return ret; + return 0; } diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index fd560a9a8d..f01accc50b 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -126,7 +126,7 @@ struct wpa_bss { /** Link ID of this affiliated AP of the AP MLD */ u8 mld_link_id; - /** An array of MLD links */ + /** An array of MLD links, any link found in the RNR is "valid" */ u16 valid_links; struct mld_link { u8 bssid[ETH_ALEN]; @@ -217,7 +217,7 @@ void calculate_update_time(const struct os_reltime *fetch_time, unsigned int age_ms, struct os_reltime *update_time); -int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, +u16 wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, u16 *missing_links, struct wpa_ssid *ssid, diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index fe9e358f5d..b8db56921d 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1176,9 +1176,7 @@ static bool wpas_valid_ml_bss(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) { u16 removed_links; - if (wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, NULL, NULL)) - return true; - + wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, NULL, NULL); if (!bss->valid_links) return true; @@ -1888,17 +1886,17 @@ static int wpa_supplicant_connect_ml_missing(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { int *freqs; - u16 missing_links = 0, removed_links; + 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; - if (wpa_bss_parse_basic_ml_element(wpa_s, selected, - &missing_links, ssid, - &nontransmitted) || - !missing_links) + usable_links = wpa_bss_parse_basic_ml_element(wpa_s, selected, + &missing_links, ssid, + &nontransmitted); + if (!usable_links || !missing_links) return 0; removed_links = wpa_bss_parse_reconf_ml_element(wpa_s, selected); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index d32d315766..50b3d635df 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -526,13 +526,24 @@ static int wpas_sme_ml_auth(struct wpa_supplicant *wpa_s, static void wpas_sme_set_mlo_links(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid) { + u16 usable_links; u8 i; + wpas_reset_mlo_info(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); + if (!usable_links) + return; + os_memcpy(wpa_s->ap_mld_addr, bss->mld_addr, ETH_ALEN); wpa_s->valid_links = 0; wpa_s->mlo_assoc_link_id = bss->mld_link_id; - for_each_link(bss->valid_links, i) { + for_each_link(usable_links, i) { const u8 *bssid = bss->mld_links[i].bssid; wpa_s->valid_links |= BIT(i); @@ -613,12 +624,10 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, os_memset(¶ms, 0, sizeof(params)); - if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) && - !wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, - ssid, NULL) && - bss->valid_links) { + wpas_sme_set_mlo_links(wpa_s, bss, ssid); + + if (wpa_s->valid_links) { wpa_printf(MSG_DEBUG, "MLD: In authentication"); - wpas_sme_set_mlo_links(wpa_s, bss, ssid); #ifdef CONFIG_TESTING_OPTIONS bss = wpas_ml_connect_pref(wpa_s, bss, ssid); -- 2.49.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap