[PATCH 06/42] wpa_supplicant: Remove duplicate logic in wpas_ml_element()
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Mon Nov 20 15:51:20 PST 2023
Parsing multiple RNR elements already exists in
wpa_bss_parse_basic_ml_element(), so wpas_ml_element() just duplicates
the same code.
Combine the functionality of both these functions and remove the
duplicate.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/common/ieee802_11_common.c | 29 ----
src/common/ieee802_11_common.h | 1 -
wpa_supplicant/bss.c | 62 ++++++---
wpa_supplicant/bss.h | 4 +-
wpa_supplicant/events.c | 5 +-
wpa_supplicant/sme.c | 246 ++++-----------------------------
6 files changed, 71 insertions(+), 276 deletions(-)
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 37a300ea48..06f82ce303 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -2495,35 +2495,6 @@ const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
}
-/**
- * get_ie_nth - Fetch a specified information element from IEs buffer
- * @ies: Information elements buffer
- * @len: Information elements buffer length
- * @eid: Information element identifier (WLAN_EID_*)
- * @nth: Return the nth element of the requested type (2 returns the second)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the nth matching information element in the IEs
- * buffer or %NULL in case the element is not found.
- */
-const u8 * get_ie_nth(const u8 *ies, size_t len, u8 eid, int nth)
-{
- const struct element *elem;
- int sofar = 0;
-
- if (!ies)
- return NULL;
-
- for_each_element_id(elem, eid, ies, len) {
- sofar++;
- if (sofar == nth)
- return &elem->id;
- }
-
- return NULL;
-}
-
-
/**
* get_ie_ext - Fetch a specified extended information element from IEs buffer
* @ies: Information elements buffer
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index a8a2118b1f..a7d407b65d 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -261,7 +261,6 @@ extern const struct oper_class_map global_op_class[];
extern size_t global_op_class_size;
const u8 * get_ie(const u8 *ies, size_t len, u8 eid);
-const u8 * get_ie_nth(const u8 *ies, size_t len, u8 eid, int nth);
const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext);
const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index b85a9ad177..e9164a09e7 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -18,6 +18,7 @@
#include "notify.h"
#include "scan.h"
#include "bss.h"
+#include "rsn_supp/wpa.h"
static void wpa_bss_set_hessid(struct wpa_bss *bss)
{
@@ -1221,22 +1222,6 @@ const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie)
}
-/**
- * wpa_bss_get_ie_nth - Fetch a specified information element from a BSS entry
- * @bss: BSS table entry
- * @ie: Information element identitifier (WLAN_EID_*)
- * @nth: Return the nth element of the requested type (2 returns the second)
- * Returns: Pointer to the information element (id field) or %NULL if not found
- *
- * This function returns the nth matching information element in the BSS
- * entry.
- */
-const u8 * wpa_bss_get_ie_nth(const struct wpa_bss *bss, u8 ie, int nth)
-{
- return get_ie_nth(wpa_bss_ie_ptr(bss), bss->ie_len, ie, nth);
-}
-
-
/**
* wpa_bss_get_ie_ext - Fetch a specified extended IE from a BSS entry
* @bss: BSS table entry
@@ -1500,7 +1485,8 @@ static void
wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, u8 mbssid_idx,
const struct ieee80211_neighbor_ap_info *ap_info,
- size_t len, u16 *seen, u16 *missing)
+ size_t len, u16 *seen, u16 *missing,
+ struct wpa_ssid *ssid)
{
const u8 *pos, *end;
const u8 *mld_params;
@@ -1524,12 +1510,15 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
pos += sizeof(*ap_info);
for (i = 0; i < count; i++) {
+ u8 bss_params;
+
if (bss->n_mld_links >= MAX_NUM_MLD_LINKS)
return;
if (end - pos < ap_info->tbtt_info_len)
break;
+ bss_params = pos[1 + ETH_ALEN + 4];
mld_params = pos + mld_params_offset;
link_id = *(mld_params + 1) & EHT_ML_LINK_ID_MSK;
@@ -1545,7 +1534,13 @@ 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);
- if (neigh_bss) {
+ if (!neigh_bss) {
+ *missing |= BIT(link_id);
+ } else if (!ssid ||
+ bss_params & RNR_BSS_PARAM_SAME_SSID ||
+ bss_params & RNR_BSS_PARAM_CO_LOCATED ||
+ wpa_scan_res_match(wpa_s, 0, neigh_bss,
+ ssid, 1, 0)) {
struct mld_link *l;
l = &bss->mld_links[bss->n_mld_links];
@@ -1554,8 +1549,6 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
ETH_ALEN);
l->freq = neigh_bss->freq;
bss->n_mld_links++;
- } else {
- *missing |= BIT(link_id);
}
}
@@ -1572,6 +1565,7 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
* @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)
* Returns: 0 on success or -1 for non-MLD or parsing failures
*
* Parses the Basic Multi-Link element of the BSS into @link_info using the scan
@@ -1582,7 +1576,8 @@ wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s,
int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss,
u8 *ap_mld_addr,
- u16 *missing_links)
+ u16 *missing_links,
+ struct wpa_ssid *ssid)
{
struct ieee802_11_elems elems;
struct wpabuf *mlbuf;
@@ -1623,6 +1618,29 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
ml_ie_len = wpabuf_len(mlbuf);
+ if (ssid) {
+ struct wpa_ie_data ie;
+
+ if (!elems.rsn_ie || wpa_parse_wpa_ie(elems.rsn_ie - 2, 2 + elems.rsn_ie_len, &ie)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
+ goto out;
+ }
+
+ if (!(ie.capabilities & WPA_CAPABILITY_MFPC) ||
+ wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "MLD: No management frame protection");
+ goto out;
+ }
+
+ ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
+ WPA_KEY_MGMT_PSK_SHA256);
+ if (!(ie.key_mgmt & ssid->key_mgmt)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
+ goto out;
+ }
+ }
+
/*
* for ext ID + 2 control + common info len + MLD address +
* link info
@@ -1702,7 +1720,7 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
wpa_bss_parse_ml_rnr_ap_info(wpa_s, bss, mbssid_idx,
ap_info, len, &seen,
- &missing);
+ &missing, ssid);
pos += ap_info_len;
len -= ap_info_len;
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index 7b0b24c616..bacf0a8e9c 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -171,7 +171,6 @@ struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id);
struct wpa_bss * wpa_bss_get_id_range(struct wpa_supplicant *wpa_s,
unsigned int idf, unsigned int idl);
const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie);
-const u8 * wpa_bss_get_ie_nth(const struct wpa_bss *bss, u8 ie, int nth);
const u8 * wpa_bss_get_ie_ext(const struct wpa_bss *bss, u8 ext);
const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type);
const u8 * wpa_bss_get_vendor_ie_beacon(const struct wpa_bss *bss,
@@ -216,7 +215,8 @@ void calculate_update_time(const struct os_reltime *fetch_time,
int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss,
u8 *ap_mld_addr,
- u16 *missing_links);
+ u16 *missing_links,
+ struct wpa_ssid *ssid);
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 1ee6eb82ed..a0c8eb1c53 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1135,7 +1135,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))
+ if (wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, NULL, NULL))
return true;
if (bss->n_mld_links == 0)
@@ -1860,7 +1860,8 @@ static int wpa_supplicant_connect_ml_missing(struct wpa_supplicant *wpa_s,
/* Try to resolve any missing link information */
if (wpa_bss_parse_basic_ml_element(wpa_s, selected, NULL,
- &missing_links) || !missing_links)
+ &missing_links, ssid) ||
+ !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 bbd8e1f205..95d1858800 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -378,225 +378,6 @@ static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
}
-static void wpas_process_tbtt_info(struct wpa_supplicant *wpa_s, const u8 *data)
-{
- struct wpa_bss *neigh_bss;
- const u8 *bssid;
- u8 bss_params;
- u8 link_id;
-
- /* TBTT Information field
- * Neighbor AP TBTT Offset[1]
- * BSSID[6]
- * Short SSID[4]
- * BSS parameters[1]
- * 20 MHz PSD[1]
- * MLD Parameters[3]
- * B0..B7: AP MLD ID
- * B7..B11: Link ID
- * B12..B19: BSS Parameters Change Count
- * B20: All Updates Included
- * B21: Disabled Link Indication */
-
- bssid = data + 1;
- bss_params = data[1 + ETH_ALEN + 4];
-
- data += 13; /* MLD Parameters */
- link_id = *(data + 1) & 0xF;
-
- wpa_dbg(wpa_s, MSG_DEBUG,
- "MLD: mld ID=%u, link ID=%u, bssid=" MACSTR ", bss_params=0x%x",
- *data, link_id, MAC2STR(bssid), bss_params);
-
- if (*data) {
- wpa_printf(MSG_DEBUG, "MLD: Reported link not part of MLD");
- return;
- }
-
- neigh_bss = wpa_bss_get_bssid(wpa_s, bssid);
- if (!neigh_bss) {
- wpa_printf(MSG_DEBUG, "MLD: Neighbor not found in scan");
- return;
- }
-
- if (!((bss_params & RNR_BSS_PARAM_SAME_SSID) &&
- (bss_params & RNR_BSS_PARAM_CO_LOCATED)) &&
- !wpa_scan_res_match(wpa_s, 0, neigh_bss, wpa_s->current_ssid,
- 1, 0)) {
- wpa_printf(MSG_DEBUG,
- "MLD: Neighbor doesn't match current SSID - skip link");
- return;
- }
-
- wpa_s->valid_links |= BIT(link_id);
- os_memcpy(wpa_s->links[link_id].bssid, bssid, ETH_ALEN);
- wpa_s->links[link_id].freq = neigh_bss->freq;
-}
-
-
-static void wpas_process_rnr(struct wpa_supplicant *wpa_s, const u8 *pos,
- size_t rnr_ie_len)
-{
- while (rnr_ie_len > sizeof(struct ieee80211_neighbor_ap_info)) {
- const struct ieee80211_neighbor_ap_info *ap_info =
- (const struct ieee80211_neighbor_ap_info *) pos;
- /* The first TBTT Information field */
- const u8 *data = ap_info->data;
- u8 tbtt_count;
- size_t len;
- int tbtt_i;
-
- if (rnr_ie_len < sizeof(struct ieee80211_neighbor_ap_info))
- break;
-
- tbtt_count = (ap_info->tbtt_info_hdr >> 4) + 1;
- len = sizeof(struct ieee80211_neighbor_ap_info) +
- ap_info->tbtt_info_len * tbtt_count;
-
- wpa_printf(MSG_DEBUG, "MLD: op_class=%u, channel=%u",
- ap_info->op_class, ap_info->channel);
-
- if (len > rnr_ie_len)
- break;
-
- if (ap_info->tbtt_info_len < 16) {
- rnr_ie_len -= len;
- pos += len;
- continue;
- }
-
- for (tbtt_i = 0; tbtt_i < tbtt_count; tbtt_i++) {
- wpas_process_tbtt_info(wpa_s, data);
- data += ap_info->tbtt_info_len;
- }
-
- rnr_ie_len -= len;
- pos += len;
- }
-}
-
-
-static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
- struct wpa_ssid *ssid)
-{
- struct wpabuf *mlbuf;
- const u8 *rnr_ie, *rsn_ie;
- struct wpa_ie_data ie;
- u8 ml_ie_len;
- const struct ieee80211_eht_ml *eht_ml;
- const struct eht_ml_basic_common_info *ml_basic_common_info;
- struct ieee802_11_elems elems;
- u8 i;
- const u16 control =
- host_to_le16(MULTI_LINK_CONTROL_TYPE_BASIC |
- BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
- BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT |
- BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA);
- bool ret = false;
- int rnr_idx;
-
- if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO))
- return false;
-
- if (ieee802_11_parse_elems(wpa_bss_ie_ptr(bss),
- bss->ie_len, &elems, 1) == ParseFailed)
- return false;
-
- mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true);
- if (!mlbuf) {
- wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No ML element");
- return false;
- }
-
- rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
- if (!rsn_ie || wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
- goto out;
- }
-
- if (!(ie.capabilities & WPA_CAPABILITY_MFPC) ||
- wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "MLD: No management frame protection");
- goto out;
- }
-
- ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
- WPA_KEY_MGMT_PSK_SHA256);
- if (!(ie.key_mgmt & ssid->key_mgmt)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
- goto out;
- }
-
- ml_ie_len = wpabuf_len(mlbuf);
-
- /* control + common info len + MLD address + MLD link information */
- if (ml_ie_len < 2 + 1 + ETH_ALEN + 1)
- goto out;
-
- eht_ml = wpabuf_head(mlbuf);
- if ((eht_ml->ml_control & control) != control) {
- wpa_printf(MSG_DEBUG, "MLD: Unexpected ML element control=0x%x",
- eht_ml->ml_control);
- goto out;
- }
-
- ml_basic_common_info =
- (const struct eht_ml_basic_common_info *) eht_ml->variable;
-
- /* common info length should be valid (self, mld_addr, link_id) */
- if (ml_basic_common_info->len < 1 + ETH_ALEN + 1)
- goto out;
-
- /* get the MLD address and MLD link ID */
- os_memcpy(wpa_s->ap_mld_addr, ml_basic_common_info->mld_addr,
- ETH_ALEN);
- wpa_s->mlo_assoc_link_id = ml_basic_common_info->variable[0] &
- EHT_ML_LINK_ID_MSK;
-
- os_memcpy(wpa_s->links[wpa_s->mlo_assoc_link_id].bssid, bss->bssid,
- ETH_ALEN);
- wpa_s->links[wpa_s->mlo_assoc_link_id].freq = bss->freq;
-
- wpa_printf(MSG_DEBUG, "MLD: address=" MACSTR ", link ID=%u",
- MAC2STR(wpa_s->ap_mld_addr), wpa_s->mlo_assoc_link_id);
-
- wpa_s->valid_links = BIT(wpa_s->mlo_assoc_link_id);
-
- ret = true;
-
- /* Process all Reduced Neighbor Report elements */
- for (rnr_idx = 1; ; rnr_idx++) {
- rnr_ie = wpa_bss_get_ie_nth(bss,
- WLAN_EID_REDUCED_NEIGHBOR_REPORT,
- rnr_idx);
- if (!rnr_ie) {
- if (rnr_idx == 0) {
- wpa_dbg(wpa_s, MSG_DEBUG,
- "MLD: No RNR element");
- goto out;
- }
- break;
- }
- wpas_process_rnr(wpa_s, rnr_ie + 2, rnr_ie[1]);
- }
-
- wpa_printf(MSG_DEBUG, "MLD: valid_links=0x%x", wpa_s->valid_links);
-
- for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
- if (!(wpa_s->valid_links & BIT(i)))
- continue;
-
- wpa_printf(MSG_DEBUG, "MLD: link=%u, bssid=" MACSTR,
- i, MAC2STR(wpa_s->links[i].bssid));
- }
-
-out:
- wpabuf_free(mlbuf);
- return ret;
-}
-
-
static void wpas_ml_handle_removed_links(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss)
{
@@ -740,6 +521,26 @@ out:
}
+static void wpas_sme_set_mlo_links(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+{
+ int i;
+
+ wpa_s->valid_links = 0;
+
+ for (i = 0; i < bss->n_mld_links; i++) {
+ u8 link_id = bss->mld_links[i].link_id;
+ u8 *bssid = bss->mld_links[i].bssid;
+
+ if (i == 0)
+ wpa_s->mlo_assoc_link_id = link_id;
+ wpa_s->valid_links |= BIT(link_id);
+ os_memcpy(wpa_s->links[link_id].bssid, bssid, ETH_ALEN);
+ wpa_s->links[link_id].freq = bss->mld_links[i].freq;
+ wpa_s->links[link_id].bss = wpa_bss_get_bssid(wpa_s, bssid);
+ }
+}
+
+
static void sme_send_authentication(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, struct wpa_ssid *ssid,
int start)
@@ -772,8 +573,13 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
}
os_memset(¶ms, 0, sizeof(params));
- if (wpas_ml_element(wpa_s, bss, ssid)) {
+
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO &&
+ !wpa_bss_parse_basic_ml_element(wpa_s, bss, wpa_s->ap_mld_addr,
+ NULL, ssid) && bss->n_mld_links) {
wpa_printf(MSG_DEBUG, "MLD: In authentication");
+ wpas_sme_set_mlo_links(wpa_s, bss);
+
#ifdef CONFIG_TESTING_OPTIONS
bss = wpas_ml_connect_pref(wpa_s, bss);
--
2.38.1
More information about the Hostap
mailing list