Update regulatory change to all virtual interface for the phy
wpas_p2p_setup_channels function uses the per interface information (wpa_s->hw.modes) for setting up the available channel list for P2P operation, but if a separate P2P interface is used (e.g., p2p0 on Android), the wpa_s instance for that interface may not get an updated channel list. This can result in some operations, like "P2P_SET disallow_freq", using old channel list information (e.g., world roaming information with passive-scan/no-ibss flags) which was initialized during the start-up. This could result in P2P functionality using conflicting or obsolete channel information. To resolve this issue, update channel list information on regulatory change events to all of the virtual interfaces sharing the same phy for which the event is received. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
709f18d501
commit
731ca6364e
1 changed files with 47 additions and 10 deletions
|
@ -2632,6 +2632,52 @@ static void wpas_event_deauth(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
const char *rn, *rn2;
|
||||||
|
struct wpa_supplicant *ifs;
|
||||||
|
|
||||||
|
if (wpa_s->drv_priv == NULL)
|
||||||
|
return; /* Ignore event during drv initialization */
|
||||||
|
|
||||||
|
free_hw_features(wpa_s);
|
||||||
|
wpa_s->hw.modes = wpa_drv_get_hw_feature_data(
|
||||||
|
wpa_s, &wpa_s->hw.num_modes, &wpa_s->hw.flags);
|
||||||
|
|
||||||
|
#ifdef CONFIG_P2P
|
||||||
|
wpas_p2p_update_channel_list(wpa_s);
|
||||||
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check other interfaces to see if they have the same radio-name. If
|
||||||
|
* so, they get updated with this same hw mode info.
|
||||||
|
*/
|
||||||
|
if (!wpa_s->driver->get_radio_name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
|
||||||
|
if (rn == NULL || rn[0] == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, "Checking for other virtual interfaces "
|
||||||
|
"sharing same radio (%s) in event_channel_list_change", rn);
|
||||||
|
|
||||||
|
for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
|
||||||
|
if (ifs == wpa_s || !ifs->driver->get_radio_name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
|
||||||
|
if (rn2 && os_strcmp(rn, rn2) == 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
|
||||||
|
ifs->ifname);
|
||||||
|
free_hw_features(ifs);
|
||||||
|
ifs->hw.modes = wpa_drv_get_hw_feature_data(
|
||||||
|
ifs, &ifs->hw.num_modes, &ifs->hw.flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
|
@ -3118,16 +3164,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
|
wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
|
||||||
break;
|
break;
|
||||||
case EVENT_CHANNEL_LIST_CHANGED:
|
case EVENT_CHANNEL_LIST_CHANGED:
|
||||||
if (wpa_s->drv_priv == NULL)
|
wpa_supplicant_update_channel_list(wpa_s);
|
||||||
break; /* Ignore event during drv initialization */
|
|
||||||
|
|
||||||
free_hw_features(wpa_s);
|
|
||||||
wpa_s->hw.modes = wpa_drv_get_hw_feature_data(
|
|
||||||
wpa_s, &wpa_s->hw.num_modes, &wpa_s->hw.flags);
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
|
||||||
wpas_p2p_update_channel_list(wpa_s);
|
|
||||||
#endif /* CONFIG_P2P */
|
|
||||||
break;
|
break;
|
||||||
case EVENT_INTERFACE_UNAVAILABLE:
|
case EVENT_INTERFACE_UNAVAILABLE:
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
|
|
Loading…
Reference in a new issue