MLD: Also mark links as failed after association failure
Parse the link status values out of Multi-Link association response. If the AP rejects ML association and marks the links as failed with a reason code other than TX_LINK_NOT_ACCEPTED, also report these links to wpas_connection_failed() and ignore them. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
parent
c55a272f66
commit
5af986c75a
5 changed files with 336 additions and 28 deletions
|
@ -3642,6 +3642,262 @@ static void wpas_fst_update_mb_assoc(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int wpas_ml_parse_assoc(struct wpa_supplicant *wpa_s,
|
||||||
|
struct ieee802_11_elems *elems,
|
||||||
|
struct ml_sta_link_info *ml_info)
|
||||||
|
{
|
||||||
|
struct wpabuf *mlbuf;
|
||||||
|
struct ieee80211_eht_ml *ml;
|
||||||
|
size_t ml_len;
|
||||||
|
struct eht_ml_basic_common_info *common_info;
|
||||||
|
const u8 *pos;
|
||||||
|
u16 eml_capa = 0, mld_capa = 0;
|
||||||
|
const u16 control =
|
||||||
|
host_to_le16(MULTI_LINK_CONTROL_TYPE_BASIC |
|
||||||
|
BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
|
||||||
|
BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT);
|
||||||
|
u8 expected_common_info_len = 9;
|
||||||
|
unsigned int i = 0;
|
||||||
|
u16 ml_control;
|
||||||
|
|
||||||
|
if (!wpa_s->valid_links || !elems->basic_mle || !elems->basic_mle_len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mlbuf = ieee802_11_defrag(elems->basic_mle, elems->basic_mle_len, true);
|
||||||
|
if (!mlbuf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ml = (struct ieee80211_eht_ml *) wpabuf_head(mlbuf);
|
||||||
|
ml_len = wpabuf_len(mlbuf);
|
||||||
|
if (ml_len < sizeof(*ml))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
os_memset(ml_info, 0, sizeof(*ml_info) * MAX_NUM_MLD_LINKS);
|
||||||
|
|
||||||
|
ml_control = le_to_host16(ml->ml_control);
|
||||||
|
|
||||||
|
if ((ml_control & control) != control) {
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: Invalid presence BM=0x%x",
|
||||||
|
ml_control);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) {
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: EML capabilities included");
|
||||||
|
expected_common_info_len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) {
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: MLD capabilities included");
|
||||||
|
expected_common_info_len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Unexpected: medium sync delay info present");
|
||||||
|
expected_common_info_len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Unexpected: MLD ID present");
|
||||||
|
expected_common_info_len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof(*ml) + expected_common_info_len > ml_len) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Not enough bytes for common info. ml_len=%zu",
|
||||||
|
ml_len);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
common_info = (struct eht_ml_basic_common_info *) ml->variable;
|
||||||
|
if (common_info->len != expected_common_info_len) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Invalid common info len=%u. expected=%u",
|
||||||
|
common_info->len, expected_common_info_len);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: address: " MACSTR,
|
||||||
|
MAC2STR(common_info->mld_addr));
|
||||||
|
|
||||||
|
if (os_memcmp(wpa_s->ap_mld_addr, common_info->mld_addr, ETH_ALEN) !=
|
||||||
|
0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: Mismatching MLD address (expected "
|
||||||
|
MACSTR ")", MAC2STR(wpa_s->ap_mld_addr));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = common_info->variable;
|
||||||
|
|
||||||
|
/* Store the information for the association link */
|
||||||
|
ml_info[i].link_id = *pos;
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
/* Skip the BSS Parameters Change Count */
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
/* Skip the Medium Synchronization Delay Information if present */
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO)
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) {
|
||||||
|
eml_capa = WPA_GET_LE16(pos);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) {
|
||||||
|
mld_capa = WPA_GET_LE16(pos);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: link_id=%u, eml=0x%x, mld=0x%x",
|
||||||
|
ml_info[i].link_id, eml_capa, mld_capa);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
pos = ((u8 *) common_info) + common_info->len;
|
||||||
|
ml_len -= sizeof(*ml) + common_info->len;
|
||||||
|
while (ml_len > 2 && i < MAX_NUM_MLD_LINKS) {
|
||||||
|
u8 sub_elem_len = pos[1];
|
||||||
|
u8 sta_info_len;
|
||||||
|
u8 nstr_bitmap_len = 0;
|
||||||
|
u16 ctrl;
|
||||||
|
const u8 *end;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: Subelement len=%u", sub_elem_len);
|
||||||
|
|
||||||
|
if (sub_elem_len > ml_len - 2) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Invalid link info len: %u > %zu",
|
||||||
|
2 + sub_elem_len, ml_len);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*pos) {
|
||||||
|
case EHT_ML_SUB_ELEM_PER_STA_PROFILE:
|
||||||
|
break;
|
||||||
|
case EHT_ML_SUB_ELEM_FRAGMENT:
|
||||||
|
case EHT_ML_SUB_ELEM_VENDOR:
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Skip subelement id=%u, len=%u",
|
||||||
|
*pos, sub_elem_len);
|
||||||
|
pos += 2 + sub_elem_len;
|
||||||
|
ml_len -= 2 + sub_elem_len;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: Unknown subelement ID=%u",
|
||||||
|
*pos);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = pos + 2 + sub_elem_len;
|
||||||
|
|
||||||
|
/* Skip the subelement ID and the length */
|
||||||
|
pos += 2;
|
||||||
|
ml_len -= 2;
|
||||||
|
|
||||||
|
if (end - pos < 2)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Get the station control field */
|
||||||
|
ctrl = WPA_GET_LE16(pos);
|
||||||
|
|
||||||
|
pos += 2;
|
||||||
|
ml_len -= 2;
|
||||||
|
|
||||||
|
if (!(ctrl & EHT_PER_STA_CTRL_COMPLETE_PROFILE_MSK)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Per STA complete profile expected");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctrl & EHT_PER_STA_CTRL_MAC_ADDR_PRESENT_MSK)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Per STA MAC address not present");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctrl & EHT_PER_STA_CTRL_TSF_OFFSET_PRESENT_MSK)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Per STA TSF offset not present");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctrl & EHT_PER_STA_CTRL_BEACON_INTERVAL_PRESENT_MSK)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Beacon interval not present");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctrl & EHT_PER_STA_CTRL_DTIM_INFO_PRESENT_MSK)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: DTIM information not present");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl & EHT_PER_STA_CTRL_NSTR_LINK_PAIR_PRESENT_MSK) {
|
||||||
|
if (ctrl & EHT_PER_STA_CTRL_NSTR_BM_SIZE_MSK)
|
||||||
|
nstr_bitmap_len = 2;
|
||||||
|
else
|
||||||
|
nstr_bitmap_len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ctrl & EHT_PER_STA_CTRL_BSS_PARAM_CNT_PRESENT_MSK)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: BSS params change count not present");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sta_info_len = 1 + ETH_ALEN + 8 + 2 + 2 + 1 + nstr_bitmap_len;
|
||||||
|
if (sta_info_len > ml_len || sta_info_len > end - pos ||
|
||||||
|
sta_info_len + 2 > sub_elem_len ||
|
||||||
|
sta_info_len != *pos) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Invalid STA info len=%u, len=%u",
|
||||||
|
sta_info_len, *pos);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the link address */
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: link addr: " MACSTR " nstr BM len=%u",
|
||||||
|
MAC2STR(pos + 1), nstr_bitmap_len);
|
||||||
|
|
||||||
|
ml_info[i].link_id = ctrl & EHT_PER_STA_CTRL_LINK_ID_MSK;
|
||||||
|
os_memcpy(ml_info[i].bssid, pos + 1, ETH_ALEN);
|
||||||
|
|
||||||
|
pos += sta_info_len;
|
||||||
|
ml_len -= sta_info_len;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: sub_elem_len=%u, sta_info_len=%u",
|
||||||
|
sub_elem_len, sta_info_len);
|
||||||
|
|
||||||
|
sub_elem_len -= sta_info_len + 2;
|
||||||
|
if (sub_elem_len < 4) {
|
||||||
|
wpa_printf(MSG_DEBUG, "MLD: Per STA profile too short");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "MLD: STA profile", pos, sub_elem_len);
|
||||||
|
ml_info[i].status = WPA_GET_LE16(pos + 2);
|
||||||
|
|
||||||
|
pos += sub_elem_len;
|
||||||
|
ml_len -= sub_elem_len;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_free(mlbuf);
|
||||||
|
return i;
|
||||||
|
out:
|
||||||
|
wpabuf_free(mlbuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_drv_get_mlo_info(struct wpa_supplicant *wpa_s)
|
static int wpa_drv_get_mlo_info(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct driver_sta_mlo_info mlo;
|
struct driver_sta_mlo_info mlo;
|
||||||
|
@ -4236,7 +4492,7 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
|
||||||
if (is_zero_ether_addr(bssid))
|
if (is_zero_ether_addr(bssid))
|
||||||
bssid = wpa_s->pending_bssid;
|
bssid = wpa_s->pending_bssid;
|
||||||
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
|
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
|
||||||
wpas_connection_failed(wpa_s, bssid);
|
wpas_connection_failed(wpa_s, bssid, NULL);
|
||||||
wpa_sm_notify_disassoc(wpa_s->wpa);
|
wpa_sm_notify_disassoc(wpa_s->wpa);
|
||||||
ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE);
|
ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE);
|
||||||
|
|
||||||
|
@ -5251,6 +5507,8 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
const u8 *bssid = data->assoc_reject.bssid;
|
const u8 *bssid = data->assoc_reject.bssid;
|
||||||
|
struct ieee802_11_elems elems;
|
||||||
|
const u8 *link_bssids[MAX_NUM_MLD_LINKS];
|
||||||
#ifdef CONFIG_MBO
|
#ifdef CONFIG_MBO
|
||||||
struct wpa_bss *reject_bss;
|
struct wpa_bss *reject_bss;
|
||||||
#endif /* CONFIG_MBO */
|
#endif /* CONFIG_MBO */
|
||||||
|
@ -5305,7 +5563,7 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
if (!bss) {
|
if (!bss) {
|
||||||
bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
|
bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
|
||||||
if (!bss) {
|
if (!bss) {
|
||||||
wpas_connection_failed(wpa_s, bssid);
|
wpas_connection_failed(wpa_s, bssid, NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5340,7 +5598,7 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
if (!bss || wpa_s->dpp_pfs_fallback) {
|
if (!bss || wpa_s->dpp_pfs_fallback) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"DPP: Updated PFS policy for next try");
|
"DPP: Updated PFS policy for next try");
|
||||||
wpas_connection_failed(wpa_s, bssid);
|
wpas_connection_failed(wpa_s, bssid, NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5377,8 +5635,34 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_MBO */
|
#endif /* CONFIG_MBO */
|
||||||
|
|
||||||
|
/* Check for other failed links in the response */
|
||||||
|
os_memset(link_bssids, 0, sizeof(link_bssids));
|
||||||
|
if (ieee802_11_parse_elems(data->assoc_reject.resp_ies,
|
||||||
|
data->assoc_reject.resp_ies_len,
|
||||||
|
&elems, 1) != ParseFailed) {
|
||||||
|
struct ml_sta_link_info ml_info[MAX_NUM_MLD_LINKS];
|
||||||
|
unsigned int n_links, i, idx;
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
n_links = wpas_ml_parse_assoc(wpa_s, &elems, ml_info);
|
||||||
|
|
||||||
|
for (i = 1; i < n_links; i++) {
|
||||||
|
/* The status cannot be success here.
|
||||||
|
* Add the link to the failed list if it is reporting
|
||||||
|
* an error. The only valid "non-error" status is
|
||||||
|
* TX_LINK_NOT_ACCEPTED as that means this link may
|
||||||
|
* still accept an association from us.
|
||||||
|
*/
|
||||||
|
if (ml_info[i].status !=
|
||||||
|
WLAN_STATUS_DENIED_TX_LINK_NOT_ACCEPTED) {
|
||||||
|
link_bssids[idx] = ml_info[i].bssid;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
|
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
|
||||||
sme_event_assoc_reject(wpa_s, data);
|
sme_event_assoc_reject(wpa_s, data, link_bssids);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5415,7 +5699,7 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FILS */
|
#endif /* CONFIG_FILS */
|
||||||
|
|
||||||
wpas_connection_failed(wpa_s, bssid);
|
wpas_connection_failed(wpa_s, bssid, link_bssids);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1021,7 +1021,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
else
|
else
|
||||||
resp = sme_auth_build_sae_confirm(wpa_s, 0);
|
resp = sme_auth_build_sae_confirm(wpa_s, 0);
|
||||||
if (resp == NULL) {
|
if (resp == NULL) {
|
||||||
wpas_connection_failed(wpa_s, bss->bssid);
|
wpas_connection_failed(wpa_s, bss->bssid, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
params.auth_data = wpabuf_head(resp);
|
params.auth_data = wpabuf_head(resp);
|
||||||
|
@ -1157,7 +1157,7 @@ no_fils:
|
||||||
if (wpas_p2p_handle_frequency_conflicts(wpa_s,
|
if (wpas_p2p_handle_frequency_conflicts(wpa_s,
|
||||||
params.freq,
|
params.freq,
|
||||||
ssid) < 0) {
|
ssid) < 0) {
|
||||||
wpas_connection_failed(wpa_s, bss->bssid);
|
wpas_connection_failed(wpa_s, bss->bssid, NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
wpabuf_free(resp);
|
wpabuf_free(resp);
|
||||||
wpas_connect_work_done(wpa_s);
|
wpas_connect_work_done(wpa_s);
|
||||||
|
@ -1180,7 +1180,7 @@ no_fils:
|
||||||
if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) {
|
if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) {
|
||||||
wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
|
wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
|
||||||
"driver failed");
|
"driver failed");
|
||||||
wpas_connection_failed(wpa_s, bss->bssid);
|
wpas_connection_failed(wpa_s, bss->bssid, NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
wpabuf_free(resp);
|
wpabuf_free(resp);
|
||||||
wpas_connect_work_done(wpa_s);
|
wpas_connect_work_done(wpa_s);
|
||||||
|
@ -2002,7 +2002,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
|
||||||
data->auth.ies_len, 0, data->auth.peer,
|
data->auth.ies_len, 0, data->auth.peer,
|
||||||
&ie_offset);
|
&ie_offset);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid,
|
||||||
|
NULL);
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2046,7 +2047,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
|
||||||
WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
|
WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
|
||||||
wpa_s->sme.auth_alg == data->auth.auth_type ||
|
wpa_s->sme.auth_alg == data->auth.auth_type ||
|
||||||
wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
|
wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid,
|
||||||
|
NULL);
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2095,7 +2097,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
|
||||||
" reason=%d locally_generated=1",
|
" reason=%d locally_generated=1",
|
||||||
MAC2STR(wpa_s->pending_bssid),
|
MAC2STR(wpa_s->pending_bssid),
|
||||||
WLAN_REASON_DEAUTH_LEAVING);
|
WLAN_REASON_DEAUTH_LEAVING);
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid,
|
||||||
|
NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2119,7 +2122,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
|
||||||
" reason=%d locally_generated=1",
|
" reason=%d locally_generated=1",
|
||||||
MAC2STR(wpa_s->pending_bssid),
|
MAC2STR(wpa_s->pending_bssid),
|
||||||
WLAN_REASON_DEAUTH_LEAVING);
|
WLAN_REASON_DEAUTH_LEAVING);
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid,
|
||||||
|
NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2133,7 +2137,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
|
||||||
" reason=%d locally_generated=1",
|
" reason=%d locally_generated=1",
|
||||||
MAC2STR(wpa_s->pending_bssid),
|
MAC2STR(wpa_s->pending_bssid),
|
||||||
WLAN_REASON_DEAUTH_LEAVING);
|
WLAN_REASON_DEAUTH_LEAVING);
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid,
|
||||||
|
NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2591,7 +2596,7 @@ mscs_fail:
|
||||||
if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
|
if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
|
||||||
wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the "
|
wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the "
|
||||||
"driver failed");
|
"driver failed");
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid, NULL);
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
||||||
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
|
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
|
||||||
return;
|
return;
|
||||||
|
@ -2633,7 +2638,7 @@ int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sme_deauth(struct wpa_supplicant *wpa_s)
|
static void sme_deauth(struct wpa_supplicant *wpa_s, const u8 **link_bssids)
|
||||||
{
|
{
|
||||||
int bssid_changed;
|
int bssid_changed;
|
||||||
|
|
||||||
|
@ -2646,7 +2651,7 @@ static void sme_deauth(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
wpa_s->sme.prev_bssid_set = 0;
|
wpa_s->sme.prev_bssid_set = 0;
|
||||||
|
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid, link_bssids);
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
||||||
os_memset(wpa_s->bssid, 0, ETH_ALEN);
|
os_memset(wpa_s->bssid, 0, ETH_ALEN);
|
||||||
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
|
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
|
||||||
|
@ -2656,7 +2661,8 @@ static void sme_deauth(struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
|
|
||||||
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data,
|
||||||
|
const u8 **link_bssids)
|
||||||
{
|
{
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: "
|
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: "
|
||||||
"status code %d", MAC2STR(wpa_s->pending_bssid),
|
"status code %d", MAC2STR(wpa_s->pending_bssid),
|
||||||
|
@ -2720,7 +2726,7 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
* benefit from using the previous authentication, so this could be
|
* benefit from using the previous authentication, so this could be
|
||||||
* optimized in the future.
|
* optimized in the future.
|
||||||
*/
|
*/
|
||||||
sme_deauth(wpa_s);
|
sme_deauth(wpa_s, link_bssids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2728,7 +2734,7 @@ void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
|
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid, NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2737,7 +2743,7 @@ void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out");
|
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out");
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid, NULL);
|
||||||
wpa_supplicant_mark_disassoc(wpa_s);
|
wpa_supplicant_mark_disassoc(wpa_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2766,7 +2772,7 @@ static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
|
||||||
struct wpa_supplicant *wpa_s = eloop_ctx;
|
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||||
if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
|
if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
|
wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
|
||||||
sme_deauth(wpa_s);
|
sme_deauth(wpa_s, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2776,7 +2782,7 @@ static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
|
||||||
struct wpa_supplicant *wpa_s = eloop_ctx;
|
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||||
if (wpa_s->wpa_state == WPA_ASSOCIATING) {
|
if (wpa_s->wpa_state == WPA_ASSOCIATING) {
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
|
wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
|
||||||
sme_deauth(wpa_s);
|
sme_deauth(wpa_s, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data);
|
||||||
int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
|
int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
|
||||||
const u8 *ies, size_t ies_len);
|
const u8 *ies, size_t ies_len);
|
||||||
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data);
|
union wpa_event_data *data,
|
||||||
|
const u8 **link_bssids);
|
||||||
void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
|
void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data);
|
union wpa_event_data *data);
|
||||||
void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
|
void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
|
||||||
|
@ -63,7 +64,8 @@ static inline int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
|
||||||
|
|
||||||
|
|
||||||
static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data,
|
||||||
|
const u8 **link_bssids)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4420,7 +4420,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
|
||||||
* can stop right here; the association will not
|
* can stop right here; the association will not
|
||||||
* succeed.
|
* succeed.
|
||||||
*/
|
*/
|
||||||
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
|
wpas_connection_failed(wpa_s, wpa_s->pending_bssid,
|
||||||
|
NULL);
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
|
||||||
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
|
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
|
||||||
return;
|
return;
|
||||||
|
@ -8169,7 +8170,8 @@ static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
const u8 **link_bssids)
|
||||||
{
|
{
|
||||||
int timeout;
|
int timeout;
|
||||||
int count;
|
int count;
|
||||||
|
@ -8199,6 +8201,12 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Also mark links as failed */
|
||||||
|
while (link_bssids && *link_bssids) {
|
||||||
|
wpa_bssid_ignore_add(wpa_s, *link_bssids);
|
||||||
|
link_bssids++;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the failed BSSID into the ignore list and speed up next scan
|
* Add the failed BSSID into the ignore list and speed up next scan
|
||||||
* attempt if there could be other APs that could accept association.
|
* attempt if there could be other APs that could accept association.
|
||||||
|
|
|
@ -661,6 +661,13 @@ struct active_scs_elem {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ml_sta_link_info {
|
||||||
|
u8 link_id;
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
u16 status;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_supplicant - Internal data for wpa_supplicant interface
|
* struct wpa_supplicant - Internal data for wpa_supplicant interface
|
||||||
*
|
*
|
||||||
|
@ -723,7 +730,7 @@ struct wpa_supplicant {
|
||||||
u8 ap_mld_addr[ETH_ALEN];
|
u8 ap_mld_addr[ETH_ALEN];
|
||||||
u8 mlo_assoc_link_id;
|
u8 mlo_assoc_link_id;
|
||||||
u16 valid_links; /* bitmap of valid MLO link IDs */
|
u16 valid_links; /* bitmap of valid MLO link IDs */
|
||||||
struct ml_sta_link_info {
|
struct {
|
||||||
u8 addr[ETH_ALEN];
|
u8 addr[ETH_ALEN];
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
unsigned int freq;
|
unsigned int freq;
|
||||||
|
@ -1688,7 +1695,8 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *own_addr,
|
||||||
enum frame_encryption encrypted);
|
enum frame_encryption encrypted);
|
||||||
void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
|
void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
|
||||||
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
|
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
|
||||||
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
const u8 **link_bssids);
|
||||||
void fils_connection_failure(struct wpa_supplicant *wpa_s);
|
void fils_connection_failure(struct wpa_supplicant *wpa_s);
|
||||||
void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
|
void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
|
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
|
||||||
|
|
Loading…
Reference in a new issue