diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 68b407b9a..441718d7f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1743,6 +1743,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); } + wpa_s->last_eapol_matches_bssid = 0; + if (wpa_s->pending_eapol_rx) { struct os_time now, age; os_get_time(&now); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 020f0bd3a..f033924cb 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2200,17 +2200,28 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr)); wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len); - if (wpa_s->wpa_state < WPA_ASSOCIATED) { + if (wpa_s->wpa_state < WPA_ASSOCIATED || + (wpa_s->last_eapol_matches_bssid && +#ifdef CONFIG_AP + !wpa_s->ap_iface && +#endif /* CONFIG_AP */ + os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) { /* * There is possible race condition between receiving the * association event and the EAPOL frame since they are coming * through different paths from the driver. In order to avoid * issues in trying to process the EAPOL frame before receiving * association information, lets queue it for processing until - * the association event is received. + * the association event is received. This may also be needed in + * driver-based roaming case, so also use src_addr != BSSID as a + * trigger if we have previously confirmed that the + * Authenticator uses BSSID as the src_addr (which is not the + * case with wired IEEE 802.1X). */ wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing " - "of received EAPOL frame"); + "of received EAPOL frame (state=%s bssid=" MACSTR ")", + wpa_supplicant_state_txt(wpa_s->wpa_state), + MAC2STR(wpa_s->bssid)); wpabuf_free(wpa_s->pending_eapol_rx); wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len); if (wpa_s->pending_eapol_rx) { @@ -2221,6 +2232,9 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, return; } + wpa_s->last_eapol_matches_bssid = + os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0; + #ifdef CONFIG_AP if (wpa_s->ap_iface) { wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 3a56064b0..07a9e01d6 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -474,6 +474,7 @@ struct wpa_supplicant { struct wpabuf *pending_eapol_rx; struct os_time pending_eapol_rx_time; u8 pending_eapol_rx_src[ETH_ALEN]; + unsigned int last_eapol_matches_bssid:1; struct ibss_rsn *ibss_rsn;