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: 78ac51f815 ("mac80211: support multi-bssid")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2022-06-29 13:29:05 +02:00
parent ab3a830d96
commit 38c6aa29d4
10 changed files with 38 additions and 50 deletions

View File

@@ -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;
}