[RFC 2/4] HS20: Add support for configuring frame filters

Ilan Peer ilan.peer at intel.com
Mon Mar 7 08:55:47 PST 2016


From: Matti Gottlieb <matti.gottlieb at intel.com>

When a station has associated to a HS2.0 network, request
the driver to do the following, based on the BSS capabilities:

1. Enable gratuitous ARP filtering
2. Enable unsolicited Neighbor Advertisement filtering
3. Enable GTK filtering if DGAF disabled bit is zero

TODO:

HS2.0 requires the filtering to start only after an IP
address is obtained. However, the configuration is done
regardless of obtaining an IP address, so this might
not be good enough.

Signed-off-by: Matti Gottlieb <matti.gottlieb at intel.com>
---
 wpa_supplicant/driver_i.h        |  8 ++++++++
 wpa_supplicant/hs20_supplicant.c | 40 ++++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/hs20_supplicant.h |  1 +
 wpa_supplicant/wpa_supplicant.c  | 12 +++++++++++-
 4 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 699fd4f..58c85ce 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -917,4 +917,12 @@ static inline int wpa_drv_abort_scan(struct wpa_supplicant *wpa_s)
 	return wpa_s->driver->abort_scan(wpa_s->drv_priv);
 }
 
+static inline int wpa_drv_configure_frame_filters(struct wpa_supplicant *wpa_s,
+						  u32 filters)
+{
+	if (!wpa_s->driver->configure_data_frame_filters)
+		return -1;
+	return wpa_s->driver->configure_data_frame_filters(wpa_s->drv_priv,
+							   filters);
+}
 #endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
index 3128fcb..e6a1fb1 100644
--- a/wpa_supplicant/hs20_supplicant.c
+++ b/wpa_supplicant/hs20_supplicant.c
@@ -60,6 +60,46 @@ struct osu_provider {
 	size_t icon_count;
 };
 
+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 (!is_hs20_network(wpa_s, wpa_s->current_ssid, bss)) {
+		wpa_printf(MSG_DEBUG,
+			   "Not configuring frame filtering - bss "
+			   MACSTR " is not a HS network\n", 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\n");
+	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 - Cant extract proxy ARP bit\n");
+		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;
+
+	if (filter)
+		wpa_drv_configure_frame_filters(wpa_s, filter);
+}
+
 
 void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id)
 {
diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h
index 9fc654c..89c47a5 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/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 136cb58..3dccd50 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -751,6 +751,9 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 		wpas_connect_work_done(wpa_s);
 		/* Reinitialize normal_scan counter */
 		wpa_s->normal_scans = 0;
+#ifdef CONFIG_HS20
+		hs20_configure_frame_filters(wpa_s);
+#endif /* CONFIG_HS20 */
 	}
 
 #ifdef CONFIG_P2P
@@ -816,8 +819,15 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_BGSCAN
 	if (state == WPA_COMPLETED)
 		wpa_supplicant_start_bgscan(wpa_s);
-	else if (state < WPA_ASSOCIATED)
+	else if (state < WPA_ASSOCIATED) {
 		wpa_supplicant_stop_bgscan(wpa_s);
+
+#ifdef CONFIG_HS20
+		/* clear possibly configured frame filters */
+		if (old_state == WPA_COMPLETED)
+			wpa_drv_configure_frame_filters(wpa_s, 0);
+#endif /* CONFIG_HS20 */
+	}
 #endif /* CONFIG_BGSCAN */
 
 	if (state == WPA_AUTHENTICATING)
-- 
1.9.1




More information about the Hostap mailing list