It may be a weird patch, but probably just because I'm still wrapping my head around how things work. The problem is ultimately the call to __cfg80211_send_deauth() in wireless/mlme.c that is triggered by reception of the DEAUTH. That function removes wdev->auth_bsses[i], which is needed in order for an auth to succeed. The code path that gets us there is: mac80211/rx.c: ieee80211_rx_h_mgmt() mac80211/mlme.c: ieee80211_sta_rx_mgmt() ...then through the queued work and... ieee80211_sta_rx_queued_mgmt() At the bottom of the latter function, outside of the block that checks for our authentication state, we call cfg80211_send_deauth() in response to IEEE80211_STYPE_DEAUTH, which quite arguably should never be called if we're authenticated. The only time this issue touches cfg80211 is that final call to send_deauth() which I believe is done in error. I think the fix should be in mac80211 somewhere. I didn't find a way to tell where we were in the authentication proces from within ieee80211_sta_rx_queued_mgmt(), so I swallowed the packet much earlier in the process from within ieee80211_work_rx_mgmt(), which has access to that state, and can indeed claim packets for itself it it believes it knows best what to do with them. I hope this clears up my thinking on this. I'd be happy to change the patch in whatever way makes sense. -- Paul On Fri, Jul 2, 2010 at 10:29 AM, Johannes Berg <johannes@xxxxxxxxxxxxxxxx> wrote: > On Thu, 2010-07-01 at 10:21 -0700, Paul Stewart wrote: >> @@ -1030,6 +1030,25 @@ ieee80211_rx_result >> ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, >> skb_queue_tail(&local->work_skb_queue, skb); >> ieee80211_queue_work(&local->hw, &local->work_work); >> return RX_QUEUED; >> + case IEEE80211_STYPE_DEAUTH: >> + /* >> + * If we get sent a DEAUTH while we are >> + * actively trying to authenticate to this >> + * station, we shoot ourselves in the foot if >> + * we fall through using RX_CONTINUE and allow >> + * the bss context to disappear >> + * (ieee80211_sta_rx_mgmt()). This is >> + * especially true if the reason for the >> + * DEAUTH was a negative but temporary direct >> + * response to an AUTH attempt. Let the retry >> + * mechanism run its course instead. >> + */ >> + reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); >> + if (wk->type == IEEE80211_WORK_AUTH && >> + reason_code == WLAN_REASON_PREV_AUTH_NOT_VALID) { >> + return RX_DROP_MONITOR; >> + } >> + break; > > Ok, wow, I finally understand this patch, but is it weird!! You're > modifying work.c to avoid having the mlme.c code send this frame to > cfg80211? That's really confusing. > > The real reason for this is that we send up the deauth frame even when > we're not even authenticated. This happens in mlme.c. Therefore, we > should improve the logic in ieee80211_sta_rx_queued_mgmt() to make sure > it only triggers when we're authenticated with the BSS? > > Alternatively, since cfg80211 tracks this, it would be easier to modify > cfg80211_send_rx_auth() to not send the event to userspace in the !done > case I guess. > > johannes > > -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html