Bug 12101

Summary: mac80211/ath5k : missing 2 bytes in monitor mode for ACK frames
Product: Networking Reporter: Benoit PAPILLAULT (benoit.papillault)
Component: WirelessAssignee: Benoit PAPILLAULT (benoit.papillault)
Severity: normal CC: kaber, mcgrof, me
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.28-rc6-wl Subsystem:
Regression: --- Bisected commit-id:

Description Benoit PAPILLAULT 2008-11-25 12:22:11 UTC
Latest working kernel version: n/a
Earliest failing kernel version: 2.6.28-rc6-wl
Distribution: Ubuntu / Debian
Hardware Environment: CM9 Atheros 802.11abg card
Software Environment:
Problem Description: missing 2 FCS bytes

Steps to reproduce:
1. Load ath5k and mac80211
2. Create a monitor interface (iw phy phy0 interface add mon0 type monitor)
3. Run wireshark on it (wireshark -i mon0 -k)
4. Check for 802.11 ACK frames

The FCS field (last bytes of the frame) is only 2 bytes instead of 4 bytes.
Comment 1 Patrick McHardy 2008-12-09 07:51:25 UTC
I'm seeing the same on 2.6.28-rc5 with this hardware:

00:0c.0 Ethernet controller: Atheros Communications Inc. AR5212/AR5213 Multiprotocol MAC/baseband processor (rev 01)
        Subsystem: Accton Technology Corporation Device ee23
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 168 (2500ns min, 7000ns max), Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 16
        Region 0: Memory at ff610000 (32-bit, non-prefetchable) [size=64K]
        Capabilities: <access denied>
        Kernel driver in use: ath5k_pci
        Kernel modules: ath5k

The radiotap header contains "00000000" as FCS value, the real frame is two bytes short. Not sure if this is the reason, but hostapd never adds associated stations to the kernel because it doesn't receive the final ACK.
Comment 2 Patrick McHardy 2008-12-09 09:13:34 UTC
I've found the reason for the missing two bytes:

	 * the hardware adds a padding to 4 byte boundaries between
	 * the header and the payload data if the header length is
	 * not multiples of 4 - remove it
	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
	if (hdrlen & 3) {
		pad = hdrlen % 4;
		memmove(skb->data + pad, skb->data, hdrlen);
		skb_pull(skb, pad);

For ACKs with an headerlen of ten, it strips the first two byte of the FCS. Since I don't have documentation, I don't know which frames exactly should be skipped above, simply skipping all frames with hdrlen == 10 fixed the ACKs for me.
Comment 3 Bob Copeland 2008-12-09 09:33:25 UTC
Nice find.  Interesting, hdrlen == 10 would be control frames - ACK/CTS.  I don't know the history of the pad removal but I wonder if it's valid.  IIRC madwifi did that too.
Comment 4 Patrick McHardy 2008-12-09 09:42:29 UTC
For other frames it also triggers, but does no (apparent) harm. Perhaps it simply needs to check whether there actually is a payload:

if (hdrlen & 3 && hdrlen != rs.rs_datalen - FCS_LEN)

or something like that. But I'm just guessing around :)
Comment 5 Bob Copeland 2008-12-31 06:35:21 UTC
Benoit, since John committed the patch for this can you close the bug?