aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2022-06-26 19:04:16 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2022-06-26 19:04:16 +0000
commited3ef56b29fd194a5ac0b820fd09bf01a4922bb7 (patch)
tree33600d43303ec1698ea006b5879f2290183db136
parent9597f7cb99b03ecb457b160de621ce3a90bb3e5b (diff)
downloadsrc-ed3ef56b29fd194a5ac0b820fd09bf01a4922bb7.tar.gz
src-ed3ef56b29fd194a5ac0b820fd09bf01a4922bb7.zip
LinuxKPI: 802.11: sync sta->addr in lkpi_iv_update_bss()
In lkpi_iv_update_bss() introduced in d9f59799fc3e7 we swap lsta and along with that sta and drv state if ni gets reused and swapped under us by net80211. What we did not do was to sync sta->addr which later (usually in lkpi_sta_assoc_to_run) during a bss_info update cause problems in drivers (or firmware) as the BSSID and the station address were not aligned. If this proves to hold up to fix iwlwifi issues seem on firmware for older chipsets, multi-assoc runs, and rtw89 (which this fixes) we should add asserts that lkpi_iv_update_bss() can only happen in pre-auth stages and/or make sure we factor out synching more state fields. Found debugging: rtw89 MFC after: 3 days
-rw-r--r--sys/compat/linuxkpi/common/src/linux_80211.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 0328ff1c7c98..321fa47a4088 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -2073,8 +2073,8 @@ lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
struct lkpi_vif *lvif;
struct ieee80211_node *obss;
struct lkpi_sta *lsta;
+ struct ieee80211_sta *sta;
- lvif = VAP_TO_LVIF(vap);
obss = vap->iv_bss;
#ifdef LINUXKPI_DEBUG_80211
@@ -2101,13 +2101,20 @@ lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
lsta = obss->ni_drv_data;
obss->ni_drv_data = ni->ni_drv_data;
ni->ni_drv_data = lsta;
- if (lsta != NULL)
+ if (lsta != NULL) {
lsta->ni = ni;
+ sta = LSTA_TO_STA(lsta);
+ IEEE80211_ADDR_COPY(sta->addr, lsta->ni->ni_macaddr);
+ }
lsta = obss->ni_drv_data;
- if (lsta != NULL)
+ if (lsta != NULL) {
lsta->ni = obss;
+ sta = LSTA_TO_STA(lsta);
+ IEEE80211_ADDR_COPY(sta->addr, lsta->ni->ni_macaddr);
+ }
out:
+ lvif = VAP_TO_LVIF(vap);
return (lvif->iv_update_bss(vap, ni));
}