How block multicast to specific bridge port

np! :slight_smile:


Tried and failed to get tc to block forwarded multicast traffic on a bridge. Two changes were necessary to make this work:

  1. Disable the hardware switch by putting each port on its own vlan (otherwise the Linux kernel never sees the traffic being forwarded!)

  2. Ditch tc for ebtables.
    I couldn't find any way to make tc match on multicast packets. However, ebtables makes it easy:

#  ebtables -A FORWARD -o eth0.1 --pkttype-type multicast -j DROP
#  ebtables -A FORWARD -o eth0.3 --pkttype-type multicast -j DROP

Prevents forwarding multicast traffic between eth0.1 and eth0.3. One rule would do, but combination of the two allow for connecting either physical port to the multicast noise source.

1 Like

This is working on an GliNet AR-750S running OpenWRT 23.05.5
Believe it or not, the little AR-750S seems to incorporate a 3 port hardware network switch.
This is probably to get wire speed on a 1Gb network. Defeating the switch likely slows throughput markedly, but that's acceptable for my application.

Sweet !

Another option might have been to get a device with 2 or more ports, put it on the wire between topside and vehicle, set it to bridge mode, and see if the nftables netdev ingress rules work as they are supposed to. :slight_smile:

That is exactly how we intend to use this AR-750S router. It will be inserted between the topside and the vehicle. I did try tc ingress filtering, which is supposedly using the same hook as nft netdev ingress filtering. It didn't work. Couldn't seem to get the match on multicast packets to trigger properly.

Hah! :slight_smile:

Hmm the mainboard photo on the AR-750S wiki page is not very good.

But the SoC is listed as a QCA956X so I guess it wouldn't be too far-fetched to think that perhaps there is a QCA8K ethernet switch in there.

In case there is, looks like the QCA8K is supported by DSA:
https://github.com/torvalds/linux/blob/master/drivers/net/dsa/qca/Kconfig

Which means that eth0 could be a DSA master, and the user network interfaces are actually called fx. lan1.

(And there wouldn't be any ingress traffic on eth0, it's all snatched by the DSA framework when active.)

Could it perhaps be non-working because the qdisc+filter was attached to eth0 (DSA master) rather than the proper lanX interface?

Just a wild guess

I could keep pings from forwarding with tc if I separated the vlans (to avoid DSA snatching the traffic), but I couldn't get a match on the multicast traffic. Must be something amiss with the filter match expression.
Anyway, why would tc be better than ebtables?
tc just introduces another queue and traffic shaping that I'm really not using.

It's not !

ebtables is a perfect solution to the problem :slight_smile:

I was just wondering aloud

Tested to be working on my laptop after changing the qdisc. I take out the udp part cause it's ping/icmp.

$ ping 224.0.0.1 &
$ sudo tc qdisc add dev eth0 root handle 1: pfifo
$ sudo tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 224.0.0.0/20 action drop
Error: Qdisc not classful.
$ sudo tc qdisc delete dev eth0 root handle 1:
$ sudo tc qdisc add dev eth0 root handle 1: prio
$ sudo tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 224.0.0.0/20 action drop

It may be the the udp part of the match was incorrectly formulated. I didn't try omitting it.

In any case, I find the ebtables rules more intuitive.
I'm using ebtables-nft, so the rules get translated into nft bridge rules which are displayed on luci's firewall status page. Whereas tc would give no gui feedback.

1 Like