diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index c53d581643fe..87474920615a 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 2ea8acb4bc4a..9487d42f657a 100644 --- a/net/bridge/netfilter/nft_meta_bridge.c +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -7,6 +7,7 @@ #include #include #include +#include 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); }