]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
meta: introduce meta ibrhwaddr support
authorFernando Fernandez Mancera <fmancera@suse.de>
Tue, 14 Oct 2025 12:20:42 +0000 (14:20 +0200)
committerFlorian Westphal <fw@strlen.de>
Tue, 14 Oct 2025 16:30:57 +0000 (18:30 +0200)
Can be used in bridge prerouting hook to redirect the packet to the
receiving physical device for processing.

table bridge nat {
        chain PREROUTING {
                type filter hook prerouting priority 0; policy accept;
                ether daddr de:ad:00:00:be:ef meta pkttype set host ether daddr set meta ibrhwaddr accept
        }
}

Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
include/linux/netfilter/nf_tables.h
src/meta.c
tests/py/bridge/meta.t
tests/py/bridge/pass_up.t [new file with mode: 0644]
tests/py/bridge/pass_up.t.json [new file with mode: 0644]
tests/py/bridge/pass_up.t.payload [new file with mode: 0644]

index b38d4780ae8c84e1897f399d06a78cc83b86989d..45d0b92b9e837ec61ddcb527b78a2d48be729e0c 100644 (file)
@@ -949,6 +949,7 @@ enum nft_exthdr_attributes {
  * @NFT_META_SDIF: slave device interface index
  * @NFT_META_SDIFNAME: slave device interface name
  * @NFT_META_BRI_BROUTE: packet br_netfilter_broute bit
+ * @NFT_META_BRI_IIFHWADDR: packet input bridge interface ethernet address
  */
 enum nft_meta_keys {
        NFT_META_LEN,
@@ -989,6 +990,7 @@ enum nft_meta_keys {
        NFT_META_SDIFNAME,
        NFT_META_BRI_BROUTE,
        __NFT_META_IIFTYPE,
+       NFT_META_BRI_IIFHWADDR,
 };
 
 /**
index 1010209d3152526afa529a1ce818e81ca2ccfbf4..c36486029cca8cd505c2fcb55022a1032c106277 100644 (file)
@@ -23,6 +23,7 @@
 #include <arpa/inet.h>
 #include <linux/netfilter.h>
 #include <linux/pkt_sched.h>
+#include <linux/if_ether.h>
 #include <linux/if_packet.h>
 #include <time.h>
 
@@ -704,6 +705,9 @@ const struct meta_template meta_templates[] = {
                                                BYTEORDER_HOST_ENDIAN),
        [NFT_META_BRI_BROUTE]   = META_TEMPLATE("broute",   &integer_type,
                                                1    , BYTEORDER_HOST_ENDIAN),
+       [NFT_META_BRI_IIFHWADDR] = META_TEMPLATE("ibrhwaddr", &etheraddr_type,
+                                                ETH_ALEN * BITS_PER_BYTE,
+                                                BYTEORDER_BIG_ENDIAN),
 };
 
 static bool meta_key_is_unqualified(enum nft_meta_keys key)
index 171aa610204e4fcf8af33132c333ca41cc35bfdc..1e312a274828a7ba49d443a14bc42dc247fabc6c 100644 (file)
@@ -11,3 +11,4 @@ meta protocol ip udp dport 67;ok
 meta protocol ip6 udp dport 67;ok
 
 meta broute set 1;fail
+meta ibrhwaddr;fail
diff --git a/tests/py/bridge/pass_up.t b/tests/py/bridge/pass_up.t
new file mode 100644 (file)
index 0000000..642fbaf
--- /dev/null
@@ -0,0 +1,6 @@
+:prerouting;type filter hook prerouting priority 0
+
+*bridge;test-bridge;prerouting
+
+ether daddr set meta ibrhwaddr;ok
+meta ibrhwaddr set 00:1a:2b:3c:4d:5e;fail
diff --git a/tests/py/bridge/pass_up.t.json b/tests/py/bridge/pass_up.t.json
new file mode 100644 (file)
index 0000000..7d6a30b
--- /dev/null
@@ -0,0 +1,19 @@
+# ether daddr set meta ibrhwaddr
+[
+    {
+        "mangle": {
+            "key": {
+                "payload": {
+                    "field": "daddr",
+                    "protocol": "ether"
+                }
+            },
+            "value": {
+                "meta": {
+                    "key": "ibrhwaddr"
+                }
+            }
+        }
+    }
+]
+
diff --git a/tests/py/bridge/pass_up.t.payload b/tests/py/bridge/pass_up.t.payload
new file mode 100644 (file)
index 0000000..d76c6b9
--- /dev/null
@@ -0,0 +1,4 @@
+# ether daddr set meta ibrhwaddr
+bridge test-bridge prerouting
+  [ meta load ibrhwaddr => reg 1 ]
+  [ payload write reg 1 => 6b @ link header + 0 csum_type 0 csum_off 0 csum_flags 0x0 ]