If I have two interfaces (eth0, eth1) attached to a bridge (br0) then I'd like to have sockets bound to each of the slave interfaces, so that I can receive packets that were received over a specific interface and that interface only. I can bind the sockets as described (before or after adding the slave interface to the bridge) but no packets are received once they have been added to the bridge.
Alternatively, I could listen on the bridge interface and have some means to discover over which slave the received packets came, such as using
recvfrom() but this fails as
struct sockaddr_ll.sll_ifindex indicates the bridge interface. This is also the case if the socket is not bound or bound on
sll_ifindex=0 (any interface).
I suspect that ebtables
BROUTING entries might be able to block the packets of interest being forwarded to the bridge, which in turn may make then visible via the sockets bound to the slave interfaces. I have not yet investigated this.
It may not be all that useful as in a bridged configuration the slaves typically do not have IP addresses defined. Receiving ARP packets would not be a problem (they can be specified by the ethernet type in the
PF_PACKET, SOCK_RAW socket specification) but DHCP packets would need an ethernet type of
IP and user-space filtering, which is probably significantly less efficient than using the kernel filter via libpcap suggested in my answer. I guess that depends on the effectiveness of the BROUTING filter.
Ok, I'll fess up about what I'm really trying to do. I want to use a WLAN interface (which I'll call primary) connected in station mode (to some access point) and bridge that interface to another one (secondary), either ethernet or a second WLAN interface running an access point (using hostpad). The subnet DHCP service is provided via the primary interface. There are plenty of questions both here and on Unix & Linux with answers explaining why that will not work: Bridge wireless network to LAN and How do I configure a network interface bridge from WiFi to Ethernet with Debian?, for example.
I'm interested in using a bridge rather than other solution types such as NAT or IP-level proxying. The bridge needs to support broadcast and multicast traffic, as well as unicast. I understand the basic reasons why this won't work out-of-the-box and the possibilities and restrictions of using 4addr mode and WDS (which is not applicable in my case).
In fact, because there are such issues in making it work out of the box, recent Linux kernels have a blanket prohibition on adding a station-mode WLAN interface to a bridge. It is a relatively simple kernel patch to revert that limitation.
With that in place, the procedures using ebtables as described in Bridging Network Connections: Bridging with a wireless NIC get one most of the way there. That example requires manual configuration of each bridged host via a pair of ebtables entries, and implies static IP-address configuration of those hosts. It does not support DHCP configuration of hosts connected to the secondary interface.
Use of dhcprelay from BusyBox, or dhcp-helper could be part of the story except that they cannot see the traffic and/or identify from which interface the traffic is coming once the interfaces have been added to the bridge, which is essential for their operation and is the source of my question at the top.
In addition to relaying DHCP requests I want to be able to monitor that traffic and ARP traffic to use it to manage automated addition and removal of the ebtables entries, and use synthetic ARP traffic as a keep-alive mechanism.