wlan-ap-Telecominfraproject/feeds/qca/hostapd/patches/r03-027-wpa_s-add-support-to-parse-multiple-RNRs.patch
John Crispin 008ca9618d
Some checks failed
Build OpenWrt/uCentral images / build (cig_wf186h) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf186w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf188n) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf189) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf196) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-a1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-b1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap102) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap104) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap105) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap111) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap112) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_3) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xe) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (indio_um-305ax) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sercomm_ap72tip) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630c-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-211g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-id2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-od2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr5018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018-v4) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax820) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax840) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap640) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap650) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap655) (push) Has been cancelled
Build OpenWrt/uCentral images / trigger-testing (push) Has been cancelled
Build OpenWrt/uCentral images / create-x64_vm-ami (push) Has been cancelled
ipq95xx: import ath12.4-cs kernel and drivers
Signed-off-by: John Crispin <john@phrozen.org>
2024-10-20 09:25:13 +02:00

329 lines
11 KiB
Diff

From 5156635a1fce3602c5092406e54c525e1f831e41 Mon Sep 17 00:00:00 2001
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Date: Thu, 2 Nov 2023 23:17:40 +0530
Subject: [PATCH] wpa_supplicant: add support to parse multiple RNRs and TBTTs
Currently while parsing RNR to fetch partner link information, only
first TBTT inside first RNR is checked, but an MBSSID beacon/probe
responses can have multiple RNR elements & multiple TBTTs in
single neighbor information.
Add support to parse through them and find partners.
Also mld id of partner is always assumed to be 0 but in mbssid beacon/
Probe response mld id in RNR will be the mbssid index for
NON-TX ML BSS'es.
Add support to fetch mbssid index for current bss and use it to
find partners.
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
---
src/common/ieee802_11_common.c | 23 +++++
src/common/ieee802_11_common.h | 1 +
wpa_supplicant/bss.c | 31 ++++++
wpa_supplicant/bss.h | 2 +
wpa_supplicant/sme.c | 184 ++++++++++++++++-----------------
5 files changed, 147 insertions(+), 94 deletions(-)
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -2487,6 +2487,31 @@ const u8 * get_ie(const u8 *ies, size_t
/**
+* get_ie_pos - Fetch a specified information element at given index from IEs buffer
+* @ies: Information elements buffer
+* @len: Information elements buffer length
+* @eid: Information element identifier (WLAN_EID_*)
+* @idx: index of entry of element to be found.
+*
+* Returns: Pointer to the information element (id field) at given @idx
+* or %NULL if not found.
+*/
+const u8 * get_ie_pos(const u8 *ies, size_t len, u8 eid, u8 idx)
+{
+ const struct element *elem;
+
+ if (!ies)
+ return NULL;
+
+ for_each_element(elem, ies, len) {
+ if (elem->id == eid && !idx--)
+ return &elem->id;
+ }
+ return NULL;
+}
+
+
+/**
* get_ie_ext - Fetch a specified extended information element from IEs buffer
* @ies: Information elements buffer
* @len: Information elements buffer length
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -260,6 +260,7 @@ extern const struct oper_class_map globa
extern size_t global_op_class_size;
const u8 * get_ie(const u8 *ies, size_t len, u8 eid);
+const u8 * get_ie_pos(const u8 *ies, size_t len, u8 eid, u8 idx);
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);
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -1208,6 +1208,40 @@ const u8 * wpa_bss_get_ie(const struct w
/**
+ * wpa_bss_get_ie_pos - Fetch a specified information element at given index
+ * from a BSS entry. This can be used to iterate over an element which is present
+ * multiple times in ie space
+ * @bss: BSS table entry
+ * @ie: Information element identitifier (WLAN_EID_*)
+ * @idx: index of entry of element to be found.
+ *
+ * This function returns the @idx'th matching information element in the BSS
+ * entry or NULL.
+ */
+const u8 * wpa_bss_get_ie_pos(const struct wpa_bss *bss, u8 ie, u8 idx)
+{
+ return get_ie_pos(wpa_bss_ie_ptr(bss), bss->ie_len, ie, idx);
+}
+
+/**
+ * wpa_bss_get_mbssid_idx - Fetch a mbssid idx of a BSS entry
+ * @bss: BSS table entry
+ *
+ * This function returns the mbssid idx of a BSS if MULTIPLE_BSSID_INDEX
+ * element is present in the BSS ie, 0 otherwise.
+ */
+u8 wpa_bss_get_mbssid_idx(const struct wpa_bss *bss)
+{
+ const u8 *mbssid_idx_ie = get_ie(wpa_bss_ie_ptr(bss), bss->ie_len,
+ WLAN_EID_MULTIPLE_BSSID_INDEX);
+ if (!mbssid_idx_ie)
+ return 0;
+ else
+ return mbssid_idx_ie[2];
+}
+
+
+/**
* wpa_bss_get_ie_ext - Fetch a specified extended IE from a BSS entry
* @bss: BSS table entry
* @ext: Information element extension identifier (WLAN_EID_EXT_*)
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -164,6 +164,8 @@ struct wpa_bss * wpa_bss_get_id(struct w
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_pos(const struct wpa_bss *bss, u8 ie, u8 idx);
+u8 wpa_bss_get_mbssid_idx(const struct wpa_bss *bss);
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,
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -388,7 +388,7 @@ static bool wpas_ml_element(struct wpa_s
u8 ml_ie_len, rnr_ie_len;
const struct ieee80211_eht_ml *eht_ml;
const struct eht_ml_basic_common_info *ml_basic_common_info;
- u8 i;
+ u8 i, mbssid_idx = 0;
const u16 control =
host_to_le16(MULTI_LINK_CONTROL_TYPE_BASIC |
BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
@@ -462,105 +462,102 @@ static bool wpas_ml_element(struct wpa_s
wpa_s->valid_links = BIT(wpa_s->mlo_assoc_link_id);
params->mld = true;
- rnr_ie = wpa_bss_get_ie(bss, WLAN_EID_REDUCED_NEIGHBOR_REPORT);
- if (!rnr_ie) {
- wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RNR element");
- ret = true;
- goto out;
- }
-
- rnr_ie_len = rnr_ie[1];
- pos = rnr_ie + 2;
-
- 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;
- const u8 *data = ap_info->data;
- size_t len = sizeof(struct ieee80211_neighbor_ap_info) +
- ap_info->tbtt_info_len;
-
- wpa_printf(MSG_DEBUG, "MLD: op_class=%u, channel=%u",
- ap_info->op_class, ap_info->channel);
+ i = 0;
+ mbssid_idx = wpa_bss_get_mbssid_idx(bss);
+ wpa_printf(MSG_DEBUG, "MLD: mbssid idx = %u for bss " MACSTR, mbssid_idx, MAC2STR(bss->bssid));
+ while ((rnr_ie = wpa_bss_get_ie_pos(bss, WLAN_EID_REDUCED_NEIGHBOR_REPORT, i++))) {
+ rnr_ie_len = rnr_ie[1];
+ pos = rnr_ie + 2;
+
+ 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;
+ const u8 *data = ap_info->data;
+ size_t rnr_info_len = sizeof(struct ieee80211_neighbor_ap_info);
+ u8 tbtt_count = ((ap_info->tbtt_info_hdr & 0xF0) >> 4) + 1;
+
+ wpa_printf(MSG_DEBUG, "MLD: op_class=%u, channel=%u tbtt_info_len %d tbtt_count %u",
+ ap_info->op_class, ap_info->channel, ap_info->tbtt_info_len, tbtt_count);
+ rnr_ie_len -= rnr_info_len;
+ pos += rnr_info_len;
+ if (ap_info->tbtt_info_len < 16) {
+ rnr_ie_len -= (tbtt_count * ap_info->tbtt_info_len);
+ pos += (tbtt_count * ap_info->tbtt_info_len);
+ continue;
+ }
+ while (tbtt_count--) {
+ const u8 *bssid = data + 1;
+ u16 mld_id = *(data + 13);
+ u8 link_id = *(data + 14) & 0xF;
- if (len > rnr_ie_len)
- break;
+ wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u",
+ mld_id, link_id);
- if (ap_info->tbtt_info_len < 16) {
- rnr_ie_len -= len;
- pos += len;
- continue;
- }
+ /* For NON-MBSSID BSS and MBSSID Tx BSS, idx will be 0 */
+ if (mbssid_idx != mld_id) {
+ wpa_printf(MSG_DEBUG,
+ "MLD: Reported link not part of current MLD");
+ } else {
+ struct wpa_bss *neigh_bss =
+ wpa_bss_get_bssid(wpa_s, bssid);
- data += 13;
+ wpa_printf(MSG_DEBUG, "Neighbor bssid : " MACSTR,
+ MAC2STR(bssid));
- wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u",
- *data, *(data + 1) & 0xF);
+ if (neigh_bss)
+ wpa_printf(MSG_DEBUG, "MLD: Neighbor founded in scan");
- if (*data) {
- wpa_printf(MSG_DEBUG,
- "MLD: Reported link not part of MLD");
- } else {
- struct wpa_bss *neigh_bss =
- wpa_bss_get_bssid(wpa_s, ap_info->data + 1);
-
- wpa_printf(MSG_DEBUG, "Neighbor bssid : " MACSTR,
- MAC2STR(ap_info->data + 1));
-
- if (neigh_bss)
- wpa_printf(MSG_DEBUG, "MLD: Neighbor founded in scan");
-
- if (!wpa_s->current_ssid)
- wpa_printf(MSG_DEBUG, "MLD: empty wpa_s->current_ssid");
-
- u8 link_id = *(data + 1) & 0xF;
- int partner_freq = ieee80211_chan_to_freq(NULL, ap_info->op_class, ap_info->chanel);
- int curr_freq = 0;
- if (partner_freq && wpa_s->conf->freq_list && wpa_s->conf->freq_list[0]) {
- int i = 0;
- curr_freq = wpa_s->conf->freq_list[i];
- while (curr_freq) {
- i++;
- wpa_printf(MSG_DEBUG, "ML Partner freq %d our scan list freq %d", partner_freq, curr_freq);
- if (curr_freq == partner_freq) {
- wpa_printf(MSG_DEBUG, "ML Partner freq %d is part of our scan list", partner_freq);
- break;
+ if (!wpa_s->current_ssid)
+ wpa_printf(MSG_DEBUG, "MLD: empty wpa_s->current_ssid");
+
+ int partner_freq = ieee80211_chan_to_freq(NULL, ap_info->op_class, ap_info->channel);
+ int curr_freq = 0;
+ if (partner_freq && wpa_s->conf->freq_list && wpa_s->conf->freq_list[0]) {
+ int i = 0;
+ curr_freq = wpa_s->conf->freq_list[i];
+ while (curr_freq) {
+ i++;
+ if (curr_freq == partner_freq) {
+ wpa_printf(MSG_DEBUG, "ML Partner freq %d is part of our scan list", partner_freq);
+ break;
+ }
+ curr_freq = wpa_s->conf->freq_list[i];
+ }
+ }
+ if (wpa_s->conf->freq_list && wpa_s->conf->freq_list[0] && !curr_freq) {
+ wpa_printf(MSG_DEBUG, "ML Partner freq %d is not part of our scan list ignore this link", partner_freq);
+ goto cont;
+ }
+ if (neigh_bss) {
+ wpa_scan_res_match(wpa_s, 0, neigh_bss,
+ wpa_s->current_ssid,
+ 1, 1);
+
+ if (true) {
+ 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;
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "MLD: Neighbor doesn't match current SSID - skip link");
+ }
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "MLD: Neighbor not found in scan, current neigh scan retry count %u", wpa_s->ml_neigh_retries);
+ if (wpa_s->ml_neigh_retries <= 5) {
+ ret = false;
+ goto out;
+ }
}
- curr_freq = wpa_s->conf->freq_list[i];
- }
- }
- if (wpa_s->conf->freq_list && wpa_s->conf->freq_list[0] && !curr_freq) {
- wpa_printf(MSG_DEBUG, "ML Partner freq %d is not part of our scan list ignore this link", partner_freq);
- goto cont;
- }
- if (neigh_bss) {
- wpa_scan_res_match(wpa_s, 0, neigh_bss,
- wpa_s->current_ssid,
- 1, 1);
-
- if (true) {
- wpa_s->valid_links |= BIT(link_id);
- os_memcpy(wpa_s->links[link_id].bssid,
- ap_info->data + 1, ETH_ALEN);
- wpa_s->links[link_id].freq =
- neigh_bss->freq;
- } else {
- wpa_printf(MSG_DEBUG,
- "MLD: Neighbor doesn't match current SSID - skip link");
- }
- } else {
- wpa_printf(MSG_DEBUG,
- "MLD: Neighbor not found in scan, current neigh scan retry count %u", wpa_s->ml_neigh_retries);
- if (pa_s->ml_neigh_retries <= 5) {
- ret = false;
- goto out;
}
- }
- }
cont:
- rnr_ie_len -= len;
- pos += len;
+ data += ap_info->tbtt_info_len;
+ }
+ rnr_ie_len -= (data - ap_info->data);
+ pos += (data - ap_info->data);
+ }
}
-
wpa_printf(MSG_DEBUG, "MLD: valid_links=0x%x", wpa_s->valid_links);
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {