hostapd - mac80211 - rt2x00 - rt73usb AP mode bug
iwo at call-direct.com.au
Thu Sep 11 22:00:49 EDT 2008
I'm trying to get to the bottom of a bug that stops me from using
hostapd - mac80211 - rt2x00 - rt73usb as an access point.
Initially, I assumed a bug within the rt2x00 driver and added some
tracing code to that. However, it now looks like the error is more
likely within mac80211 or hostapd.
I'm using today's GIT HEAD of rt2x00 and hostapd and libnl 1.1.
Hostapd is configured for using the NL80211 driver.
I'm testing this on two systems, vmware-based x86 and ARM. The bug
exists on both, but on the x86 the AP actually emits beacons, while
on the ARM the system crashes on a bad spinlock.
The reason for the problem is the driver private data (vif), which
doesn't get initialised, due to a missing call from mac80211.
The trace below was captured during hostapd startup. Sometimes there
is a discrepancy of 4 bytes between the printed pointer values of a
particular vif - it's still the same vif.
[T87]ieee80211_open:310: sdata->vif.type=5, &sdata->vif=c3b957b4
Hostapd has opened the monitor interface. Because the type is
IEEE80211_IF_TYPE_MNTR, the driver's add_interface method is
not called. This leaves vif=c3b957b4 uninitialised.
[T87]ieee80211_open:310: sdata->vif.type=1, &sdata->vif=c3a197b4
[T87]ieee80211_open:345: Calling local->ops->add_interface()
[T87]rt2x00mac_add_interface:307: Canary Check c3a197b8
Here, hostapd has opened wlan0 in AP mode (sdata->vif.type=1).
This code path in ieee80211_open calls the add_interface method
which ends up to be rt2x00mac_add_interface in our case. This
initialises vif=c3a197b4. The 'canary' is a couple of known
magic values I use to detect uninitialised vif data.
Next, hostapd attempts to send a packet to the monitor interface:
[T87]ieee80211_monitor_start_xmit:1397: skb=c2c0e710, vif=00000004
[T87]ieee80211_master_start_xmit:1332: odev=c3b95000 (.name=mon.wlan0)
[T87]ieee80211_master_start_xmit:1339: osdata=c3b95460, &osdata->vif=c3b957b4
[T87]ieee80211_master_start_xmit:1378: skb=c2c0e710, vif=c3b957b8
ieee80211_master_start_xmit finds the correct vif=c3b957b8
(which is not initialised) and calls the driver.
[T87]__ieee80211_tx:1063: skb=c2c0e710, vif=c3b957b8
[T87]rt2x00mac_tx:117: skb=c2c0e710, vif=c3b957b8
[T87]rt2x00queue_write_tx_frame:405: skb=c2c0e710, vif=c3b957b8
[T87]rt2x00queue_create_tx_descriptor:171: enter (1)
[T87]rt2x00queue_create_tx_descriptor:175: skb=c2c0e710, vif=c3b957b8
[T87]rt2x00queue_create_tx_descriptor:178: Canary Check c3b957b8
[T87]rt2x00queue_create_tx_descriptor:178: The canary died. canary1=00000000, canary2=00000000, lock=1
kernel BUG at drivers/net/wireless/rt2x00/rt2x00queue.c:178!
The debugging code detected the uninitialised vif and called BUG().
As far as I can see, there are two possible reasons for this.
1) Hostapd shouldn't have sent packets out of the monitor interface.
In that case, mac80211 should have thrown an error at hostapd.
2) ieee80211_open should have called the add_interface method, even
for monitor mode.
I asked Ivo van Doorn (the author of the rt2x00 drivers) about this,
here is the reply:
Ivo van Doorn wrote:
> Well sending through the monitor interface is fine, as long as the userspace agent
> that does this sets the sequence number. There is no way rt2x00 can create correct
> sequence numbers for multiple interfaces when it has to keep monitor interfaces into account.
Any more opinions about this?
More information about the HostAP