mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-07 14:32:23 +00:00
wifi: mac80211: Process association status for affiliated links
In case the AP returned a non success status for one of the links, do not activate the link. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
45ebac4f05
commit
c2d052a3c4
@ -412,6 +412,8 @@ struct ieee80211_mgd_assoc_data {
|
|||||||
u8 *elems; /* pointing to inside ie[] below */
|
u8 *elems; /* pointing to inside ie[] below */
|
||||||
|
|
||||||
ieee80211_conn_flags_t conn_flags;
|
ieee80211_conn_flags_t conn_flags;
|
||||||
|
|
||||||
|
u16 status;
|
||||||
} link[IEEE80211_MLD_MAX_NUM_LINKS];
|
} link[IEEE80211_MLD_MAX_NUM_LINKS];
|
||||||
|
|
||||||
u8 ap_addr[ETH_ALEN] __aligned(2);
|
u8 ap_addr[ETH_ALEN] __aligned(2);
|
||||||
|
@ -2754,7 +2754,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|||||||
struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
|
struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
|
||||||
struct ieee80211_link_data *link;
|
struct ieee80211_link_data *link;
|
||||||
|
|
||||||
if (!cbss)
|
if (!cbss ||
|
||||||
|
assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
link = sdata_dereference(sdata->link[link_id], sdata);
|
link = sdata_dereference(sdata->link[link_id], sdata);
|
||||||
@ -2782,7 +2783,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|||||||
struct ieee80211_link_data *link;
|
struct ieee80211_link_data *link;
|
||||||
struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
|
struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
|
||||||
|
|
||||||
if (!cbss)
|
if (!cbss ||
|
||||||
|
assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
link = sdata_dereference(sdata->link[link_id], sdata);
|
link = sdata_dereference(sdata->link[link_id], sdata);
|
||||||
@ -3945,6 +3947,12 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
|||||||
|
|
||||||
if (link_id == assoc_data->assoc_link_id) {
|
if (link_id == assoc_data->assoc_link_id) {
|
||||||
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
|
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we should not get to this flow unless the association was
|
||||||
|
* successful, so set the status directly to success
|
||||||
|
*/
|
||||||
|
assoc_data->link[link_id].status = WLAN_STATUS_SUCCESS;
|
||||||
} else if (!elems->prof) {
|
} else if (!elems->prof) {
|
||||||
ret = false;
|
ret = false;
|
||||||
goto out;
|
goto out;
|
||||||
@ -3952,8 +3960,19 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
|||||||
const u8 *ptr = elems->prof->variable +
|
const u8 *ptr = elems->prof->variable +
|
||||||
elems->prof->sta_info_len - 1;
|
elems->prof->sta_info_len - 1;
|
||||||
|
|
||||||
/* FIXME: need to also handle the status code */
|
/*
|
||||||
|
* During parsing, we validated that these fields exist,
|
||||||
|
* otherwise elems->prof would have been set to NULL.
|
||||||
|
*/
|
||||||
capab_info = get_unaligned_le16(ptr);
|
capab_info = get_unaligned_le16(ptr);
|
||||||
|
assoc_data->link[link_id].status = get_unaligned_le16(ptr + 2);
|
||||||
|
|
||||||
|
if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
|
||||||
|
link_info(link, "association response status code=%u\n",
|
||||||
|
assoc_data->link[link_id].status);
|
||||||
|
ret = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_s1g && !elems->supp_rates) {
|
if (!is_s1g && !elems->supp_rates) {
|
||||||
@ -4874,6 +4893,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||||||
unsigned int link_id;
|
unsigned int link_id;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
u64 changed[IEEE80211_MLD_MAX_NUM_LINKS] = {};
|
u64 changed[IEEE80211_MLD_MAX_NUM_LINKS] = {};
|
||||||
|
u16 valid_links = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mutex_lock(&sdata->local->sta_mtx);
|
mutex_lock(&sdata->local->sta_mtx);
|
||||||
@ -4886,8 +4906,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
if (sdata->vif.valid_links) {
|
if (sdata->vif.valid_links) {
|
||||||
u16 valid_links = 0;
|
|
||||||
|
|
||||||
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
|
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
|
||||||
if (!assoc_data->link[link_id].bss)
|
if (!assoc_data->link[link_id].bss)
|
||||||
continue;
|
continue;
|
||||||
@ -4957,6 +4975,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||||||
&changed[link_id]))
|
&changed[link_id]))
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
|
if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
|
||||||
|
valid_links &= ~BIT(link_id);
|
||||||
|
ieee80211_sta_remove_link(sta, link_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (link_id != assoc_data->assoc_link_id) {
|
if (link_id != assoc_data->assoc_link_id) {
|
||||||
err = ieee80211_sta_activate_link(sta, link_id);
|
err = ieee80211_sta_activate_link(sta, link_id);
|
||||||
if (err)
|
if (err)
|
||||||
@ -4964,6 +4988,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* links might have changed due to rejected ones, set them again */
|
||||||
|
ieee80211_vif_set_links(sdata, valid_links);
|
||||||
|
|
||||||
rate_control_rate_init(sta);
|
rate_control_rate_init(sta);
|
||||||
|
|
||||||
if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
|
if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
|
||||||
@ -5197,10 +5224,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|||||||
link = sdata_dereference(sdata->link[link_id], sdata);
|
link = sdata_dereference(sdata->link[link_id], sdata);
|
||||||
if (!link)
|
if (!link)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!assoc_data->link[link_id].bss)
|
if (!assoc_data->link[link_id].bss)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
resp.links[link_id].bss = assoc_data->link[link_id].bss;
|
resp.links[link_id].bss = assoc_data->link[link_id].bss;
|
||||||
resp.links[link_id].addr = link->conf->addr;
|
resp.links[link_id].addr = link->conf->addr;
|
||||||
|
resp.links[link_id].status = assoc_data->link[link_id].status;
|
||||||
|
|
||||||
/* get uapsd queues configuration - same for all links */
|
/* get uapsd queues configuration - same for all links */
|
||||||
resp.uapsd_queues = 0;
|
resp.uapsd_queues = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user