Ebtables to nftables migration for L2 NAT

Greetings OpenWRT community,

In this opportunity I want the share the issue I am currently facing by trying to port some ebtables rules to the current way to achieve the same, which is using nftables.

Years ago I solved this issue by using ebtables. Now I tested the following rules in nftables:

table bridge filter {
        chain forward {
                ether type 0x893a iifname "lan1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:88
                ether type 0x893a iifname "lan2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:89
                ether type 0x893a iifname "lan3" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8a
                ether type 0x893a iifname "lan4" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8b
                ether type 0x893a iifname "wan" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8c
                ether type 0x893a iifname "bss0" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:85
                ether type 0x893a iifname "bss1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:86
                ether type 0x893a iifname "bss2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:87
                ether type 0x893a iifname "p-1905" accept
                ether type 0x893a oifname != "p-1905" ether daddr 01:80:c2:00:00:13 drop
        }
}

In this case, the first 8 rules are intended to change the source mac address of the ethernet frames which its protocol is "0x893a" and the destination address is "01:80:c2:00:00:13". The new source is the mac address of each interface, this of course is generated dinamically by an application.

The 9th rule accepts all 0x893a frames from an specific interface("p-1905", of a veth pair) and the 10th discards all the 0x893a frames to "01:80:c2:00:00:13" which are not destinated to that interface.

None of the rules are working, no frames are filtered, no src mac values ​​are changed. Even the basic instruction of discarding all frames of an ethertype does not work.


table bridge filter {
        chain forward {
                ether type 0x893a drop
        }
}

It's like it doesn't work at all.

I included all the rules into the same chain because with nftables the table and chain names seems to be just for organization and do not involve functionality. Anyway I tested it in other ways like:

table bridge filter {
        chain forward {
                ether type 0x893a iifname "p-1905" accept
                ether type 0x893a oifname != "p-1905" ether daddr 01:80:c2:00:00:13 drop
        }

        chain postrouting {
                ether type 0x893a iifname "lan1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:88
                ether type 0x893a iifname "lan2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:89
                ether type 0x893a iifname "lan3" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8a
                ether type 0x893a iifname "lan4" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8b
                ether type 0x893a iifname "wan" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8c
                ether type 0x893a iifname "bss0" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:85
                ether type 0x893a iifname "bss1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:86
                ether type 0x893a iifname "bss2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:87
        }
}

Or

table bridge filter {
        chain forward {
                ether type 0x893a iifname "p-1905" accept
                ether type 0x893a oifname != "p-1905" ether daddr 01:80:c2:00:00:13 drop
        }

table bridge nat       
        chain postrouting {
                ether type 0x893a iifname "lan1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:88
                ether type 0x893a iifname "lan2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:89
                ether type 0x893a iifname "lan3" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8a
                ether type 0x893a iifname "lan4" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8b
                ether type 0x893a iifname "wan" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8c
                ether type 0x893a iifname "bss0" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:85
                ether type 0x893a iifname "bss1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:86
                ether type 0x893a iifname "bss2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:87
        }
}

All with the same results.

Any clue about this will be priceless.

Best regards.

I think what you are missing is the netfilter hook.

For example:

table bridge filter {
        chain forward {
                type filter hook forward priority 0; policy accept; 
                ether type 0x893a iifname "p-1905" accept
                ether type 0x893a oifname != "p-1905" ether daddr 01:80:c2:00:00:13 drop
        }

        chain postrouting {
                type filter hook postrouting priority 0; policy accept; 
                ether type 0x893a iifname "lan1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:88
                ether type 0x893a iifname "lan2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:89
                ether type 0x893a iifname "lan3" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8a
                ether type 0x893a iifname "lan4" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8b
                ether type 0x893a iifname "wan" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8c
                ether type 0x893a iifname "bss0" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:85
                ether type 0x893a iifname "bss1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:86
                ether type 0x893a iifname "bss2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:87
        }
}

(change priorities and default policies as you need them)

https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks

BTW with nftables, chain names do not determine the netfilter hook and have no practical bearing on the rules or how they are processed, so you can call the chains as you like.

3 Likes

You not only gave me the solution, you also gave me a clear explanation and cited the correct source which explains in detail the reason.

I decided to solve all in the same chain, with ebtables I used two chains because only in nat/postrouting I was able to edit de src MAC. Now with this method of a pointer like to hooks all the rules will work OK aimed to forward hook.

table bridge filter {
        chain forward {
                type filter hook forward priority 0; policy accept;
                ether type 0x893a iifname "lan1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:88
                ether type 0x893a iifname "lan2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:89
                ether type 0x893a iifname "lan3" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8a
                ether type 0x893a iifname "lan4" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8b
                ether type 0x893a iifname "wan" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:8c
                ether type 0x893a iifname "bss0" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:85
                ether type 0x893a iifname "bss1" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:86
                ether type 0x893a iifname "bss2" ether daddr 01:80:c2:00:00:13 ether saddr set 54:af:97:c5:c0:87
                ether type 0x893a iifname "p-1905" accept
                ether type 0x893a oifname != "p-1905" ether daddr 01:80:c2:00:00:13 drop
        }
}

Solved.

Thank you very much.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.