netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge
@ 2019-07-05 13:16 wenxu
  2019-07-05 13:16 ` [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header wenxu
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: wenxu <wenxu@ucloud.cn>

Separate bridge meta key from nft_meta to meta_bridge for other key
support. So there is n dependency between nft_meta and the bridge
module

Signed-off-by: wenxu <wenxu@ucloud.cn>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 include/net/netfilter/nft_meta.h       |  44 ++++++++++++
 net/bridge/netfilter/Kconfig           |   6 ++
 net/bridge/netfilter/Makefile          |   1 +
 net/bridge/netfilter/nft_meta_bridge.c | 127 +++++++++++++++++++++++++++++++++
 net/netfilter/nf_tables_core.c         |   1 +
 net/netfilter/nft_meta.c               |  81 ++++++++-------------
 6 files changed, 207 insertions(+), 53 deletions(-)
 create mode 100644 include/net/netfilter/nft_meta.h
 create mode 100644 net/bridge/netfilter/nft_meta_bridge.c

diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
new file mode 100644
index 0000000..5c69e9b
--- /dev/null
+++ b/include/net/netfilter/nft_meta.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _NFT_META_H_
+#define _NFT_META_H_
+
+struct nft_meta {
+	enum nft_meta_keys	key:8;
+	union {
+		enum nft_registers	dreg:8;
+		enum nft_registers	sreg:8;
+	};
+};
+
+extern const struct nla_policy nft_meta_policy[];
+
+int nft_meta_get_init(const struct nft_ctx *ctx,
+		      const struct nft_expr *expr,
+		      const struct nlattr * const tb[]);
+
+int nft_meta_set_init(const struct nft_ctx *ctx,
+		      const struct nft_expr *expr,
+		      const struct nlattr * const tb[]);
+
+int nft_meta_get_dump(struct sk_buff *skb,
+		      const struct nft_expr *expr);
+
+int nft_meta_set_dump(struct sk_buff *skb,
+		      const struct nft_expr *expr);
+
+void nft_meta_get_eval(const struct nft_expr *expr,
+		       struct nft_regs *regs,
+		       const struct nft_pktinfo *pkt);
+
+void nft_meta_set_eval(const struct nft_expr *expr,
+		       struct nft_regs *regs,
+		       const struct nft_pktinfo *pkt);
+
+void nft_meta_set_destroy(const struct nft_ctx *ctx,
+			  const struct nft_expr *expr);
+
+int nft_meta_set_validate(const struct nft_ctx *ctx,
+			  const struct nft_expr *expr,
+			  const struct nft_data **data);
+
+#endif
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index f4fb0b9..fbc7085 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -9,6 +9,12 @@ menuconfig NF_TABLES_BRIDGE
 	bool "Ethernet Bridge nf_tables support"
 
 if NF_TABLES_BRIDGE
+
+config NFT_BRIDGE_META
+	tristate "Netfilter nf_table bridge meta support"
+	help
+	  Add support for bridge dedicated meta key.
+
 config NFT_BRIDGE_REJECT
 	tristate "Netfilter nf_tables bridge reject support"
 	depends on NFT_REJECT && NFT_REJECT_IPV4 && NFT_REJECT_IPV6
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 9d77673..8e2c575 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -3,6 +3,7 @@
 # Makefile for the netfilter modules for Link Layer filtering on a bridge.
 #
 
+obj-$(CONFIG_NFT_BRIDGE_META)  += nft_meta_bridge.o
 obj-$(CONFIG_NFT_BRIDGE_REJECT)  += nft_reject_bridge.o
 
 # connection tracking
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
new file mode 100644
index 0000000..dde8651
--- /dev/null
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nft_meta.h>
+
+#include "../br_private.h"
+
+static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
+				     struct nft_regs *regs,
+				     const struct nft_pktinfo *pkt)
+{
+	const struct nft_meta *priv = nft_expr_priv(expr);
+	const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
+	u32 *dest = &regs->data[priv->dreg];
+	const struct net_bridge_port *p;
+
+	switch (priv->key) {
+	case NFT_META_BRI_IIFNAME:
+		if (in == NULL || (p = br_port_get_rcu(in)) == NULL)
+			goto err;
+		break;
+	case NFT_META_BRI_OIFNAME:
+		if (out == NULL || (p = br_port_get_rcu(out)) == NULL)
+			goto err;
+		break;
+	default:
+		goto out;
+	}
+
+	strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
+	return;
+out:
+	return nft_meta_get_eval(expr, regs, pkt);
+err:
+	regs->verdict.code = NFT_BREAK;
+}
+
+static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
+				    const struct nft_expr *expr,
+				    const struct nlattr * const tb[])
+{
+	struct nft_meta *priv = nft_expr_priv(expr);
+	unsigned int len;
+
+	priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
+	switch (priv->key) {
+	case NFT_META_BRI_IIFNAME:
+	case NFT_META_BRI_OIFNAME:
+		len = IFNAMSIZ;
+		break;
+	default:
+		return nft_meta_get_init(ctx, expr, tb);
+	}
+
+	priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
+	return nft_validate_register_store(ctx, priv->dreg, NULL,
+					   NFT_DATA_VALUE, len);
+}
+
+static struct nft_expr_type nft_meta_bridge_type;
+static const struct nft_expr_ops nft_meta_bridge_get_ops = {
+	.type		= &nft_meta_bridge_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_meta)),
+	.eval		= nft_meta_bridge_get_eval,
+	.init		= nft_meta_bridge_get_init,
+	.dump		= nft_meta_get_dump,
+};
+
+static const struct nft_expr_ops nft_meta_bridge_set_ops = {
+	.type		= &nft_meta_bridge_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_meta)),
+	.eval		= nft_meta_set_eval,
+	.init		= nft_meta_set_init,
+	.destroy	= nft_meta_set_destroy,
+	.dump		= nft_meta_set_dump,
+	.validate	= nft_meta_set_validate,
+};
+
+static const struct nft_expr_ops *
+nft_meta_bridge_select_ops(const struct nft_ctx *ctx,
+			   const struct nlattr * const tb[])
+{
+	if (tb[NFTA_META_KEY] == NULL)
+		return ERR_PTR(-EINVAL);
+
+	if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG])
+		return ERR_PTR(-EINVAL);
+
+	if (tb[NFTA_META_DREG])
+		return &nft_meta_bridge_get_ops;
+
+	if (tb[NFTA_META_SREG])
+		return &nft_meta_bridge_set_ops;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static struct nft_expr_type nft_meta_bridge_type __read_mostly = {
+	.family         = NFPROTO_BRIDGE,
+	.name           = "meta",
+	.select_ops     = nft_meta_bridge_select_ops,
+	.policy         = nft_meta_policy,
+	.maxattr        = NFTA_META_MAX,
+	.owner          = THIS_MODULE,
+};
+
+static int __init nft_meta_bridge_module_init(void)
+{
+	return nft_register_expr(&nft_meta_bridge_type);
+}
+
+static void __exit nft_meta_bridge_module_exit(void)
+{
+	nft_unregister_expr(&nft_meta_bridge_type);
+}
+
+module_init(nft_meta_bridge_module_init);
+module_exit(nft_meta_bridge_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("wenxu <wenxu@ucloud.cn>");
+MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "meta");
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index b950cd3..96c74c4 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -19,6 +19,7 @@
 #include <net/netfilter/nf_tables_core.h>
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_log.h>
+#include <net/netfilter/nft_meta.h>
 
 static noinline void __nft_trace_packet(struct nft_traceinfo *info,
 					const struct nft_chain *chain,
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index a54329b863..18a848b 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -21,23 +21,12 @@
 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
+#include <net/netfilter/nft_meta.h>
 
 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
 
-struct nft_meta {
-	enum nft_meta_keys	key:8;
-	union {
-		enum nft_registers	dreg:8;
-		enum nft_registers	sreg:8;
-	};
-};
-
 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
 
-#ifdef CONFIG_NF_TABLES_BRIDGE
-#include "../bridge/br_private.h"
-#endif
-
 void nft_meta_get_eval(const struct nft_expr *expr,
 		       struct nft_regs *regs,
 		       const struct nft_pktinfo *pkt)
@@ -47,9 +36,6 @@ void nft_meta_get_eval(const struct nft_expr *expr,
 	const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
 	struct sock *sk;
 	u32 *dest = &regs->data[priv->dreg];
-#ifdef CONFIG_NF_TABLES_BRIDGE
-	const struct net_bridge_port *p;
-#endif
 
 	switch (priv->key) {
 	case NFT_META_LEN:
@@ -229,18 +215,6 @@ void nft_meta_get_eval(const struct nft_expr *expr,
 		nft_reg_store8(dest, secpath_exists(skb));
 		break;
 #endif
-#ifdef CONFIG_NF_TABLES_BRIDGE
-	case NFT_META_BRI_IIFNAME:
-		if (in == NULL || (p = br_port_get_rcu(in)) == NULL)
-			goto err;
-		strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
-		return;
-	case NFT_META_BRI_OIFNAME:
-		if (out == NULL || (p = br_port_get_rcu(out)) == NULL)
-			goto err;
-		strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
-		return;
-#endif
 	case NFT_META_IIFKIND:
 		if (in == NULL || in->rtnl_link_ops == NULL)
 			goto err;
@@ -260,10 +234,11 @@ void nft_meta_get_eval(const struct nft_expr *expr,
 err:
 	regs->verdict.code = NFT_BREAK;
 }
+EXPORT_SYMBOL_GPL(nft_meta_get_eval);
 
-static void nft_meta_set_eval(const struct nft_expr *expr,
-			      struct nft_regs *regs,
-			       const struct nft_pktinfo *pkt)
+void nft_meta_set_eval(const struct nft_expr *expr,
+		       struct nft_regs *regs,
+		       const struct nft_pktinfo *pkt)
 {
 	const struct nft_meta *meta = nft_expr_priv(expr);
 	struct sk_buff *skb = pkt->skb;
@@ -300,16 +275,18 @@ static void nft_meta_set_eval(const struct nft_expr *expr,
 		WARN_ON(1);
 	}
 }
+EXPORT_SYMBOL_GPL(nft_meta_set_eval);
 
-static const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
+const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
 	[NFTA_META_DREG]	= { .type = NLA_U32 },
 	[NFTA_META_KEY]		= { .type = NLA_U32 },
 	[NFTA_META_SREG]	= { .type = NLA_U32 },
 };
+EXPORT_SYMBOL_GPL(nft_meta_policy);
 
-static int nft_meta_get_init(const struct nft_ctx *ctx,
-			     const struct nft_expr *expr,
-			     const struct nlattr * const tb[])
+int nft_meta_get_init(const struct nft_ctx *ctx,
+		      const struct nft_expr *expr,
+		      const struct nlattr * const tb[])
 {
 	struct nft_meta *priv = nft_expr_priv(expr);
 	unsigned int len;
@@ -360,14 +337,6 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,
 		len = sizeof(u8);
 		break;
 #endif
-#ifdef CONFIG_NF_TABLES_BRIDGE
-	case NFT_META_BRI_IIFNAME:
-	case NFT_META_BRI_OIFNAME:
-		if (ctx->family != NFPROTO_BRIDGE)
-			return -EOPNOTSUPP;
-		len = IFNAMSIZ;
-		break;
-#endif
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -376,6 +345,7 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,
 	return nft_validate_register_store(ctx, priv->dreg, NULL,
 					   NFT_DATA_VALUE, len);
 }
+EXPORT_SYMBOL_GPL(nft_meta_get_init);
 
 static int nft_meta_get_validate(const struct nft_ctx *ctx,
 				 const struct nft_expr *expr,
@@ -409,9 +379,9 @@ static int nft_meta_get_validate(const struct nft_ctx *ctx,
 #endif
 }
 
-static int nft_meta_set_validate(const struct nft_ctx *ctx,
-				 const struct nft_expr *expr,
-				 const struct nft_data **data)
+int nft_meta_set_validate(const struct nft_ctx *ctx,
+			  const struct nft_expr *expr,
+			  const struct nft_data **data)
 {
 	struct nft_meta *priv = nft_expr_priv(expr);
 	unsigned int hooks;
@@ -437,10 +407,11 @@ static int nft_meta_set_validate(const struct nft_ctx *ctx,
 
 	return nft_chain_validate_hooks(ctx->chain, hooks);
 }
+EXPORT_SYMBOL_GPL(nft_meta_set_validate);
 
-static int nft_meta_set_init(const struct nft_ctx *ctx,
-			     const struct nft_expr *expr,
-			     const struct nlattr * const tb[])
+int nft_meta_set_init(const struct nft_ctx *ctx,
+		      const struct nft_expr *expr,
+		      const struct nlattr * const tb[])
 {
 	struct nft_meta *priv = nft_expr_priv(expr);
 	unsigned int len;
@@ -475,9 +446,10 @@ static int nft_meta_set_init(const struct nft_ctx *ctx,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(nft_meta_set_init);
 
-static int nft_meta_get_dump(struct sk_buff *skb,
-			     const struct nft_expr *expr)
+int nft_meta_get_dump(struct sk_buff *skb,
+		      const struct nft_expr *expr)
 {
 	const struct nft_meta *priv = nft_expr_priv(expr);
 
@@ -490,8 +462,9 @@ static int nft_meta_get_dump(struct sk_buff *skb,
 nla_put_failure:
 	return -1;
 }
+EXPORT_SYMBOL_GPL(nft_meta_get_dump);
 
-static int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
+int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
 {
 	const struct nft_meta *priv = nft_expr_priv(expr);
 
@@ -505,15 +478,17 @@ static int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
 nla_put_failure:
 	return -1;
 }
+EXPORT_SYMBOL_GPL(nft_meta_set_dump);
 
-static void nft_meta_set_destroy(const struct nft_ctx *ctx,
-				 const struct nft_expr *expr)
+void nft_meta_set_destroy(const struct nft_ctx *ctx,
+			  const struct nft_expr *expr)
 {
 	const struct nft_meta *priv = nft_expr_priv(expr);
 
 	if (priv->key == NFT_META_NFTRACE)
 		static_branch_dec(&nft_trace_enabled);
 }
+EXPORT_SYMBOL_GPL(nft_meta_set_destroy);
 
 static const struct nft_expr_ops nft_meta_get_ops = {
 	.type		= &nft_meta_type,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
@ 2019-07-05 13:16 ` wenxu
  2019-07-05 20:45   ` Pablo Neira Ayuso
  2019-07-05 13:16 ` [PATCH 3/7 nf-next v2] bridge: add br_vlan_get_pvid_rcu() wenxu
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: wenxu <wenxu@ucloud.cn>

Mkae the nft_bridge_meta can't direct access the bridge
internal API.

Signed-off-by: wenxu <wenxu@ucloud.cn>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 net/bridge/netfilter/nft_meta_bridge.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index dde8651..2ea8acb 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -8,7 +8,14 @@
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nft_meta.h>
 
-#include "../br_private.h"
+static const struct net_device *
+nft_meta_get_bridge(const struct net_device *dev)
+{
+	if (dev && netif_is_bridge_port(dev))
+		return netdev_master_upper_dev_get_rcu((struct net_device *)dev);
+
+	return NULL;
+}
 
 static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
 				     struct nft_regs *regs,
@@ -17,22 +24,24 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
 	const struct nft_meta *priv = nft_expr_priv(expr);
 	const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
 	u32 *dest = &regs->data[priv->dreg];
-	const struct net_bridge_port *p;
+	const struct net_device *br_dev;
 
 	switch (priv->key) {
 	case NFT_META_BRI_IIFNAME:
-		if (in == NULL || (p = br_port_get_rcu(in)) == NULL)
+		br_dev = nft_meta_get_bridge(in);
+		if (!br_dev)
 			goto err;
 		break;
 	case NFT_META_BRI_OIFNAME:
-		if (out == NULL || (p = br_port_get_rcu(out)) == NULL)
+		br_dev = nft_meta_get_bridge(out);
+		if (!br_dev)
 			goto err;
 		break;
 	default:
 		goto out;
 	}
 
-	strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
+	strncpy((char *)dest, br_dev->name, IFNAMSIZ);
 	return;
 out:
 	return nft_meta_get_eval(expr, regs, pkt);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/7 nf-next v2] bridge: add br_vlan_get_pvid_rcu()
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
  2019-07-05 13:16 ` [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header wenxu
@ 2019-07-05 13:16 ` wenxu
  2019-07-05 20:45   ` Pablo Neira Ayuso
  2019-07-05 13:16 ` [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support wenxu
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: Pablo Neira Ayuso <pablo@netfilter.org>

This new function allows you to fetch bridge pvid from packet path.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 include/linux/if_bridge.h |  6 ++++++
 net/bridge/br_vlan.c      | 19 +++++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index f3fab5d0ea97..950db1dad830 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -88,6 +88,7 @@ static inline bool br_multicast_router(const struct net_device *dev)
 #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING)
 bool br_vlan_enabled(const struct net_device *dev);
 int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid);
+int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid);
 int br_vlan_get_info(const struct net_device *dev, u16 vid,
 		     struct bridge_vlan_info *p_vinfo);
 #else
@@ -101,6 +102,11 @@ static inline int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
 	return -EINVAL;
 }
 
+static inline int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid)
+{
+	return -EINVAL;
+}
+
 static inline int br_vlan_get_info(const struct net_device *dev, u16 vid,
 				   struct bridge_vlan_info *p_vinfo)
 {
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index f47f526b4f19..8d97b91ad503 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1227,13 +1227,11 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
 	}
 }
 
-int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
+static int __br_vlan_get_pvid(const struct net_device *dev,
+			      struct net_bridge_port *p, u16 *p_pvid)
 {
 	struct net_bridge_vlan_group *vg;
-	struct net_bridge_port *p;
 
-	ASSERT_RTNL();
-	p = br_port_get_check_rtnl(dev);
 	if (p)
 		vg = nbp_vlan_group(p);
 	else if (netif_is_bridge_master(dev))
@@ -1244,8 +1242,21 @@ int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
 	*p_pvid = br_get_pvid(vg);
 	return 0;
 }
+
+int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
+{
+	ASSERT_RTNL();
+
+	return __br_vlan_get_pvid(dev, br_port_get_check_rtnl(dev), p_pvid);
+}
 EXPORT_SYMBOL_GPL(br_vlan_get_pvid);
 
+int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid)
+{
+	return __br_vlan_get_pvid(dev, br_port_get_check_rcu(dev), p_pvid);
+}
+EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu);
+
 int br_vlan_get_info(const struct net_device *dev, u16 vid,
 		     struct bridge_vlan_info *p_vinfo)
 {
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
  2019-07-05 13:16 ` [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header wenxu
  2019-07-05 13:16 ` [PATCH 3/7 nf-next v2] bridge: add br_vlan_get_pvid_rcu() wenxu
@ 2019-07-05 13:16 ` wenxu
  2019-07-05 20:45   ` Pablo Neira Ayuso
       [not found]   ` <20190813195427.vmootvj5rmxgihml@salvia>
  2019-07-05 13:16 ` [PATCH 5/7 nf-next v2] bridge: add br_vlan_get_proto() wenxu
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: wenxu <wenxu@ucloud.cn>

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@ucloud.cn>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 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


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/7 nf-next v2] bridge: add br_vlan_get_proto()
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
                   ` (2 preceding siblings ...)
  2019-07-05 13:16 ` [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support wenxu
@ 2019-07-05 13:16 ` wenxu
  2019-07-05 20:45   ` Pablo Neira Ayuso
  2019-07-05 13:16 ` [PATCH 6/7 nf-next v2] netfilter: nft_meta_bridge: Add NFT_META_BRI_IIFVPROTO support wenxu
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: wenxu <wenxu@ucloud.cn>

This new function allows you to fetch bridge vlan proto.

Signed-off-by: wenxu <wenxu@ucloud.cn>
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 include/linux/if_bridge.h |  6 ++++++
 net/bridge/br_vlan.c      | 10 ++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 950db1d..9e57c44 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -89,6 +89,7 @@ static inline bool br_multicast_router(const struct net_device *dev)
 bool br_vlan_enabled(const struct net_device *dev);
 int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid);
 int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid);
+int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto);
 int br_vlan_get_info(const struct net_device *dev, u16 vid,
 		     struct bridge_vlan_info *p_vinfo);
 #else
@@ -102,6 +103,11 @@ static inline int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
 	return -EINVAL;
 }
 
+static inline int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto)
+{
+	return -EINVAL;
+}
+
 static inline int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid)
 {
 	return -EINVAL;
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 8d97b91..021cc9f66 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -797,6 +797,16 @@ bool br_vlan_enabled(const struct net_device *dev)
 }
 EXPORT_SYMBOL_GPL(br_vlan_enabled);
 
+int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	*p_proto = ntohs(br->vlan_proto);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(br_vlan_get_proto);
+
 int __br_vlan_set_proto(struct net_bridge *br, __be16 proto)
 {
 	int err = 0;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/7 nf-next v2] netfilter: nft_meta_bridge: Add NFT_META_BRI_IIFVPROTO support
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
                   ` (3 preceding siblings ...)
  2019-07-05 13:16 ` [PATCH 5/7 nf-next v2] bridge: add br_vlan_get_proto() wenxu
@ 2019-07-05 13:16 ` wenxu
  2019-07-05 20:45   ` Pablo Neira Ayuso
  2019-07-05 13:16 ` [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support wenxu
  2019-07-05 20:44 ` [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge Pablo Neira Ayuso
  6 siblings, 1 reply; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: wenxu <wenxu@ucloud.cn>

This patch provide a meta to get the bridge vlan proto

nft add rule bridge firewall zones counter meta br_vlan_proto 0x8100

Signed-off-by: wenxu <wenxu@ucloud.cn>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/bridge/netfilter/nft_meta_bridge.c   | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 8a1bd0b..a0d1dbd 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -796,6 +796,7 @@ enum nft_exthdr_attributes {
  * @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
+ * @NFT_META_BRI_IIFVPROTO: packet input bridge vlan proto
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -827,6 +828,7 @@ enum nft_meta_keys {
 	NFT_META_IIFKIND,
 	NFT_META_OIFKIND,
 	NFT_META_BRI_IIFPVID,
+	NFT_META_BRI_IIFVPROTO,
 };
 
 /**
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 9487d42..bed66f5 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -49,6 +49,17 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
 		nft_reg_store16(dest, p_pvid);
 		return;
 	}
+	case NFT_META_BRI_IIFVPROTO: {
+		u16 p_proto;
+
+		br_dev = nft_meta_get_bridge(in);
+		if (!br_dev || !br_vlan_enabled(br_dev))
+			goto err;
+
+		br_vlan_get_proto(br_dev, &p_proto);
+		nft_reg_store16(dest, p_proto);
+		return;
+	}
 	default:
 		goto out;
 	}
@@ -75,6 +86,7 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
 		len = IFNAMSIZ;
 		break;
 	case NFT_META_BRI_IIFPVID:
+	case NFT_META_BRI_IIFVPROTO:
 		len = sizeof(u16);
 		break;
 	default:
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
                   ` (4 preceding siblings ...)
  2019-07-05 13:16 ` [PATCH 6/7 nf-next v2] netfilter: nft_meta_bridge: Add NFT_META_BRI_IIFVPROTO support wenxu
@ 2019-07-05 13:16 ` wenxu
  2019-07-06 12:02   ` Nikolay Aleksandrov
  2019-07-05 20:44 ` [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge Pablo Neira Ayuso
  6 siblings, 1 reply; 18+ messages in thread
From: wenxu @ 2019-07-05 13:16 UTC (permalink / raw)
  To: nikolay, pablo; +Cc: netfilter-devel, bridge

From: wenxu <wenxu@ucloud.cn>

This patch provide a meta vlan to set the vlan tag of the packet.

for q-in-q outer vlan id 20:
meta vlan set 0x88a8:20

set the default 0x8100 vlan type with vlan id 20
meta vlan set 20

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 include/net/netfilter/nft_meta.h         |  5 ++++-
 include/uapi/linux/netfilter/nf_tables.h |  4 ++++
 net/netfilter/nft_meta.c                 | 25 +++++++++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
index 5c69e9b..cb0f1e8 100644
--- a/include/net/netfilter/nft_meta.h
+++ b/include/net/netfilter/nft_meta.h
@@ -6,7 +6,10 @@ struct nft_meta {
 	enum nft_meta_keys	key:8;
 	union {
 		enum nft_registers	dreg:8;
-		enum nft_registers	sreg:8;
+		struct {
+			enum nft_registers	sreg:8;
+			enum nft_registers	sreg2:8;
+		};
 	};
 };
 
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index a0d1dbd..699524a 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -797,6 +797,7 @@ enum nft_exthdr_attributes {
  * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
  * @NFT_META_BRI_IIFPVID: packet input bridge port pvid
  * @NFT_META_BRI_IIFVPROTO: packet input bridge vlan proto
+ * @NFT_META_VLAN: packet vlan metadata
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -829,6 +830,7 @@ enum nft_meta_keys {
 	NFT_META_OIFKIND,
 	NFT_META_BRI_IIFPVID,
 	NFT_META_BRI_IIFVPROTO,
+	NFT_META_VLAN,
 };
 
 /**
@@ -895,12 +897,14 @@ enum nft_hash_attributes {
  * @NFTA_META_DREG: destination register (NLA_U32)
  * @NFTA_META_KEY: meta data item to load (NLA_U32: nft_meta_keys)
  * @NFTA_META_SREG: source register (NLA_U32)
+ * @NFTA_META_SREG2: source register (NLA_U32)
  */
 enum nft_meta_attributes {
 	NFTA_META_UNSPEC,
 	NFTA_META_DREG,
 	NFTA_META_KEY,
 	NFTA_META_SREG,
+	NFTA_META_SREG2,
 	__NFTA_META_MAX
 };
 #define NFTA_META_MAX		(__NFTA_META_MAX - 1)
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 18a848b..fb3d12e 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -271,6 +271,20 @@ void nft_meta_set_eval(const struct nft_expr *expr,
 		skb->secmark = value;
 		break;
 #endif
+	case NFT_META_VLAN: {
+		u32 *sreg2 = &regs->data[meta->sreg2];
+		u16 vlan_proto;
+		u16 vlan_tci;
+
+		vlan_tci = nft_reg_load16(sreg);
+		vlan_proto = nft_reg_load16(sreg2);
+
+		if (vlan_proto != ETH_P_8021Q && vlan_proto != ETH_P_8021AD)
+			return;
+
+		__vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci & VLAN_VID_MASK);
+		break;
+	}
 	default:
 		WARN_ON(1);
 	}
@@ -281,6 +295,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
 	[NFTA_META_DREG]	= { .type = NLA_U32 },
 	[NFTA_META_KEY]		= { .type = NLA_U32 },
 	[NFTA_META_SREG]	= { .type = NLA_U32 },
+	[NFTA_META_SREG2]	= { .type = NLA_U32 },
 };
 EXPORT_SYMBOL_GPL(nft_meta_policy);
 
@@ -432,6 +447,13 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
 	case NFT_META_PKTTYPE:
 		len = sizeof(u8);
 		break;
+	case NFT_META_VLAN:
+		len = sizeof(u16);
+		priv->sreg2 = nft_parse_register(tb[NFTA_META_SREG2]);
+		err = nft_validate_register_load(priv->sreg2, len);
+		if (err < 0)
+			return err;
+		break;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -457,6 +479,9 @@ int nft_meta_get_dump(struct sk_buff *skb,
 		goto nla_put_failure;
 	if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
 		goto nla_put_failure;
+	if (priv->key == NFT_META_VLAN &&
+	    nft_dump_register(skb, NFTA_META_SREG2, priv->sreg2))
+		goto nla_put_failure;
 	return 0;
 
 nla_put_failure:
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge
  2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
                   ` (5 preceding siblings ...)
  2019-07-05 13:16 ` [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support wenxu
@ 2019-07-05 20:44 ` Pablo Neira Ayuso
  6 siblings, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-05 20:44 UTC (permalink / raw)
  To: wenxu; +Cc: nikolay, netfilter-devel, bridge

On Fri, Jul 05, 2019 at 09:16:32PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> Separate bridge meta key from nft_meta to meta_bridge for other key
> support. So there is n dependency between nft_meta and the bridge
> module

Applied, thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header
  2019-07-05 13:16 ` [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header wenxu
@ 2019-07-05 20:45   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-05 20:45 UTC (permalink / raw)
  To: wenxu; +Cc: nikolay, netfilter-devel, bridge

On Fri, Jul 05, 2019 at 09:16:33PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> Mkae the nft_bridge_meta can't direct access the bridge
> internal API.

Applied, thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7 nf-next v2] bridge: add br_vlan_get_pvid_rcu()
  2019-07-05 13:16 ` [PATCH 3/7 nf-next v2] bridge: add br_vlan_get_pvid_rcu() wenxu
@ 2019-07-05 20:45   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-05 20:45 UTC (permalink / raw)
  To: wenxu; +Cc: nikolay, netfilter-devel, bridge

On Fri, Jul 05, 2019 at 09:16:34PM +0800, wenxu@ucloud.cn wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> This new function allows you to fetch bridge pvid from packet path.

Applied, thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support
  2019-07-05 13:16 ` [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support wenxu
@ 2019-07-05 20:45   ` Pablo Neira Ayuso
       [not found]   ` <20190813195427.vmootvj5rmxgihml@salvia>
  1 sibling, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-05 20:45 UTC (permalink / raw)
  To: wenxu; +Cc: nikolay, netfilter-devel, bridge

On Fri, Jul 05, 2019 at 09:16:35PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> 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

Applied, thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/7 nf-next v2] bridge: add br_vlan_get_proto()
  2019-07-05 13:16 ` [PATCH 5/7 nf-next v2] bridge: add br_vlan_get_proto() wenxu
@ 2019-07-05 20:45   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-05 20:45 UTC (permalink / raw)
  To: wenxu; +Cc: nikolay, netfilter-devel, bridge

On Fri, Jul 05, 2019 at 09:16:36PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> This new function allows you to fetch bridge vlan proto.

Applied, thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 6/7 nf-next v2] netfilter: nft_meta_bridge: Add NFT_META_BRI_IIFVPROTO support
  2019-07-05 13:16 ` [PATCH 6/7 nf-next v2] netfilter: nft_meta_bridge: Add NFT_META_BRI_IIFVPROTO support wenxu
@ 2019-07-05 20:45   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-05 20:45 UTC (permalink / raw)
  To: wenxu; +Cc: nikolay, netfilter-devel, bridge

On Fri, Jul 05, 2019 at 09:16:37PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> This patch provide a meta to get the bridge vlan proto
> 
> nft add rule bridge firewall zones counter meta br_vlan_proto 0x8100

Applied, thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support
  2019-07-05 13:16 ` [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support wenxu
@ 2019-07-06 12:02   ` Nikolay Aleksandrov
  2019-07-06 14:29     ` wenxu
  0 siblings, 1 reply; 18+ messages in thread
From: Nikolay Aleksandrov @ 2019-07-06 12:02 UTC (permalink / raw)
  To: wenxu, pablo; +Cc: netfilter-devel, bridge

On 05/07/2019 16:16, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> This patch provide a meta vlan to set the vlan tag of the packet.
> 
> for q-in-q outer vlan id 20:
> meta vlan set 0x88a8:20
> 
> set the default 0x8100 vlan type with vlan id 20
> meta vlan set 20
> 
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
>  include/net/netfilter/nft_meta.h         |  5 ++++-
>  include/uapi/linux/netfilter/nf_tables.h |  4 ++++
>  net/netfilter/nft_meta.c                 | 25 +++++++++++++++++++++++++
>  3 files changed, 33 insertions(+), 1 deletion(-)
> 

The patch looks fine, just a note: you'll only be able to work with the
outer tag, so guessing to achieve a double-tagged frame you'll have to
add another NFT_META_VLAN_INNER(?) and will have to organize them one
after another.

Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>

> diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
> index 5c69e9b..cb0f1e8 100644
> --- a/include/net/netfilter/nft_meta.h
> +++ b/include/net/netfilter/nft_meta.h
> @@ -6,7 +6,10 @@ struct nft_meta {
>  	enum nft_meta_keys	key:8;
>  	union {
>  		enum nft_registers	dreg:8;
> -		enum nft_registers	sreg:8;
> +		struct {
> +			enum nft_registers	sreg:8;
> +			enum nft_registers	sreg2:8;
> +		};
>  	};
>  };
>  
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index a0d1dbd..699524a 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -797,6 +797,7 @@ enum nft_exthdr_attributes {
>   * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
>   * @NFT_META_BRI_IIFPVID: packet input bridge port pvid
>   * @NFT_META_BRI_IIFVPROTO: packet input bridge vlan proto
> + * @NFT_META_VLAN: packet vlan metadata
>   */
>  enum nft_meta_keys {
>  	NFT_META_LEN,
> @@ -829,6 +830,7 @@ enum nft_meta_keys {
>  	NFT_META_OIFKIND,
>  	NFT_META_BRI_IIFPVID,
>  	NFT_META_BRI_IIFVPROTO,
> +	NFT_META_VLAN,
>  };
>  
>  /**
> @@ -895,12 +897,14 @@ enum nft_hash_attributes {
>   * @NFTA_META_DREG: destination register (NLA_U32)
>   * @NFTA_META_KEY: meta data item to load (NLA_U32: nft_meta_keys)
>   * @NFTA_META_SREG: source register (NLA_U32)
> + * @NFTA_META_SREG2: source register (NLA_U32)
>   */
>  enum nft_meta_attributes {
>  	NFTA_META_UNSPEC,
>  	NFTA_META_DREG,
>  	NFTA_META_KEY,
>  	NFTA_META_SREG,
> +	NFTA_META_SREG2,
>  	__NFTA_META_MAX
>  };
>  #define NFTA_META_MAX		(__NFTA_META_MAX - 1)
> diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
> index 18a848b..fb3d12e 100644
> --- a/net/netfilter/nft_meta.c
> +++ b/net/netfilter/nft_meta.c
> @@ -271,6 +271,20 @@ void nft_meta_set_eval(const struct nft_expr *expr,
>  		skb->secmark = value;
>  		break;
>  #endif
> +	case NFT_META_VLAN: {
> +		u32 *sreg2 = &regs->data[meta->sreg2];
> +		u16 vlan_proto;
> +		u16 vlan_tci;
> +
> +		vlan_tci = nft_reg_load16(sreg);
> +		vlan_proto = nft_reg_load16(sreg2);
> +
> +		if (vlan_proto != ETH_P_8021Q && vlan_proto != ETH_P_8021AD)
> +			return;
> +
> +		__vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci & VLAN_VID_MASK);
> +		break;
> +	}
>  	default:
>  		WARN_ON(1);
>  	}
> @@ -281,6 +295,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
>  	[NFTA_META_DREG]	= { .type = NLA_U32 },
>  	[NFTA_META_KEY]		= { .type = NLA_U32 },
>  	[NFTA_META_SREG]	= { .type = NLA_U32 },
> +	[NFTA_META_SREG2]	= { .type = NLA_U32 },
>  };
>  EXPORT_SYMBOL_GPL(nft_meta_policy);
>  
> @@ -432,6 +447,13 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
>  	case NFT_META_PKTTYPE:
>  		len = sizeof(u8);
>  		break;
> +	case NFT_META_VLAN:
> +		len = sizeof(u16);
> +		priv->sreg2 = nft_parse_register(tb[NFTA_META_SREG2]);
> +		err = nft_validate_register_load(priv->sreg2, len);
> +		if (err < 0)
> +			return err;
> +		break;
>  	default:
>  		return -EOPNOTSUPP;
>  	}
> @@ -457,6 +479,9 @@ int nft_meta_get_dump(struct sk_buff *skb,
>  		goto nla_put_failure;
>  	if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
>  		goto nla_put_failure;
> +	if (priv->key == NFT_META_VLAN &&
> +	    nft_dump_register(skb, NFTA_META_SREG2, priv->sreg2))
> +		goto nla_put_failure;
>  	return 0;
>  
>  nla_put_failure:
> 


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support
  2019-07-06 12:02   ` Nikolay Aleksandrov
@ 2019-07-06 14:29     ` wenxu
  2019-07-07 10:12       ` Nikolay Aleksandrov
  0 siblings, 1 reply; 18+ messages in thread
From: wenxu @ 2019-07-06 14:29 UTC (permalink / raw)
  To: Nikolay Aleksandrov, pablo; +Cc: netfilter-devel, bridge


在 2019/7/6 20:02, Nikolay Aleksandrov 写道:
> On 05/07/2019 16:16, wenxu@ucloud.cn wrote:
>> From: wenxu <wenxu@ucloud.cn>
>>
>> This patch provide a meta vlan to set the vlan tag of the packet.
>>
>> for q-in-q outer vlan id 20:
>> meta vlan set 0x88a8:20
>>
>> set the default 0x8100 vlan type with vlan id 20
>> meta vlan set 20
>>
>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>> ---
>>  include/net/netfilter/nft_meta.h         |  5 ++++-
>>  include/uapi/linux/netfilter/nf_tables.h |  4 ++++
>>  net/netfilter/nft_meta.c                 | 25 +++++++++++++++++++++++++
>>  3 files changed, 33 insertions(+), 1 deletion(-)
>>
> The patch looks fine, just a note: you'll only be able to work with the
> outer tag, so guessing to achieve a double-tagged frame you'll have to
> add another NFT_META_VLAN_INNER(?) and will have to organize them one
> after another.

yes, It's just set/mangle the meta vlan data. 
I think it's a good idear for stacked tagged with NFT_META_VLAN_INNER, in 
this case it should check the the proto of vlan tag already on packet
There are three case:
1. packet already contain a vlan header with proto 0x88a8, it should push the inner vlan tag
2. there is no outer vlan tag, maybe we should add a inner 0x8100 tag 
and outer 0x88a8 tag?
3.  packet already contain a vlan tag with proto 0x8100, push the vlan tag and add outer 0x88a8 tag ?

>
>
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support
  2019-07-06 14:29     ` wenxu
@ 2019-07-07 10:12       ` Nikolay Aleksandrov
  2019-07-07 10:13         ` Nikolay Aleksandrov
  0 siblings, 1 reply; 18+ messages in thread
From: Nikolay Aleksandrov @ 2019-07-07 10:12 UTC (permalink / raw)
  To: wenxu, pablo; +Cc: netfilter-devel, bridge

On 06/07/2019 17:29, wenxu wrote:
> 
> 在 2019/7/6 20:02, Nikolay Aleksandrov 写道:
>> On 05/07/2019 16:16, wenxu@ucloud.cn wrote:
>>> From: wenxu <wenxu@ucloud.cn>
>>>
>>> This patch provide a meta vlan to set the vlan tag of the packet.
>>>
>>> for q-in-q outer vlan id 20:
>>> meta vlan set 0x88a8:20
>>>
>>> set the default 0x8100 vlan type with vlan id 20
>>> meta vlan set 20
>>>
>>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>>> ---
>>>  include/net/netfilter/nft_meta.h         |  5 ++++-
>>>  include/uapi/linux/netfilter/nf_tables.h |  4 ++++
>>>  net/netfilter/nft_meta.c                 | 25 +++++++++++++++++++++++++
>>>  3 files changed, 33 insertions(+), 1 deletion(-)
>>>
>> The patch looks fine, just a note: you'll only be able to work with the
>> outer tag, so guessing to achieve a double-tagged frame you'll have to
>> add another NFT_META_VLAN_INNER(?) and will have to organize them one
>> after another.
> 
> yes, It's just set/mangle the meta vlan data. 
> I think it's a good idear for stacked tagged with NFT_META_VLAN_INNER, in 
> this case it should check the the proto of vlan tag already on packet
> There are three case:
> 1. packet already contain a vlan header with proto 0x88a8, it should push the inner vlan tag
> 2. there is no outer vlan tag, maybe we should add a inner 0x8100 tag 
> and outer 0x88a8 tag?
> 3.  packet already contain a vlan tag with proto 0x8100, push the vlan tag and add outer 0x88a8 tag ?
> 

I'm more inclined to make it simpler, i.e. always push inner vlan. That way you can arrange them
anyway you like, also skb_vlan_push() already takes care of all that. It'll push the vlan
if hwaccel is present or make it hwaccel if it isn't.

In fact I'd suggest using skb_vlan_push(), so you don't need another NFT_META_VLAN_INNER,
this one can be re-used. If you chain 2 of these you'll get properly double-tagged frame.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support
  2019-07-07 10:12       ` Nikolay Aleksandrov
@ 2019-07-07 10:13         ` Nikolay Aleksandrov
  0 siblings, 0 replies; 18+ messages in thread
From: Nikolay Aleksandrov @ 2019-07-07 10:13 UTC (permalink / raw)
  To: wenxu, pablo; +Cc: netfilter-devel, bridge

On 07/07/2019 13:12, Nikolay Aleksandrov wrote:
> On 06/07/2019 17:29, wenxu wrote:
>>
>> 在 2019/7/6 20:02, Nikolay Aleksandrov 写道:
>>> On 05/07/2019 16:16, wenxu@ucloud.cn wrote:
>>>> From: wenxu <wenxu@ucloud.cn>
>>>>
>>>> This patch provide a meta vlan to set the vlan tag of the packet.
>>>>
>>>> for q-in-q outer vlan id 20:
>>>> meta vlan set 0x88a8:20
>>>>
>>>> set the default 0x8100 vlan type with vlan id 20
>>>> meta vlan set 20
>>>>
>>>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>>>> ---
>>>>  include/net/netfilter/nft_meta.h         |  5 ++++-
>>>>  include/uapi/linux/netfilter/nf_tables.h |  4 ++++
>>>>  net/netfilter/nft_meta.c                 | 25 +++++++++++++++++++++++++
>>>>  3 files changed, 33 insertions(+), 1 deletion(-)
>>>>
>>> The patch looks fine, just a note: you'll only be able to work with the
>>> outer tag, so guessing to achieve a double-tagged frame you'll have to
>>> add another NFT_META_VLAN_INNER(?) and will have to organize them one
>>> after another.
>>
>> yes, It's just set/mangle the meta vlan data. 
>> I think it's a good idear for stacked tagged with NFT_META_VLAN_INNER, in 
>> this case it should check the the proto of vlan tag already on packet
>> There are three case:
>> 1. packet already contain a vlan header with proto 0x88a8, it should push the inner vlan tag
>> 2. there is no outer vlan tag, maybe we should add a inner 0x8100 tag 
>> and outer 0x88a8 tag?
>> 3.  packet already contain a vlan tag with proto 0x8100, push the vlan tag and add outer 0x88a8 tag ?
>>
> 
> I'm more inclined to make it simpler, i.e. always push inner vlan. That way you can arrange them
> anyway you like, also skb_vlan_push() already takes care of all that. It'll push the vlan
> if hwaccel is present or make it hwaccel if it isn't.
> 
> In fact I'd suggest using skb_vlan_push(), so you don't need another NFT_META_VLAN_INNER,
> this one can be re-used. If you chain 2 of these you'll get properly double-tagged frame.
> 

You just need to be careful because skb_vlan_push expects skb->data to be at the mac header.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support
       [not found]   ` <20190813195427.vmootvj5rmxgihml@salvia>
@ 2019-08-13 19:54     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2019-08-13 19:54 UTC (permalink / raw)
  To: wenxu; +Cc: netfilter-devel

On Fri, Jul 05, 2019 at 09:16:35PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> 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

No patches for libnftnl and nftables to support for this?

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2019-08-13 19:54 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-05 13:16 [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge wenxu
2019-07-05 13:16 ` [PATCH 2/7 nf-next v2] netfilter: nft_meta_bridge: Remove the br_private.h header wenxu
2019-07-05 20:45   ` Pablo Neira Ayuso
2019-07-05 13:16 ` [PATCH 3/7 nf-next v2] bridge: add br_vlan_get_pvid_rcu() wenxu
2019-07-05 20:45   ` Pablo Neira Ayuso
2019-07-05 13:16 ` [PATCH 4/7 nf-next v2] netfilter: nft_meta_bridge: add NFT_META_BRI_IIFPVID support wenxu
2019-07-05 20:45   ` Pablo Neira Ayuso
     [not found]   ` <20190813195427.vmootvj5rmxgihml@salvia>
2019-08-13 19:54     ` Pablo Neira Ayuso
2019-07-05 13:16 ` [PATCH 5/7 nf-next v2] bridge: add br_vlan_get_proto() wenxu
2019-07-05 20:45   ` Pablo Neira Ayuso
2019-07-05 13:16 ` [PATCH 6/7 nf-next v2] netfilter: nft_meta_bridge: Add NFT_META_BRI_IIFVPROTO support wenxu
2019-07-05 20:45   ` Pablo Neira Ayuso
2019-07-05 13:16 ` [PATCH nf-next v2] netfilter:nft_meta: add NFT_META_VLAN support wenxu
2019-07-06 12:02   ` Nikolay Aleksandrov
2019-07-06 14:29     ` wenxu
2019-07-07 10:12       ` Nikolay Aleksandrov
2019-07-07 10:13         ` Nikolay Aleksandrov
2019-07-05 20:44 ` [PATCH 1/7 nf-next v2] netfilter: separate bridge meta key from nft_meta into meta_bridge Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).