MLD: Support multiple RNR elements
Beacon frames are allowed to optionally include one more more Reduced Neighbor Report elements. Only the first one was parsed previously. Extend this to use a loop to go through all included RNR elements. Signed-off-by: Ben Greear <greearb@candelatech.com>
This commit is contained in:
parent
be212bdb55
commit
99a8dd0495
5 changed files with 64 additions and 8 deletions
|
@ -2495,6 +2495,35 @@ 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
|
||||
|
|
|
@ -261,6 +261,7 @@ 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);
|
||||
|
||||
|
|
|
@ -1220,6 +1220,22 @@ 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
|
||||
|
|
|
@ -169,6 +169,7 @@ 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,
|
||||
|
|
|
@ -454,6 +454,7 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
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;
|
||||
|
@ -519,14 +520,23 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
|
||||
wpa_s->valid_links = BIT(wpa_s->mlo_assoc_link_id);
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
|
||||
|
@ -538,7 +548,6 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
i, MAC2STR(wpa_s->links[i].bssid));
|
||||
}
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
wpabuf_free(mlbuf);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue