After key negotiation completed using wpa_supplicant, wpa_supplicant can't reassoc with the AP if we reboot the AP. It always fails at the 4-way handshake. The problem is the key info is not cleared correctly. Thus when wpa_supplicant send the EAPOL-KEY packet, the d80211 stack finds the old key and uses it to encrypt the packet.
The patch removes the sta_info when we disassociate with AP. Thanks, Hong
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c index 8caf352..2144b34 100644 --- a/net/d80211/ieee80211_sta.c +++ b/net/d80211/ieee80211_sta.c @@ -739,6 +739,14 @@ static void ieee80211_associated(struct wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); mod_timer(&ifsta->timer, jiffies + IEEE80211_MONITORING_INTERVAL + 30 * HZ); + + sta = sta_info_get(local, ifsta->bssid); + if (sta) { + sta_info_free(sta, 0); + sta_info_put(sta); + } + + ifsta->probereq_poll = 0; } else { mod_timer(&ifsta->timer, jiffies + IEEE80211_MONITORING_INTERVAL); diff --git a/net/d80211/sta_info.c b/net/d80211/sta_info.c index 7f5febe..8902816 100644 --- a/net/d80211/sta_info.c +++ b/net/d80211/sta_info.c @@ -197,6 +197,12 @@ #ifdef CONFIG_D80211_VERBOSE_DEBUG local->mdev->name, MAC_ARG(sta->addr)); #endif /* CONFIG_D80211_VERBOSE_DEBUG */ + if (sta->key) { + ieee80211_key_sysfs_remove(sta->key); + ieee80211_key_free(sta->key); + sta->key = NULL; + } + rate_control_remove_sta_attrs(local, sta->rate_ctrl_priv, &sta->kobj); ieee80211_sta_sysfs_remove(sta); @@ -244,8 +250,6 @@ void sta_info_free(struct sta_info *sta, kfree(key); } } - ieee80211_key_free(sta->key); - sta->key = NULL; } else if (sta->key_idx_compression != HW_KEY_IDX_INVALID) { struct ieee80211_key_conf conf; memset(&conf, 0, sizeof(conf));