MSCS: Parse result of MSCS setup in (Re)Association Response frames

Add support to parse the (Re)Association Response frames to check if the
AP has accepted/declined the MSCS request in response to the
corresponding (Re)Association Request frame. AP indicates the result by
setting it in the optional MSCS Status subelement of MSCS Descriptor
element in (Re)Association Response frame.

This MSCS Status subelement is defined in the process of being added
into P802.11-REVmd/D4.0 (11-20-0516-17-000m-cr-mscs-and-cid4158).

Signed-off-by: Vinita S. Maloo <vmaloo@codeaurora.org>
This commit is contained in:
Vinita S. Maloo 2020-08-05 22:55:32 +05:30 committed by Jouni Malinen
parent c504ff5398
commit af8ab3208d
4 changed files with 44 additions and 5 deletions

View file

@ -2359,4 +2359,9 @@ enum scs_request_type {
SCS_REQ_CHANGE = 2, SCS_REQ_CHANGE = 2,
}; };
/* Optional subelement IDs for MSCS Descriptor element */
enum mscs_description_subelem {
MCSC_SUBELEM_STATUS = 1,
};
#endif /* IEEE802_11_DEFS_H */ #endif /* IEEE802_11_DEFS_H */

View file

@ -2678,11 +2678,11 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
{ {
int l, len, found = 0, found_x = 0, wpa_found, rsn_found; int l, len, found = 0, found_x = 0, wpa_found, rsn_found;
const u8 *p; const u8 *p;
#if defined(CONFIG_IEEE80211R) || defined(CONFIG_OWE)
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
#endif /* CONFIG_IEEE80211R || CONFIG_OWE */ bool bssid_known;
wpa_dbg(wpa_s, MSG_DEBUG, "Association info event"); wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
if (data->assoc_info.req_ies) if (data->assoc_info.req_ies)
wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies, wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
data->assoc_info.req_ies_len); data->assoc_info.req_ies_len);
@ -2799,7 +2799,7 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_OWE #ifdef CONFIG_OWE
if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE && if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE &&
(wpa_drv_get_bssid(wpa_s, bssid) < 0 || (!bssid_known ||
owe_process_assoc_resp(wpa_s->wpa, bssid, owe_process_assoc_resp(wpa_s->wpa, bssid,
data->assoc_info.resp_ies, data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len) < 0)) { data->assoc_info.resp_ies_len) < 0)) {
@ -2834,7 +2834,7 @@ no_pfs:
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
#ifdef CONFIG_SME #ifdef CONFIG_SME
if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) { if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
if (wpa_drv_get_bssid(wpa_s, bssid) < 0 || if (!bssid_known ||
wpa_ft_validate_reassoc_resp(wpa_s->wpa, wpa_ft_validate_reassoc_resp(wpa_s->wpa,
data->assoc_info.resp_ies, data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len, data->assoc_info.resp_ies_len,
@ -2894,7 +2894,7 @@ no_pfs:
/* Process FT when SME is in the driver */ /* Process FT when SME is in the driver */
if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
wpa_ft_is_completed(wpa_s->wpa)) { wpa_ft_is_completed(wpa_s->wpa)) {
if (wpa_drv_get_bssid(wpa_s, bssid) < 0 || if (!bssid_known ||
wpa_ft_validate_reassoc_resp(wpa_s->wpa, wpa_ft_validate_reassoc_resp(wpa_s->wpa,
data->assoc_info.resp_ies, data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len, data->assoc_info.resp_ies_len,
@ -2912,6 +2912,11 @@ no_pfs:
data->assoc_info.resp_ies_len); data->assoc_info.resp_ies_len);
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
if (bssid_known)
wpas_handle_assoc_resp_mscs(wpa_s, bssid,
data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len);
/* WPA/RSN IE from Beacon/ProbeResp */ /* WPA/RSN IE from Beacon/ProbeResp */
p = data->assoc_info.beacon_ies; p = data->assoc_info.beacon_ies;
l = data->assoc_info.beacon_ies_len; l = data->assoc_info.beacon_ies_len;

View file

@ -9,6 +9,7 @@
#include "utils/includes.h" #include "utils/includes.h"
#include "utils/common.h" #include "utils/common.h"
#include "common/wpa_ctrl.h" #include "common/wpa_ctrl.h"
#include "common/ieee802_11_common.h"
#include "wpa_supplicant_i.h" #include "wpa_supplicant_i.h"
#include "driver_i.h" #include "driver_i.h"
#include "bss.h" #include "bss.h"
@ -119,3 +120,29 @@ void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
" status_code=%u", MAC2STR(src), status_code); " status_code=%u", MAC2STR(src), status_code);
} }
void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
const u8 *ies, size_t ies_len)
{
const u8 *mscs_desc_ie, *mscs_status;
u16 status;
/* Process optional MSCS Status subelement when MSCS IE is in
* (Re)Association Response frame */
if (!ies || ies_len == 0 || !wpa_s->robust_av.valid_config)
return;
mscs_desc_ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_MSCS_DESCRIPTOR);
if (!mscs_desc_ie || mscs_desc_ie[1] < 1)
return;
mscs_status = get_ie(mscs_desc_ie, mscs_desc_ie[1],
MCSC_SUBELEM_STATUS);
if (!mscs_status || mscs_status[1] < 2)
return;
status = WPA_GET_LE16(mscs_status + 2);
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
" status_code=%u", MAC2STR(bssid), status);
}

View file

@ -1641,5 +1641,7 @@ void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s, void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
const u8 *src, const u8 *buf, const u8 *src, const u8 *buf,
size_t len); size_t len);
void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
const u8 *ies, size_t ies_len);
#endif /* WPA_SUPPLICANT_I_H */ #endif /* WPA_SUPPLICANT_I_H */