Interworking: Prefer last added network during network selection
Previously, any network block could be used to select the BSS to connect to when processing scan results after Interworking network selection. This can result in somewhat unexpected network selection in cases where credential preferences indicated that a specific network was selected, but another network ended up getting used for the connection. While the older networks continue to be valid, add special processing for this initial post-interworking-connect case to get more consistent network selection to match with the Interworking network selection result. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
da60d9c1ca
commit
3d910ef497
5 changed files with 41 additions and 7 deletions
|
@ -5462,6 +5462,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
|
||||||
eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
|
eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
|
||||||
|
|
||||||
radio_remove_works(wpa_s, NULL, 1);
|
radio_remove_works(wpa_s, NULL, 1);
|
||||||
|
|
||||||
|
wpa_s->next_ssid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
|
||||||
int i, struct wpa_bss *bss,
|
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;
|
u8 wpa_ie_len, rsn_ie_len;
|
||||||
int wpa;
|
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;
|
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 check_ssid = wpa ? 1 : (ssid->ssid_len != 0);
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -938,16 +939,22 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
|
||||||
static struct wpa_bss *
|
static struct wpa_bss *
|
||||||
wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
|
wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *group,
|
struct wpa_ssid *group,
|
||||||
struct wpa_ssid **selected_ssid)
|
struct wpa_ssid **selected_ssid,
|
||||||
|
int only_first_ssid)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
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",
|
wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
|
||||||
group->priority);
|
group->priority);
|
||||||
|
|
||||||
for (i = 0; i < wpa_s->last_scan_res_used; i++) {
|
for (i = 0; i < wpa_s->last_scan_res_used; i++) {
|
||||||
struct wpa_bss *bss = wpa_s->last_scan_res[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)
|
if (!*selected_ssid)
|
||||||
continue;
|
continue;
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, " selected BSS " MACSTR
|
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 */
|
return NULL; /* no scan results from last update */
|
||||||
|
|
||||||
while (selected == NULL) {
|
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++) {
|
for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
|
||||||
selected = wpa_supplicant_select_bss(
|
selected = wpa_supplicant_select_bss(
|
||||||
wpa_s, wpa_s->conf->pssid[prio],
|
wpa_s, wpa_s->conf->pssid[prio],
|
||||||
selected_ssid);
|
selected_ssid, 0);
|
||||||
if (selected)
|
if (selected)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -918,6 +918,7 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
|
||||||
wpa_config_set_quoted(ssid, "password", cred->password) < 0)
|
wpa_config_set_quoted(ssid, "password", cred->password) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
wpa_s->next_ssid = ssid;
|
||||||
wpa_config_update_prio_list(wpa_s->conf);
|
wpa_config_update_prio_list(wpa_s->conf);
|
||||||
interworking_reconnect(wpa_s);
|
interworking_reconnect(wpa_s);
|
||||||
|
|
||||||
|
@ -1241,6 +1242,7 @@ static int interworking_connect_roaming_consortium(
|
||||||
cred->eap_method->method == EAP_TYPE_TTLS) < 0)
|
cred->eap_method->method == EAP_TYPE_TTLS) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
wpa_s->next_ssid = ssid;
|
||||||
wpa_config_update_prio_list(wpa_s->conf);
|
wpa_config_update_prio_list(wpa_s->conf);
|
||||||
interworking_reconnect(wpa_s);
|
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);
|
nai_realm_free(realm, count);
|
||||||
|
|
||||||
|
wpa_s->next_ssid = ssid;
|
||||||
wpa_config_update_prio_list(wpa_s->conf);
|
wpa_config_update_prio_list(wpa_s->conf);
|
||||||
interworking_reconnect(wpa_s);
|
interworking_reconnect(wpa_s);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid)
|
struct wpa_ssid *ssid)
|
||||||
{
|
{
|
||||||
|
if (wpa_s->next_ssid == ssid)
|
||||||
|
wpa_s->next_ssid = NULL;
|
||||||
if (wpa_s->wpa)
|
if (wpa_s->wpa)
|
||||||
wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
|
wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
|
||||||
if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s)
|
if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s)
|
||||||
|
|
|
@ -420,6 +420,9 @@ struct wpa_supplicant {
|
||||||
|
|
||||||
enum { WPA_SETBAND_AUTO, WPA_SETBAND_5G, WPA_SETBAND_2G } setband;
|
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
|
/* previous scan was wildcard when interleaving between
|
||||||
* wildcard scans and specific SSID scan when max_ssids=1 */
|
* wildcard scans and specific SSID scan when max_ssids=1 */
|
||||||
int prev_scan_wildcard;
|
int prev_scan_wildcard;
|
||||||
|
|
Loading…
Reference in a new issue