Hi, The wpa supplicant (tries to) use routing messages of type RTM_80211INFO to detect WLAN access point changes. If the SSID or the BSSID changes compared to the last RTM_80211INFO message an ASSOC event is injected into the 802.1x state machines. The problem with this approach is that the kernel only generates these events when the WLAN link state changes to "UP". In most cases link UP is basically the same as the IEEE80211_S_RUN which means that the STA associated to an AP and the AP confirmed the association. However, in the case of 802.1x the flag IEEE80211_F_RSNON is set which delays the link up event until after the 802.1x handshake is complete. In the roaming case this means that the WPA supplicant does not notice that it was DEAUTH'ed from an access point that we are roaming away from. As a result it will drop EAPOL packets from the new AP an association with the new AP will fail. In the case of an initial connection wpa_supplicant will try to associate with the BSSID 00:00:00:00:00:00 until this attempt times out. Depending on the exact timing a subsequent attempt to associate with the correct BSSID may or may not be started. To fix this send the RTM_80211INFO if we reach the IEEE80211_S_RUN state even if this does not result in a link up event. In the 802.1x case this will result in two of these messages with the same SSID and BSSID. The first event when we reach the IEEE80211_S_RUN state (before the 802.1x authentication) and a second message once the interface is actually up. A quick grep into userland suggest that this additional message is not a problem and it fixes 802.1x.
regards Christian diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index accec8d74d..a1a99e5024 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1307,6 +1307,8 @@ justcleanup: */ ieee80211_set_link_state(ic, LINK_STATE_UP); ni->ni_assoc_fail = 0; + } else { + task_add(systq, &ic->ic_rtm_80211info_task); } ic->ic_mgt_timer = 0; ieee80211_set_beacon_miss_threshold(ic); @@ -1322,11 +1324,10 @@ void ieee80211_rtm_80211info_task(void *arg) { struct ieee80211com *ic = arg; - struct ifnet *ifp = &ic->ic_if; struct if_ieee80211_data ifie; int s = splnet(); - if (LINK_STATE_IS_UP(ifp->if_link_state)) { + if (ic->ic_state == IEEE80211_S_RUN) { memset(&ifie, 0, sizeof(ifie)); ifie.ifie_nwid_len = ic->ic_bss->ni_esslen; memcpy(ifie.ifie_nwid, ic->ic_bss->ni_essid,
smime.p7s
Description: S/MIME cryptographic signature