When wpa_supplicant is running on a Linux interface that is configured in promiscuous mode, and it is not a member of a bridge, incoming EAPOL packets are processed regardless of the Destination Address in the frame. As a consequence, there are situations where wpa_supplicant replies to EAPOL packets that are not destined for it. This behavior seems undesired (see IEEE Std 802.1X-2010, 11.4.a), and can be avoided by attaching a BPF filter that lets the kernel discard packets having pkt_type equal to PACKET_OTHERHOST. Signed-off-by: Davide Caratti <davide.caratti@xxxxxxxxx> --- src/l2_packet/l2_packet.h | 1 + src/l2_packet/l2_packet_linux.c | 22 ++++++++++++++++++++++ wpa_supplicant/wpa_supplicant.c | 5 +++++ 3 files changed, 28 insertions(+) diff --git a/src/l2_packet/l2_packet.h b/src/l2_packet/l2_packet.h index 2a4524582..53871774b 100644 --- a/src/l2_packet/l2_packet.h +++ b/src/l2_packet/l2_packet.h @@ -42,6 +42,7 @@ struct l2_ethhdr { enum l2_packet_filter_type { L2_PACKET_FILTER_DHCP, L2_PACKET_FILTER_NDISC, + L2_PACKET_FILTER_PKTTYPE, }; /** diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c index 65b490679..c5d889dca 100644 --- a/src/l2_packet/l2_packet_linux.c +++ b/src/l2_packet/l2_packet_linux.c @@ -84,6 +84,25 @@ static const struct sock_fprog ndisc_sock_filter = { .filter = ndisc_sock_filter_insns, }; +/* drop packet if skb->pkt_type is PACKET_OTHERHOST (0x03). Generated by: + * $ bpfc - <<-EOF + * > ldb #type + * > jeq #0x03, drop + * > pass: ret #-1 + * > drop: ret #0 + * > EOF + */ +static struct sock_filter pkt_type_filter_insns[] = { + { 0x30, 0, 0, 0xfffff004 }, + { 0x15, 1, 0, 0x00000003 }, + { 0x6, 0, 0, 0xffffffff }, + { 0x6, 0, 0, 0x00000000 }, +}; + +static const struct sock_fprog pkt_type_sock_filter = { + .len = ARRAY_SIZE(pkt_type_filter_insns), + .filter = pkt_type_filter_insns, +}; int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) { @@ -471,6 +490,9 @@ int l2_packet_set_packet_filter(struct l2_packet_data *l2, case L2_PACKET_FILTER_NDISC: sock_filter = &ndisc_sock_filter; break; + case L2_PACKET_FILTER_PKTTYPE: + sock_filter = &pkt_type_sock_filter; + break; default: return -1; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index fcb267764..7e6844a75 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3993,6 +3993,11 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) wpa_supplicant_rx_eapol, wpa_s, 0); if (wpa_s->l2 == NULL) return -1; + + if (l2_packet_set_packet_filter(wpa_s->l2, + L2_PACKET_FILTER_PKTTYPE)) + wpa_msg(wpa_s, MSG_DEBUG, + "Failed to attach pkt_type filter"); } else { const u8 *addr = wpa_drv_get_mac_addr(wpa_s); if (addr) -- 2.14.3 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap