In monitor mode, make iwm(4) pass short control frames to bpf instead
of dropping them.

Checking frames against IEEE80211_MIN_LEN is wrong because that value
includes the CRC trailer, which the firmware does not include in the
reported byte count.

With this change these checks in iwm(4) match those in iwn(4).

Note: This diff applies on top of two other changes I've just committed.

ok?

diff c337e8955e3da971f2aaa6e351b64f7047f7d1ea 
3d4ee40dee795d04e3b24fd0fe4590e701ef86b4
blob - f10479776ea459653a6219785d7871b46f186fb3
blob + 9352658c1df0ee8959e699be11d6b8c9c037b0e9
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -3989,7 +3989,15 @@ iwm_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, void
        phy_info = &sc->sc_last_phy_info;
        rx_res = (struct iwm_rx_mpdu_res_start *)pktdata;
        len = le16toh(rx_res->byte_count);
-       if (len < IEEE80211_MIN_LEN) {
+       if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+               /* Allow control frames in monitor mode. */
+               if (len < sizeof(struct ieee80211_frame_cts)) {
+                       ic->ic_stats.is_rx_tooshort++;
+                       IC2IFP(ic)->if_ierrors++;
+                       m_freem(m);
+                       return;
+               }
+       } else if (len < sizeof(struct ieee80211_frame)) {
                ic->ic_stats.is_rx_tooshort++;
                IC2IFP(ic)->if_ierrors++;
                m_freem(m);
@@ -4055,7 +4063,15 @@ iwm_rx_mpdu_mq(struct iwm_softc *sc, struct mbuf *m, v
        }
 
        len = le16toh(desc->mpdu_len);
-       if (len < IEEE80211_MIN_LEN) {
+       if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+               /* Allow control frames in monitor mode. */
+               if (len < sizeof(struct ieee80211_frame_cts)) {
+                       ic->ic_stats.is_rx_tooshort++;
+                       IC2IFP(ic)->if_ierrors++;
+                       m_freem(m);
+                       return;
+               }
+       } else if (len < sizeof(struct ieee80211_frame)) {
                ic->ic_stats.is_rx_tooshort++;
                IC2IFP(ic)->if_ierrors++;
                m_freem(m);


Reply via email to