The generic solution here is to use ebtables - the broute chain is there to perform exactly this kind of filtering. Set a rule in the broute chain to route these EAPOL frames, rather than bridging them. Then open the packet socket on the original interface.
Simon -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Jouni Malinen Sent: Wednesday, March 29, 2006 11:14 AM To: netdev@vger.kernel.org Subject: RX processing order for packet sockets and bridge The current netif_receive_skb() implementation is delivering packets to all ptype_all handlers before calling handle_bridge() and to all ptype_base[type] handlers after calling handle_bridge(). This causes somewhat unfortunate difference in how packet sockets work based on whether they are bound to a specific sll_protocol or not for the case of special frames that bridge (stp) code processes internally. This does not probably matter much for most cases, but this breaks some applications. I'm looking at an issue where IEEE 802.1X authentication is used on an Ethernet device. In such a case, EAPOL frames are sent to special PAE group address (01:80:c2:00:00:03) with ethertype=EAPOL. At least for me, the most logical way of receiving these frames is to use a packet socket bound to the selected sll_ifndex and sll_protocol=EAPOL. This works fine whenever the network device is not part of a bridge. However, this gets difficult when the interface is added to a bridge. With STP disabled it is still possible to use the same type of packet socket to receive EAPOL frames. However, the frames will now end up being received from the bridge interface (e.g., br0), not Ethernet (eth0). In other words, the supplicant will need to know that it needs to bind to another interface. With STP enabled, the EAPOL frames to 01:80:c2:00:00:03 are not received anymore, so IEEE 802.1X authentication does not work with this kind of packet socket use. br_handle_frame() (called via br_handle_frame_hook) has code that processes all 01:80:c2:00:00:0? frames differently. 01:80:c2:00:00:00 will be delivered to NF_BR_LOCAL_IN and consumed internally (I would assume). Packets to other 01:80:c2:00:00:0? addresses get dropped. This is understandable since these are special addresses that bridges are not supposed to forward. However, IEEE 802.1X uses one of these addresses and those frames should be made available to user space programs (but without forwarding them to other ports). What could be done to make this work better? If the supplicant would not bind to a specific sll_protocol, the packets are received at eth0 and this works. However, lots of other packets would also be received and user space filtering for these is not really a good idea. One could probably use Linux socket filters to do filtering in kernel (if those are processed before packet sockets; I did not yet verify this), but even that is somewhat complex solution compared to binding a packet socket to sll_protocol=EAPOL. One option would be to move packet socket handlers to be called before handle_bridge() call for both the cases where they are bound to a specific protocol and where they are not. This would allow EAPOL frames to be received from eth0 regardless of whether the device is in a bridge or not. This sounds like the cleanest solution from the user space viewpoint. Would this be feasible? Can all protocol (ptype_base[type]) handlers be called before handle_bridge() or would there need to be special case for packet sockets? Another option would be to teach bridge code about this special-special case and make br_handle_frame() return 0 if destination address is 01:80:c2:00:00:03. Doing this for the stp_enabled case seemed to resolve the problem I was seeing with wpa_supplicant not receiving the frames when STP was enabled. However, since this was only for stp_enabled, the frames in STP disabled case were received from br0, not eth0. It would be possible to return 0 from br_handle_frame() for both cases with some extra CPU use (i.e., one new memcmp() regardless of whether STP is enabled or not). This should allow EAPOL frames to be received from eth0 in all cases using packet socket with sll_protocol bound to EAPOL, so user space side would be as clean as the first option I mentioned above. However, this would be a specific solution for this particular issue with IEEE 802.1X. Would this be acceptable, if moving packet socket handlers in netif_receive_skb() is consider too expensive? Is anyone aware of a better solution for this issue? -- Jouni Malinen PGP id EFC895FA - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html