From: wenxu <wenxu@xxxxxxxxx> nft add table bridge firewall nft add chain bridge firewall zones { type filter hook prerouting priority - 300 \; } nft add rule bridge firewall zones counter ct zone set vlan id map { 100 : 1, 200 : 2 } As above set the bridge port with pvid, the received packet don't contain the vlan tag which means the packet should belong to vlan 200 through pvid. With this pacth user can get the pvid of bridge ports. So add the following rule for as the first rule in the chain of zones. nft add rule bridge firewall zones counter meta vlan set meta briifpvid Signed-off-by: wenxu <wenxu@xxxxxxxxx> --- include/uapi/linux/netfilter/nf_tables.h | 2 ++ net/bridge/netfilter/nft_meta_bridge.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index c6c8ec5..8a1bd0b 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -795,6 +795,7 @@ enum nft_exthdr_attributes { * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp) * @NFT_META_IIFKIND: packet input interface kind name (dev->rtnl_link_ops->kind) * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind) + * @NFT_META_BRI_IIFPVID: packet input bridge port pvid */ enum nft_meta_keys { NFT_META_LEN, @@ -825,6 +826,7 @@ enum nft_meta_keys { NFT_META_SECPATH, NFT_META_IIFKIND, NFT_META_OIFKIND, + NFT_META_BRI_IIFPVID, }; /** diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c index 2ea8acb..9487d42 100644 --- a/net/bridge/netfilter/nft_meta_bridge.c +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -7,6 +7,7 @@ #include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> #include <net/netfilter/nft_meta.h> +#include <linux/if_bridge.h> static const struct net_device * nft_meta_get_bridge(const struct net_device *dev) @@ -37,6 +38,17 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr, if (!br_dev) goto err; break; + case NFT_META_BRI_IIFPVID: { + u16 p_pvid; + + br_dev = nft_meta_get_bridge(in); + if (!br_dev || !br_vlan_enabled(br_dev)) + goto err; + + br_vlan_get_pvid_rcu(in, &p_pvid); + nft_reg_store16(dest, p_pvid); + return; + } default: goto out; } @@ -62,6 +74,9 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, case NFT_META_BRI_OIFNAME: len = IFNAMSIZ; break; + case NFT_META_BRI_IIFPVID: + len = sizeof(u16); + break; default: return nft_meta_get_init(ctx, expr, tb); } -- 1.8.3.1