diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 5161333d8..bd3248000 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -325,6 +325,11 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) bin_clear_free(hapd->tmp_eap_user.password, hapd->tmp_eap_user.password_len); #endif /* CONFIG_SQLITE */ + +#ifdef CONFIG_MESH + wpabuf_free(hapd->mesh_pending_auth); + hapd->mesh_pending_auth = NULL; +#endif /* CONFIG_MESH */ } diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 4a50a008d..8e2c70eca 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -251,6 +251,8 @@ struct hostapd_data { int num_plinks; int max_plinks; void (*mesh_sta_free_cb)(struct sta_info *sta); + struct wpabuf *mesh_pending_auth; + struct os_reltime mesh_pending_auth_time; #endif /* CONFIG_MESH */ #ifdef CONFIG_SQLITE diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 09c398ab1..97f98f28e 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -889,6 +889,16 @@ static void handle_auth(struct hostapd_data *hapd, if (hapd->conf->mesh & MESH_ENABLED) { /* if the mesh peer is not available, we don't do auth. */ + wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR + " not yet known - drop Authentiation frame", + MAC2STR(mgmt->sa)); + /* + * Save a copy of the frame so that it can be processed + * if a new peer entry is added shortly after this. + */ + wpabuf_free(hapd->mesh_pending_auth); + hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len); + os_get_reltime(&hapd->mesh_pending_auth_time); return; } #endif /* CONFIG_MESH */ diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c index ff909faac..e7c53eace 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -583,6 +583,29 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr, if (ssid && ssid->no_auto_peer) { wpa_msg(wpa_s, MSG_INFO, "will not initiate new peer link with " MACSTR " because of no_auto_peer", MAC2STR(addr)); + if (data->mesh_pending_auth) { + struct os_reltime age; + const struct ieee80211_mgmt *mgmt; + struct hostapd_frame_info fi; + + mgmt = wpabuf_head(data->mesh_pending_auth); + os_reltime_age(&data->mesh_pending_auth_time, &age); + if (age.sec < 2 && + os_memcmp(mgmt->sa, addr, ETH_ALEN) == 0) { + wpa_printf(MSG_DEBUG, + "mesh: Process pending Authentication frame from %u.%06u seconds ago", + (unsigned int) age.sec, + (unsigned int) age.usec); + os_memset(&fi, 0, sizeof(fi)); + ieee802_11_mgmt( + data, + wpabuf_head(data->mesh_pending_auth), + wpabuf_len(data->mesh_pending_auth), + &fi); + } + wpabuf_free(data->mesh_pending_auth); + data->mesh_pending_auth = NULL; + } return; }