diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 4c1bf7b8d..dbc01e236 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -281,6 +281,11 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) wpa_supplicant_ap_deinit(wpa_s); #endif /* CONFIG_AP */ +#ifdef CONFIG_HS20 + /* Clear possibly configured frame filters */ + wpa_drv_configure_frame_filters(wpa_s, 0); +#endif /* CONFIG_HS20 */ + if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) return; diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 3128fcb34..a62c1c36a 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -61,6 +61,46 @@ struct osu_provider { }; +void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) +{ + struct wpa_bss *bss = wpa_s->current_bss; + u8 *bssid = wpa_s->bssid; + const u8 *ie; + const u8 *ext_capa; + u32 filter = 0; + + if (!bss || !is_hs20_network(wpa_s, wpa_s->current_ssid, bss)) { + wpa_printf(MSG_DEBUG, + "Not configuring frame filtering - BSS " MACSTR + " is not a Hotspot 2.0 network", MAC2STR(bssid)); + return; + } + + ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE); + + /* Check if DGAF disabled bit is zero (5th byte in the IE) */ + if (!ie || ie[1] < 5) + wpa_printf(MSG_DEBUG, + "Not configuring frame filtering - Can't extract DGAF bit"); + else if (!(ie[6] & HS20_DGAF_DISABLED)) + filter |= WPA_DATA_FRAME_FILTER_FLAG_GTK; + + ext_capa = wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB); + if (!ext_capa || ext_capa[1] < 2) { + wpa_printf(MSG_DEBUG, + "Not configuring frame filtering - Can't extract Proxy ARP bit"); + return; + } + + /* Check if Proxy ARP is enabled (2nd byte in the IE) */ + if (ext_capa[3] & BIT(4)) + filter |= WPA_DATA_FRAME_FILTER_FLAG_ARP | + WPA_DATA_FRAME_FILTER_FLAG_NA; + + wpa_drv_configure_frame_filters(wpa_s, filter); +} + + void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id) { u8 conf; diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h index 9fc654c9a..89c47a536 100644 --- a/wpa_supplicant/hs20_supplicant.h +++ b/wpa_supplicant/hs20_supplicant.h @@ -8,6 +8,7 @@ #ifndef HS20_SUPPLICANT_H #define HS20_SUPPLICANT_H +void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s); void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id); int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes, diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index a6ace1adc..d1c953712 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -556,6 +556,10 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, if (old_ssid != wpa_s->current_ssid) wpas_notify_network_changed(wpa_s); +#ifdef CONFIG_HS20 + hs20_configure_frame_filters(wpa_s); +#endif /* CONFIG_HS20 */ + #ifdef CONFIG_P2P /* * If multi-channel concurrency is not supported, check for any diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 3f1d08b83..45930f9cd 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -552,6 +552,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->last_scan_res = NULL; #ifdef CONFIG_HS20 + if (wpa_s->drv_priv) + wpa_drv_configure_frame_filters(wpa_s, 0); hs20_deinit(wpa_s); #endif /* CONFIG_HS20 */ @@ -2319,6 +2321,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) wpa_ie_len += wpabuf_len(hs20); } wpabuf_free(hs20); + + hs20_configure_frame_filters(wpa_s); } } #endif /* CONFIG_HS20 */ @@ -2611,8 +2615,14 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) } old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = ssid; - if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) + + if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) { wpa_s->current_bss = bss; +#ifdef CONFIG_HS20 + hs20_configure_frame_filters(wpa_s); +#endif /* CONFIG_HS20 */ + } + wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s); if (old_ssid != wpa_s->current_ssid)