On Thu, Jul 17, 2025 at 04:27:37PM +0800, Miao Wang via B4 Relay wrote: > From: Miao Wang <shankerwangmiao@xxxxxxxxx> > > The redirect target in ebtables do two things: 1. set skb->pkt_type to > PACKET_HOST, and 2. set the destination mac address to the address of > the receiving bridge device (when not used in BROUTING chain), or the > receiving physical device (otherwise). However, the later cannot be > implemented in nftables not given the translated mac address. So it is > not appropriate to give a specious translation. It should be possible to expose the bridge port device address through this extension, see (untested) patch. Then, it should be possible to provide this translation: ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef \ counter meta pkttype set host ether daddr set meta ibrhwdr accept'
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 2beb30be2c5f..a0d9daa05a8f 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -959,6 +959,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, @@ -999,6 +1000,7 @@ enum nft_meta_keys { NFT_META_SDIFNAME, NFT_META_BRI_BROUTE, __NFT_META_IIFTYPE, + NFT_META_BRI_IIFHWADDR, }; /** diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c index 5adced1e7d0c..d1ae1a2a59f5 100644 --- a/net/bridge/netfilter/nft_meta_bridge.c +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -59,6 +59,13 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr, nft_reg_store_be16(dest, htons(p_proto)); return; } + case NFT_META_BRI_IIFHWADDR: + br_dev = nft_meta_get_bridge(in); + if (!br_dev) + goto err; + + memcpy(dest, br_dev->dev_addr, ETH_ALEN); + return; default: return nft_meta_get_eval(expr, regs, pkt); } @@ -86,6 +93,9 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, case NFT_META_BRI_IIFVPROTO: len = sizeof(u16); break; + case NFT_META_BRI_IIFHWADDR: + len = ETH_ALEN; + break; default: return nft_meta_get_init(ctx, expr, tb); }