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,

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to