Sync the BSS channel restore parts around ieee80211_input() with iwm and iwn.

See:
https://marc.info/?l=openbsd-tech&m=153407168731621&w=2
https://marc.info/?l=openbsd-tech&m=157052714901054&w=2

ok?

Index: ic/bwfm.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/bwfm.c,v
retrieving revision 1.64
diff -u -p -u -r1.64 bwfm.c
--- ic/bwfm.c   27 Aug 2019 14:57:48 -0000      1.64
+++ ic/bwfm.c   8 Oct 2019 13:03:51 -0000
@@ -2369,6 +2369,7 @@ bwfm_scan_node(struct bwfm_softc *sc, st
        struct ieee80211_node *ni;
        struct ieee80211_rxinfo rxi;
        struct ieee80211_channel *bss_chan;
+       uint8_t saved_bssid[IEEE80211_ADDR_LEN] = { 0 };
        struct mbuf *m;
        uint32_t pktlen, ieslen;
        uint16_t iesoff;
@@ -2403,13 +2404,16 @@ bwfm_scan_node(struct bwfm_softc *sc, st
        /* Finalize mbuf. */
        m->m_pkthdr.len = m->m_len = pktlen;
        ni = ieee80211_find_rxnode(ic, wh);
-       /*
-        * We may switch ic_bss's channel during scans.
-        * Record the current channel so we can restore it later.
-        */
-       bss_chan = NULL;
-       if (ni == ic->ic_bss)
+
+       /* Fix current channel. */
+       if (ni == ic->ic_bss) {
+               /*
+                * We may switch ic_bss's channel during scans.
+                * Record the current channel so we can restore it later.
+                */
                bss_chan = ni->ni_chan;
+               IEEE80211_ADDR_COPY(&saved_bssid, ni->ni_macaddr);
+       }
        /* Channel mask equals IEEE80211_CHAN_MAX */
        chanidx = bwfm_spec2chan(sc, letoh32(bss->chanspec));
        ni->ni_chan = &ic->ic_channels[chanidx];
@@ -2418,9 +2422,14 @@ bwfm_scan_node(struct bwfm_softc *sc, st
        rxi.rxi_rssi = (int16_t)letoh16(bss->rssi);
        rxi.rxi_tstamp = 0;
        ieee80211_input(ifp, m, ni, &rxi);
-       /* Restore channel */
-       if (bss_chan)
+
+       /*
+        * ieee80211_input() might have changed our BSS.
+        * Restore ic_bss's channel if we are still in the same BSS.
+        */
+       if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
                ni->ni_chan = bss_chan;
+
        /* Node is no longer needed. */
        ieee80211_release_node(ic, ni);
 }

Reply via email to