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:
Jouni Malinen 2014-02-25 22:37:57 +02:00 committed by Jouni Malinen
parent da60d9c1ca
commit 3d910ef497
5 changed files with 41 additions and 7 deletions

View file

@ -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;
}

View file

@ -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;
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;
}

View file

@ -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);

View file

@ -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)

View file

@ -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;