Multi-AP: Parse the Multi-AP element using a shared helper function
This makes it more convenient to handle extensions to the element and allows code to be shared between hostapd and wpa_supplicant. Signed-off-by: Manoj Sekar <quic_sekar@quicinc.com>
This commit is contained in:
parent
0e2ca2e4e2
commit
364cb7c943
4 changed files with 68 additions and 30 deletions
|
@ -3416,37 +3416,26 @@ static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *multi_ap_ie, size_t multi_ap_len)
|
||||
{
|
||||
u8 multi_ap_value = 0;
|
||||
struct multi_ap_params multi_ap;
|
||||
u16 status;
|
||||
|
||||
sta->flags &= ~WLAN_STA_MULTI_AP;
|
||||
|
||||
if (!hapd->conf->multi_ap)
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
|
||||
if (multi_ap_ie) {
|
||||
const u8 *multi_ap_subelem;
|
||||
status = check_multi_ap_ie(multi_ap_ie + 4, multi_ap_len - 4,
|
||||
&multi_ap);
|
||||
if (status != WLAN_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
multi_ap_subelem = get_ie(multi_ap_ie + 4,
|
||||
multi_ap_len - 4,
|
||||
MULTI_AP_SUB_ELEM_TYPE);
|
||||
if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
|
||||
multi_ap_value = multi_ap_subelem[2];
|
||||
} else {
|
||||
hostapd_logger(hapd, sta->addr,
|
||||
HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO,
|
||||
"Multi-AP IE has missing or invalid Multi-AP subelement");
|
||||
return WLAN_STATUS_INVALID_IE;
|
||||
}
|
||||
}
|
||||
|
||||
if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
|
||||
if (multi_ap.capability && multi_ap.capability != MULTI_AP_BACKHAUL_STA)
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO,
|
||||
"Multi-AP IE with unexpected value 0x%02x",
|
||||
multi_ap_value);
|
||||
multi_ap.capability);
|
||||
|
||||
if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
|
||||
if (!(multi_ap.capability & MULTI_AP_BACKHAUL_STA)) {
|
||||
if (hapd->conf->multi_ap & FRONTHAUL_BSS)
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
|
||||
|
|
|
@ -2571,6 +2571,54 @@ size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
|
|||
}
|
||||
|
||||
|
||||
u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
|
||||
struct multi_ap_params *multi_ap)
|
||||
{
|
||||
const struct element *elem;
|
||||
bool ext_present = false;
|
||||
|
||||
os_memset(multi_ap, 0, sizeof(*multi_ap));
|
||||
|
||||
for_each_element(elem, multi_ap_ie, multi_ap_len) {
|
||||
u8 id = elem->id, elen = elem->datalen;
|
||||
const u8 *pos = elem->data;
|
||||
|
||||
switch (id) {
|
||||
case MULTI_AP_SUB_ELEM_TYPE:
|
||||
if (elen >= 1) {
|
||||
multi_ap->capability = *pos;
|
||||
ext_present = true;
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Multi-AP invalid Multi-AP subelement");
|
||||
return WLAN_STATUS_INVALID_IE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Ignore unknown subelement %u in Multi-AP IE",
|
||||
id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!for_each_element_completed(elem, multi_ap_ie, multi_ap_len)) {
|
||||
wpa_printf(MSG_DEBUG, "Multi AP IE parse failed @%d",
|
||||
(int) (multi_ap_ie + multi_ap_len -
|
||||
(const u8 *) elem));
|
||||
wpa_hexdump(MSG_MSGDUMP, "IEs", multi_ap_ie, multi_ap_len);
|
||||
}
|
||||
|
||||
if (!ext_present) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Multi-AP element without Multi-AP Extension subelement");
|
||||
return WLAN_STATUS_INVALID_IE;
|
||||
}
|
||||
|
||||
return WLAN_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
size_t add_multi_ap_ie(u8 *buf, size_t len,
|
||||
const struct multi_ap_params *multi_ap)
|
||||
{
|
||||
|
|
|
@ -271,6 +271,8 @@ const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
|
|||
|
||||
size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
|
||||
|
||||
u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len,
|
||||
struct multi_ap_params *multi_ap);
|
||||
size_t add_multi_ap_ie(u8 *buf, size_t len,
|
||||
const struct multi_ap_params *multi_ap);
|
||||
|
||||
|
|
|
@ -2996,25 +2996,24 @@ static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
|
|||
const u8 *ies, size_t ies_len)
|
||||
{
|
||||
struct ieee802_11_elems elems;
|
||||
const u8 *map_sub_elem, *pos;
|
||||
size_t len;
|
||||
struct multi_ap_params multi_ap;
|
||||
u16 status;
|
||||
|
||||
wpa_s->multi_ap_ie = 0;
|
||||
|
||||
if (!ies ||
|
||||
ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
|
||||
!elems.multi_ap || elems.multi_ap_len < 7)
|
||||
!elems.multi_ap)
|
||||
return;
|
||||
|
||||
pos = elems.multi_ap + 4;
|
||||
len = elems.multi_ap_len - 4;
|
||||
|
||||
map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
|
||||
if (!map_sub_elem || map_sub_elem[1] < 1)
|
||||
status = check_multi_ap_ie(elems.multi_ap + 4, elems.multi_ap_len - 4,
|
||||
&multi_ap);
|
||||
if (status != WLAN_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
wpa_s->multi_ap_backhaul = !!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS);
|
||||
wpa_s->multi_ap_fronthaul = !!(map_sub_elem[2] &
|
||||
wpa_s->multi_ap_backhaul = !!(multi_ap.capability &
|
||||
MULTI_AP_BACKHAUL_BSS);
|
||||
wpa_s->multi_ap_fronthaul = !!(multi_ap.capability &
|
||||
MULTI_AP_FRONTHAUL_BSS);
|
||||
wpa_s->multi_ap_ie = 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue