skip to Main Content

I have basic knowledge in nftables syntax and I am trying to drop all arp traffic that occurs on a Linux bridge.

I am running debian and have several virtual machines which are all connected to one bridge. For a project I need to prevent any kind of ARP traffic but only on this bridge.

I tried something like

table bridge bridge_filter {
        chain forward {
                type filter hook forward priority 0;
                policy accept;

                iifname "tap2*" ether type arp drop;
                oifname "tap2*" ether type arp drop;

                iifname "vmbr1" ether type arp drop;
        }
}

(the virtual machines are automatically connected to the bridge with "tap2*" tap devices")
but it doesn’t work very well, at least I can still see ARP packets on each virtual machines with tcpdump, both request and reply. I know that the config above may not make sense completely but I couldn’t figure out what’s the right way.

What is wrong with my config?

2

Answers


  1. Chosen as BEST ANSWER

    The goal was just to block all ARP traffic between several nodes in a network. This was an environment used for educational purposes where students should explore routing. There were three virtual machines in a network. Two of them should not be allowed to exchange ARP messages, the third one should be the middleman. Therefore, I justed wanted to block ARP traffic between two specified nodes.

    I ended up with the following statements for each network:

    iifname "tap201i0" oifname "tap203i0" ether type arp drop;
    iifname "tap201i0" oifname "tap203i0" ip daddr 172.30.1.255 drop;
    iifname "tap203i0" oifname "tap201i0" ether type arp drop;
    iifname "tap203i0" oifname "tap201i0" ip daddr 172.30.1.255 drop;
    

    (tap interfaces belong to virtual machines, 172.30.1.0/24 consists of nodes A, B and C) With these statements I achieved what I wanted. The nodes A and C are not able to communicate via ARP (and broadcast IP) with each other. Therefore they require node B to work as router, which still can communicate with A and B.

    The previous answer is what I wanted, I just wanted to show my final solution in case someone has the same goal.


  2. I’m not sure if you need to filter ARP traffic between just the VMs or also between the host and the VMs.

    If it’s the latter then ARP traffic between the host and the VMs won’t be filtered when using the "bridge forward" hook.

    In order to filter unicast ARP traffic between the VMs and the host I think you’ll need to also use a chain with the bridge "prerouting" and "postrouting" hooks.

    For example

    table bridge bridge_prerouting_filter {
            chain prerouting {
                    type filter hook prerouting priority 0; policy accept;
                    iifname "tap2*" ether type arp drop;
            }
    }
    
    table bridge bridge_postrouting_filter {
            chain postrouting {
                    type filter hook postrouting priority 0; policy accept;
                    oifname "tap2*" ether type arp drop;
            }
    }
    

    In regards to broadcast ARP traffic, that is going to be harder to selectively filter. I don’t know if the "oifname" parameter can be applied to broadcast traffic because the output interface is all interfaces.

    Filtering broadcast ARP traffic is going to be easier on the input side but it’s going to be difficult to differentiate between broadcast ARP traffic that’s allowed and ARP traffic that’s not. There was supposed to be a new netdev "egress" filter in Linux 5.7 that might have been able to be used for this purpose but I think it’s been removed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search