With A-MSDUs enabled in -current people are seeing a lot of
input packet decapsulations failed
events in netstat -W iwm0.
This fixes the issue on iwm 8265 for me. There are between 6 and 8 bytes of
trailing data in the A-MSDU frame buffer. This results in a decap failure
being counted when m_pullup() fails to fetch ETHER_HDR_LEN + LLC_SNAPFRAMELEN
bytes.
I suppose such bytes are padding left by the hardware, most likely due to
decryption. It should be safe to ignore these. A TCP stream that uses
A-MSDUs looks clean, so we're not losing any packets. This problem is
just a cosmetic one.
ok?
iwm(4) 9260+ and iwx(4) have another issue because these devices actually
decapsulate A-MSDUs in hardware and our code doesn't handle that yet.
I will send a separate patch for this soon.
diff b0e5533ef47f577f6c3be1bfdbb89151a76d3add /usr/src
blob - 2c9ee3ab48a212ce9730860568ca59d17d3d4636
file + sys/net80211/ieee80211_input.c
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -1148,14 +1148,13 @@ ieee80211_amsdu_decap(struct ieee80211com *ic, struct
/* strip 802.11 header */
m_adj(m, hdrlen);
- for (;;) {
+ while (m->m_pkthdr.len >= ETHER_HDR_LEN + LLC_SNAPFRAMELEN) {
/* process an A-MSDU subframe */
- if (m->m_len < ETHER_HDR_LEN + LLC_SNAPFRAMELEN) {
- m = m_pullup(m, ETHER_HDR_LEN + LLC_SNAPFRAMELEN);
- if (m == NULL) {
- ic->ic_stats.is_rx_decap++;
- break;
- }
+ len = m->m_pkthdr.len;
+ m = m_pullup(m, ETHER_HDR_LEN + LLC_SNAPFRAMELEN);
+ if (m == NULL) {
+ ic->ic_stats.is_rx_decap++;
+ break;
}
eh = mtod(m, struct ether_header *);
/* examine 802.3 header */
@@ -1202,15 +1201,13 @@ ieee80211_amsdu_decap(struct ieee80211com *ic, struct
}
ieee80211_enqueue_data(ic, m, ni, mcast, ml);
- if (n->m_pkthdr.len == 0) {
- m_freem(n);
- break;
- }
m = n;
/* remove padding */
pad = ((len + 3) & ~3) - len;
m_adj(m, pad);
}
+
+ m_freem(m);
}
/*