From 25f839c6d986285179528c3d30f9fbc1db87592c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 5 Mar 2012 15:22:42 +0200 Subject: [PATCH] Filter station mode EAPOL RX on bridge interface based on destination If multiple station mode radios are bridged together on the same device, it is possible for wpa_supplicant to receive EAPOL frames from the bridge interface and then process them separately for each interface. This can results in problems since multiple instances of supplicant side could end up trying to process a single 4-way handshake. Avoid this problem by filtering bridge interface EAPOL RX based on the desctination MAC address. It should be noted that this works only when unicast addresses are used (e.g., with WLAN) and not with the IEEE 802.1X EAPOL group address (e.g., most wired networks). Signed-hostap: Jouni Malinen --- wpa_supplicant/wpa_supplicant.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index fdee4076d..36074d582 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2094,6 +2094,31 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) } +static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr, + const u8 *buf, size_t len) +{ + struct wpa_supplicant *wpa_s = ctx; + const struct l2_ethhdr *eth; + + if (len < sizeof(*eth)) + return; + eth = (const struct l2_ethhdr *) buf; + + if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 && + !(eth->h_dest[0] & 0x01)) { + wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR + " (bridge - not for this interface - ignore)", + MAC2STR(src_addr), MAC2STR(eth->h_dest)); + return; + } + + wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR + " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest)); + wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth), + len - sizeof(*eth)); +} + + /** * wpa_supplicant_driver_init - Initialize driver interface parameters * @wpa_s: Pointer to wpa_supplicant data @@ -2116,8 +2141,8 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s) wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname, wpa_s->own_addr, ETH_P_EAPOL, - wpa_supplicant_rx_eapol, wpa_s, - 0); + wpa_supplicant_rx_eapol_bridge, + wpa_s, 1); if (wpa_s->l2_br == NULL) { wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet " "connection for the bridge interface '%s'",