From d72aad942ba23d415ea91375052f77dbf1a098a7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 2 Dec 2009 17:54:57 +0200 Subject: [PATCH] nl80211: Clear BSS state mismatches with deauth as a workaround There seem to be some cases in which wpa_supplicant and cfg80211/mac80211 seem to have different understanding on authentication/association state. Since cfg80211/mac80211 is very strict on when it accepts new authentication/association/scan commands, try our best at clearing such state mismatches by explicitly deauthenticating from BSSes with which the driver claims we are associated with if we do not have local information about such association. --- src/drivers/driver_nl80211.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index c4db1a266..89ddf5c79 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -121,6 +121,8 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, static int wpa_driver_nl80211_set_mode(void *priv, int mode); static int wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv); +static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, + const u8 *addr, int cmd, u16 reason_code); #if defined(CONFIG_AP) || defined(HOSTAPD) static void nl80211_remove_monitor_interface( @@ -1700,6 +1702,19 @@ static int bss_info_handler(struct nl_msg *msg, void *arg) } +static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv, + const u8 *addr) +{ + if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) { + wpa_printf(MSG_DEBUG, "nl80211: Clear possible state " + "mismatch"); + wpa_driver_nl80211_mlme(drv, addr, + NL80211_CMD_DEAUTHENTICATE, + WLAN_REASON_PREV_AUTH_NOT_VALID); + } +} + + static void wpa_driver_nl80211_check_bss_status( struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res) { @@ -1734,13 +1749,16 @@ static void wpa_driver_nl80211_check_bss_status( wpa_printf(MSG_DEBUG, "nl80211: Local state " "(not associated) does not match " "with BSS state"); + clear_state_mismatch(drv, r->bssid); } else if (drv->nlmode == NL80211_IFTYPE_STATION && os_memcmp(drv->bssid, r->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "nl80211: Local state " "(associated with " MACSTR ") does " "not match with BSS state", - MAC2STR(r->bssid)); + MAC2STR(drv->bssid)); + clear_state_mismatch(drv, r->bssid); + clear_state_mismatch(drv, drv->bssid); } } }