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,
|
static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
const u8 *multi_ap_ie, size_t multi_ap_len)
|
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;
|
sta->flags &= ~WLAN_STA_MULTI_AP;
|
||||||
|
|
||||||
if (!hapd->conf->multi_ap)
|
if (!hapd->conf->multi_ap)
|
||||||
return WLAN_STATUS_SUCCESS;
|
return WLAN_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (multi_ap_ie) {
|
status = check_multi_ap_ie(multi_ap_ie + 4, multi_ap_len - 4,
|
||||||
const u8 *multi_ap_subelem;
|
&multi_ap);
|
||||||
|
if (status != WLAN_STATUS_SUCCESS)
|
||||||
|
return status;
|
||||||
|
|
||||||
multi_ap_subelem = get_ie(multi_ap_ie + 4,
|
if (multi_ap.capability && multi_ap.capability != MULTI_AP_BACKHAUL_STA)
|
||||||
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)
|
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||||
HOSTAPD_LEVEL_INFO,
|
HOSTAPD_LEVEL_INFO,
|
||||||
"Multi-AP IE with unexpected value 0x%02x",
|
"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)
|
if (hapd->conf->multi_ap & FRONTHAUL_BSS)
|
||||||
return WLAN_STATUS_SUCCESS;
|
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,
|
size_t add_multi_ap_ie(u8 *buf, size_t len,
|
||||||
const struct multi_ap_params *multi_ap)
|
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);
|
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,
|
size_t add_multi_ap_ie(u8 *buf, size_t len,
|
||||||
const struct multi_ap_params *multi_ap);
|
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)
|
const u8 *ies, size_t ies_len)
|
||||||
{
|
{
|
||||||
struct ieee802_11_elems elems;
|
struct ieee802_11_elems elems;
|
||||||
const u8 *map_sub_elem, *pos;
|
struct multi_ap_params multi_ap;
|
||||||
size_t len;
|
u16 status;
|
||||||
|
|
||||||
wpa_s->multi_ap_ie = 0;
|
wpa_s->multi_ap_ie = 0;
|
||||||
|
|
||||||
if (!ies ||
|
if (!ies ||
|
||||||
ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
|
ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed ||
|
||||||
!elems.multi_ap || elems.multi_ap_len < 7)
|
!elems.multi_ap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pos = elems.multi_ap + 4;
|
status = check_multi_ap_ie(elems.multi_ap + 4, elems.multi_ap_len - 4,
|
||||||
len = elems.multi_ap_len - 4;
|
&multi_ap);
|
||||||
|
if (status != WLAN_STATUS_SUCCESS)
|
||||||
map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
|
|
||||||
if (!map_sub_elem || map_sub_elem[1] < 1)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wpa_s->multi_ap_backhaul = !!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS);
|
wpa_s->multi_ap_backhaul = !!(multi_ap.capability &
|
||||||
wpa_s->multi_ap_fronthaul = !!(map_sub_elem[2] &
|
MULTI_AP_BACKHAUL_BSS);
|
||||||
|
wpa_s->multi_ap_fronthaul = !!(multi_ap.capability &
|
||||||
MULTI_AP_FRONTHAUL_BSS);
|
MULTI_AP_FRONTHAUL_BSS);
|
||||||
wpa_s->multi_ap_ie = 1;
|
wpa_s->multi_ap_ie = 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue