diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index e95b55bf0..1fbbddae1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5462,6 +5462,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) eapol_sm_notify_logoff(wpa_s->eapol, FALSE); radio_remove_works(wpa_s, NULL, 1); + + wpa_s->next_ssid = NULL; } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 47434e4b3..44449440f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -728,7 +728,8 @@ static int bss_is_ess(struct wpa_bss *bss) static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, int i, struct wpa_bss *bss, - struct wpa_ssid *group) + struct wpa_ssid *group, + int only_first_ssid) { u8 wpa_ie_len, rsn_ie_len; int wpa; @@ -789,7 +790,7 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, wpa = wpa_ie_len > 0 || rsn_ie_len > 0; - for (ssid = group; ssid; ssid = ssid->pnext) { + for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) { int check_ssid = wpa ? 1 : (ssid->ssid_len != 0); int res; @@ -938,16 +939,22 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, static struct wpa_bss * wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group, - struct wpa_ssid **selected_ssid) + struct wpa_ssid **selected_ssid, + int only_first_ssid) { unsigned int i; - wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d", - group->priority); + if (only_first_ssid) + wpa_dbg(wpa_s, MSG_DEBUG, "Try to find BSS matching pre-selected network id=%d", + group->id); + else + wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d", + group->priority); for (i = 0; i < wpa_s->last_scan_res_used; i++) { struct wpa_bss *bss = wpa_s->last_scan_res[i]; - *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group); + *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group, + only_first_ssid); if (!*selected_ssid) continue; wpa_dbg(wpa_s, MSG_DEBUG, " selected BSS " MACSTR @@ -972,10 +979,27 @@ struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, return NULL; /* no scan results from last update */ while (selected == NULL) { + if (wpa_s->next_ssid) { + struct wpa_ssid *ssid; + + /* check that next_ssid is still valid */ + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + if (ssid == wpa_s->next_ssid) + break; + wpa_s->next_ssid = NULL; + + if (ssid) { + selected = wpa_supplicant_select_bss( + wpa_s, ssid, selected_ssid, 1); + if (selected) + break; + } + } + for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { selected = wpa_supplicant_select_bss( wpa_s, wpa_s->conf->pssid[prio], - selected_ssid); + selected_ssid, 0); if (selected) break; } diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index da8971d9b..eaf231bc4 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -918,6 +918,7 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s, wpa_config_set_quoted(ssid, "password", cred->password) < 0) goto fail; + wpa_s->next_ssid = ssid; wpa_config_update_prio_list(wpa_s->conf); interworking_reconnect(wpa_s); @@ -1241,6 +1242,7 @@ static int interworking_connect_roaming_consortium( cred->eap_method->method == EAP_TYPE_TTLS) < 0) goto fail; + wpa_s->next_ssid = ssid; wpa_config_update_prio_list(wpa_s->conf); interworking_reconnect(wpa_s); @@ -1443,6 +1445,7 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) nai_realm_free(realm, count); + wpa_s->next_ssid = ssid; wpa_config_update_prio_list(wpa_s->conf); interworking_reconnect(wpa_s); diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index a82fbf3a9..2db1d5441 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -252,6 +252,8 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s, void wpas_notify_network_removed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { + if (wpa_s->next_ssid == ssid) + wpa_s->next_ssid = NULL; if (wpa_s->wpa) wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 3dcc90007..765f5b6c5 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -420,6 +420,9 @@ struct wpa_supplicant { enum { WPA_SETBAND_AUTO, WPA_SETBAND_5G, WPA_SETBAND_2G } setband; + /* Preferred network for the next connection attempt */ + struct wpa_ssid *next_ssid; + /* previous scan was wildcard when interleaving between * wildcard scans and specific SSID scan when max_ssids=1 */ int prev_scan_wildcard;