One of my 80MHz 11ac APs transmits beacons on several channels,
while indicating its actual primary channel in the HT operation
information element (HT OP IE). We currently ignore the primary
channel given in the HT OP IE, and this leads to a problem.

(We do read the AP's idea of its primary channel from the DSSS
parameter IE, but this IE will only be sent on 2GHz channels so
it won't be present in 11ac mode.)

(The HT OP IE is used in both HT/11n and VHT/11ac modes; There is
an 11ac-specific VHT OP IE as well but this only elaborates on
information provided by the HT OP IE, and therefore lacks the
primary channel number.)

In my case, the HTOP primary channel is always 104, and as expected
we see a beacon on channel 104. But we also see beacons from this AP
on channels 118 and 140. Because higher channel numbers are scanned
later and we use the channel number of the most recently received
beacon, ni->ni_chan will be set to 140. As a result, the AP shows up
with channel 140 in the ifconfig scan list, which is wrong.

When the iwm(4) driver later asks firmware to use an 80MHz wide channel,
the firmware triggers a fatal firmware error and the interface fails to
associate with these messages:

  iwm0: fatal firmware error
  iwm0: could not update PHY context (error 35)
  iwm0: failed to update PHY

This happens because the 80MHz channel configuration calculated based
on the value 140 is nonsense. The VHT OP IE says we should be using center
channel 106, which the driver asks the firmware to use.
This center channel works with the actual primary channel 104. But it
makes no sense with the wrong primary channel number 140, and the
firmware detects this and complains.

We can fix this problem by ignoring beacons sent on secondary channels.
With the patch below, I now see:

$ netstat -W iwm0 | grep mismatched\ chan
        2 input packets with mismatched channel
$

And the interface associates successfully.

There is a related potential issue where an AP could try to deliberately
trigger this firmware error by sending a nonsense channel configuration.
The driver should be smarter and avoid sending a bogus PHY context command
to the device. But that can be fixed separately.

ok?

diff /usr/src
commit - 40e30772d6fb1f63ba9da196c5948e7546cd6cb9
path + /usr/src
blob - 220fe94908abfd078618b64a45e652cd6adf98f1
file + sys/net80211/ieee80211_input.c
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -1693,7 +1693,12 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, str
                        htcaps = frm;
                        break;
                case IEEE80211_ELEMID_HTOP:
+                       if (frm[1] < 22) {
+                               ic->ic_stats.is_rx_elem_toosmall++;
+                               break;
+                       }
                        htop = frm;
+                       chan = frm[2];
                        break;
                case IEEE80211_ELEMID_VHTCAPS:
                        vhtcaps = frm;

Reply via email to