diff options
author | Johannes Berg <johannes.berg@intel.com> | 2022-06-29 13:29:05 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2022-07-15 11:43:17 +0200 |
commit | 38c6aa29d4558c55a1d2b4010cc588716e212f89 (patch) | |
tree | 7f8997e0e72baafdeeede9f4c369643ba3c33239 /net/mac80211/scan.c | |
parent | wifi: mac80211: move tdls_chan_switch_prohibited to link data (diff) | |
download | linux-38c6aa29d4558c55a1d2b4010cc588716e212f89.tar.xz linux-38c6aa29d4558c55a1d2b4010cc588716e212f89.zip |
wifi: mac80211: fix multi-BSSID element parsing
When parsing a frame containing a multi-BSSID element, we
need to know both the transmitted and non-transmitted BSSID
so we can parse it correctly.
Unfortunately, in quite a number of cases, we got this wrong
and were passing the wrong BSSID or useless information:
* the mgmt->bssid from a frame is only the transmitted
BSSID if the frame is a beacon
* passing just one of the parameters as non-NULL isn't
useful and ignored
In those case where we need to parse for a specific BSS we
always have a BSS structure pointer, representing the BSS
we need, whether transmitted or not. Thus, pass that pointer
to the parsing function instead of the two BSSIDs.
Also fix two bugs:
* we need to re-parse all the elements for the other BSS
when iterating the non-transmitted BSSes in scan
* we need to parse for the correct BSS when setting up
the channel data in client code
Fixes: 78ac51f81532 ("mac80211: support multi-bssid")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index f80284eee055..fa8ddf576bc1 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -209,8 +209,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, if (baselen > len) return NULL; - elems = ieee802_11_parse_elems(elements, len - baselen, false, - mgmt->bssid, cbss->bssid); + elems = ieee802_11_parse_elems(elements, len - baselen, false, cbss); if (!elems) return NULL; @@ -221,16 +220,21 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss = (void *)cbss->priv; ieee80211_update_bss_from_elems(local, bss, elems, rx_status, beacon); + kfree(elems); list_for_each_entry(non_tx_cbss, &cbss->nontrans_list, nontrans_list) { non_tx_bss = (void *)non_tx_cbss->priv; + elems = ieee802_11_parse_elems(elements, len - baselen, false, + non_tx_cbss); + if (!elems) + continue; + ieee80211_update_bss_from_elems(local, non_tx_bss, elems, rx_status, beacon); + kfree(elems); } - kfree(elems); - return bss; } |