2

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).

Update

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.

Background

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.

| improve this question | | | | |
  • What program or protocol needs this distinction? I can see it being useful for things like LLDP or STP, but not really for anything IP-based... – user1686 Jun 4 '19 at 16:36
  • Are you using IP raw sockets (af_inet/sock_raw) or Ethernet raw sockets (af_packet) in your program? I'm fairly sure existing tools such as lldpd or mstpd are able to somehow send and receive packets over individual bridge ports, but I strongly suspect they have to bypass IP to do so. (Well, besides the fact that they're working with non-IP protocols in the first place...) – user1686 Jun 5 '19 at 12:42
  • I'm using AF_PACKET, SOCK_RAW which, as far as I can tell from a quick look at the code, is also what lldpd uses, although it may also put the interface in promiscuous mode. – awy Jun 5 '19 at 14:39
  • eep. So something almost like superuser.com/questions/1409745/… but you want to listen to one of the other interfaces rather than br0? – Journeyman Geek Jun 6 '19 at 14:00
  • yes, that's basically it – awy Jun 6 '19 at 15:50
0

A option may be to use libpcap with an instance per interface of interest. It looks like pcap can see the packets on interfaces that have been added to a bridge. I have gone with this approach for the present. I doubt that the expense of the packet filter will be significant.

But I admit that I do not understand how libpcap sees the packets at the slave interface level. It also, as far as I understand, uses AF_PACKET, SOCK_RAW. Maybe there is something related to its use of PACKET_MMAP. I have tried fiddling around with things like the presenace or absence of socket filter programs without getting anywhere.

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.