All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions
@ 2019-07-23 12:52 wenxu
  2019-07-23 12:52 ` [PATCH nf-next 1/7] netfilter: nf_flow_offload: add net in offload_ctx wenxu
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

This series patch support fw_nedev and set payload offload. Keep action data in
reg  through immedidate offload

wenxu (7):
  netfilter: nf_flow_offload: add net in offload_ctx
  netfilter: nf_tables_offload: add offload_actions callback
  netfilter: nft_table_offload: Add rtnl for chain and rule operations
  netfilter: nf_tables_offload: split nft_offload_reg to match and
    action type
  netfilter: nft_immediate: add offload support for actions
  netfilter: nft_fwd_netdev: add fw_netdev action support
  netfilter: nft_payload: add nft_set_payload offload support

 include/net/netfilter/nf_tables.h         |  7 ++-
 include/net/netfilter/nf_tables_offload.h | 25 +++++++--
 net/netfilter/nf_tables_api.c             |  2 +-
 net/netfilter/nf_tables_offload.c         | 23 +++++---
 net/netfilter/nft_cmp.c                   | 10 ++--
 net/netfilter/nft_fwd_netdev.c            | 30 +++++++++++
 net/netfilter/nft_immediate.c             | 47 ++++++++++------
 net/netfilter/nft_meta.c                  |  6 ++-
 net/netfilter/nft_payload.c               | 90 ++++++++++++++++++++++++++-----
 9 files changed, 191 insertions(+), 49 deletions(-)

-- 
1.8.3.1


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

* [PATCH nf-next 1/7] netfilter: nf_flow_offload: add net in offload_ctx
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
@ 2019-07-23 12:52 ` wenxu
  2019-07-23 12:52 ` [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback wenxu
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

In the offload_ctx, the net can be used for other actions
such as fwd netdev

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 include/net/netfilter/nf_tables_offload.h | 3 ++-
 net/netfilter/nf_tables_api.c             | 2 +-
 net/netfilter/nf_tables_offload.c         | 3 ++-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index 3196663..ad61958 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -24,6 +24,7 @@ struct nft_offload_ctx {
 		__be16				l3num;
 		u8				protonum;
 	} dep;
+	struct net *net;
 	unsigned int				num_actions;
 	struct nft_offload_reg			regs[NFT_REG32_15 + 1];
 };
@@ -60,7 +61,7 @@ struct nft_flow_rule {
 #define NFT_OFFLOAD_F_ACTION	(1 << 0)
 
 struct nft_rule;
-struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule);
+struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rule *rule);
 void nft_flow_rule_destroy(struct nft_flow_rule *flow);
 int nft_flow_rule_offload_commit(struct net *net);
 
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 605a7cf..c6dc173 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2844,7 +2844,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
 		return nft_table_validate(net, table);
 
 	if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
-		flow = nft_flow_rule_create(rule);
+		flow = nft_flow_rule_create(net, rule);
 		if (IS_ERR(flow))
 			return PTR_ERR(flow);
 
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index 64f5fd5..5c1fef7 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -28,12 +28,13 @@ static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions)
 	return flow;
 }
 
-struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule)
+struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rule *rule)
 {
 	struct nft_offload_ctx ctx = {
 		.dep	= {
 			.type	= NFT_OFFLOAD_DEP_UNSPEC,
 		},
+		.net = net,
 	};
 	struct nft_flow_rule *flow;
 	int num_actions = 0, err;
-- 
1.8.3.1


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

* [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
  2019-07-23 12:52 ` [PATCH nf-next 1/7] netfilter: nf_flow_offload: add net in offload_ctx wenxu
@ 2019-07-23 12:52 ` wenxu
  2019-07-25 10:14   ` Pablo Neira Ayuso
  2019-07-23 12:52 ` [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations wenxu
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

There will be zero one or serval actions for some expr. such as
payload set and immediate

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 include/net/netfilter/nf_tables.h         | 7 ++++++-
 include/net/netfilter/nf_tables_offload.h | 2 --
 net/netfilter/nf_tables_offload.c         | 4 ++--
 net/netfilter/nft_immediate.c             | 2 +-
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 9b62456..9285df2 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -785,7 +785,7 @@ struct nft_expr_ops {
 	int				(*offload)(struct nft_offload_ctx *ctx,
 						   struct nft_flow_rule *flow,
 						   const struct nft_expr *expr);
-	u32				offload_flags;
+	int				(*offload_actions)(const struct nft_expr *expr);
 	const struct nft_expr_type	*type;
 	void				*data;
 };
@@ -794,6 +794,11 @@ struct nft_expr_ops {
 #define NFT_EXPR_SIZE(size)		(sizeof(struct nft_expr) + \
 					 ALIGN(size, __alignof__(struct nft_expr)))
 
+static inline int nft_offload_action(const struct nft_expr *expr)
+{
+	return 1;
+}
+
 /**
  *	struct nft_expr - nf_tables expression
  *
diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index ad61958..275d014 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -58,8 +58,6 @@ struct nft_flow_rule {
 	struct flow_rule	*rule;
 };
 
-#define NFT_OFFLOAD_F_ACTION	(1 << 0)
-
 struct nft_rule;
 struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rule *rule);
 void nft_flow_rule_destroy(struct nft_flow_rule *flow);
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index 5c1fef7..33543f5 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -42,8 +42,8 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rul
 
 	expr = nft_expr_first(rule);
 	while (expr->ops && expr != nft_expr_last(rule)) {
-		if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
-			num_actions++;
+		if (expr->ops->offload_actions)
+			num_actions += expr->ops->offload_actions(expr);
 
 		expr = nft_expr_next(expr);
 	}
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index ca2ae4b..391f699 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -163,7 +163,7 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx,
 	.dump		= nft_immediate_dump,
 	.validate	= nft_immediate_validate,
 	.offload	= nft_immediate_offload,
-	.offload_flags	= NFT_OFFLOAD_F_ACTION,
+	.offload_actions = nft_offload_action,
 };
 
 struct nft_expr_type nft_imm_type __read_mostly = {
-- 
1.8.3.1


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

* [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
  2019-07-23 12:52 ` [PATCH nf-next 1/7] netfilter: nf_flow_offload: add net in offload_ctx wenxu
  2019-07-23 12:52 ` [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback wenxu
@ 2019-07-23 12:52 ` wenxu
  2019-07-25  9:48   ` Pablo Neira Ayuso
  2019-07-23 12:52 ` [PATCH nf-next 4/7] netfilter: nf_tables_offload: split nft_offload_reg to match and action type wenxu
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

The nft_setup_cb_call and ndo_setup_tc callback should be under rtnl lock

or it will report:
kernel: RTNL: assertion failed at
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c (635)

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 net/netfilter/nf_tables_offload.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index 33543f5..3e1a1a8 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -115,14 +115,18 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
 			     enum tc_setup_type type, void *type_data)
 {
 	struct flow_block_cb *block_cb;
-	int err;
+	int err = 0;
 
+	rtnl_lock();
 	list_for_each_entry(block_cb, &basechain->flow_block.cb_list, list) {
 		err = block_cb->cb(type, type_data, block_cb->cb_priv);
 		if (err < 0)
-			return err;
+			goto out;
 	}
-	return 0;
+
+out:
+	rtnl_unlock();
+	return err;
 }
 
 static int nft_flow_offload_rule(struct nft_trans *trans,
@@ -204,9 +208,11 @@ static int nft_flow_offload_chain(struct nft_trans *trans,
 	bo.extack = &extack;
 	INIT_LIST_HEAD(&bo.cb_list);
 
+	rtnl_lock();
+
 	err = dev->netdev_ops->ndo_setup_tc(dev, FLOW_SETUP_BLOCK, &bo);
 	if (err < 0)
-		return err;
+		goto out;
 
 	switch (cmd) {
 	case FLOW_BLOCK_BIND:
@@ -217,6 +223,8 @@ static int nft_flow_offload_chain(struct nft_trans *trans,
 		break;
 	}
 
+out:
+	rtnl_unlock();
 	return err;
 }
 
-- 
1.8.3.1


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

* [PATCH nf-next 4/7] netfilter: nf_tables_offload: split nft_offload_reg to match and action type
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
                   ` (2 preceding siblings ...)
  2019-07-23 12:52 ` [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations wenxu
@ 2019-07-23 12:52 ` wenxu
  2019-07-23 12:52 ` [PATCH nf-next 5/7] netfilter: nft_immediate: add offload support for actions wenxu
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

Currently the nft_offload_reg is only can be used for match condition.
Can not be used for action. Add nft_offload_reg_type to make nft_offload_reg
can be iused for action also.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 include/net/netfilter/nf_tables_offload.h | 20 +++++++++++++++++-
 net/netfilter/nft_cmp.c                   | 10 ++++-----
 net/netfilter/nft_meta.c                  |  6 ++++--
 net/netfilter/nft_payload.c               | 34 ++++++++++++++++++++-----------
 4 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index 275d014..82e3936 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -4,7 +4,13 @@
 #include <net/flow_offload.h>
 #include <net/netfilter/nf_tables.h>
 
-struct nft_offload_reg {
+enum nft_offload_reg_type {
+	NFT_OFFLOAD_REG_UNSPEC	= 0,
+	NFT_OFFLOAD_REG_MATCH,
+	NFT_OFFLOAD_REG_ACTION,
+};
+
+struct nft_offload_match {
 	u32		key;
 	u32		len;
 	u32		base_offset;
@@ -12,6 +18,18 @@ struct nft_offload_reg {
 	struct nft_data	mask;
 };
 
+struct nft_offload_action {
+	struct nft_data	data;
+};
+
+struct nft_offload_reg {
+	enum nft_offload_reg_type type;
+	union {
+		struct nft_offload_match match;
+		struct nft_offload_action action;
+	};
+};
+
 enum nft_offload_dep_type {
 	NFT_OFFLOAD_DEP_UNSPEC	= 0,
 	NFT_OFFLOAD_DEP_NETWORK,
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index bd173b1..ee38cba 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -116,14 +116,14 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx,
 	u8 *mask = (u8 *)&flow->match.mask;
 	u8 *key = (u8 *)&flow->match.key;
 
-	if (priv->op != NFT_CMP_EQ)
+	if (priv->op != NFT_CMP_EQ || reg->type != NFT_OFFLOAD_REG_MATCH)
 		return -EOPNOTSUPP;
 
-	memcpy(key + reg->offset, &priv->data, priv->len);
-	memcpy(mask + reg->offset, &reg->mask, priv->len);
+	memcpy(key + reg->match.offset, &priv->data, priv->len);
+	memcpy(mask + reg->match.offset, &reg->match.mask, priv->len);
 
-	flow->match.dissector.used_keys |= BIT(reg->key);
-	flow->match.dissector.offset[reg->key] = reg->base_offset;
+	flow->match.dissector.used_keys |= BIT(reg->match.key);
+	flow->match.dissector.offset[reg->match.key] = reg->match.base_offset;
 
 	nft_offload_update_dependency(ctx, &priv->data, priv->len);
 
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index f1b1d94..6bb5ba6 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -498,15 +498,17 @@ static int nft_meta_get_offload(struct nft_offload_ctx *ctx,
 	const struct nft_meta *priv = nft_expr_priv(expr);
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	reg->type = NFT_OFFLOAD_REG_MATCH;
+
 	switch (priv->key) {
 	case NFT_META_PROTOCOL:
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto,
-				  sizeof(__u16), reg);
+				  sizeof(__u16), &reg->match);
 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
 		break;
 	case NFT_META_L4PROTO:
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
-				  sizeof(__u8), reg);
+				  sizeof(__u8), &reg->match);
 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
 		break;
 	default:
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 22a80eb..36efa1c 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -159,14 +159,16 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx,
 {
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	reg->type = NFT_OFFLOAD_REG_MATCH;
+
 	switch (priv->offset) {
 	case offsetof(struct ethhdr, h_source):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
-				  src, ETH_ALEN, reg);
+				  src, ETH_ALEN, &reg->match);
 		break;
 	case offsetof(struct ethhdr, h_dest):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
-				  dst, ETH_ALEN, reg);
+				  dst, ETH_ALEN, &reg->match);
 		break;
 	}
 
@@ -179,18 +181,20 @@ static int nft_payload_offload_ip(struct nft_offload_ctx *ctx,
 {
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	reg->type = NFT_OFFLOAD_REG_MATCH;
+
 	switch (priv->offset) {
 	case offsetof(struct iphdr, saddr):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src,
-				  sizeof(struct in_addr), reg);
+				  sizeof(struct in_addr), &reg->match);
 		break;
 	case offsetof(struct iphdr, daddr):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst,
-				  sizeof(struct in_addr), reg);
+				  sizeof(struct in_addr), &reg->match);
 		break;
 	case offsetof(struct iphdr, protocol):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
-				  sizeof(__u8), reg);
+				  sizeof(__u8), &reg->match);
 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
 		break;
 	default:
@@ -206,18 +210,20 @@ static int nft_payload_offload_ip6(struct nft_offload_ctx *ctx,
 {
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	reg->type = NFT_OFFLOAD_REG_MATCH;
+
 	switch (priv->offset) {
 	case offsetof(struct ipv6hdr, saddr):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src,
-				  sizeof(struct in6_addr), reg);
+				  sizeof(struct in6_addr), &reg->match);
 		break;
 	case offsetof(struct ipv6hdr, daddr):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst,
-				  sizeof(struct in6_addr), reg);
+				  sizeof(struct in6_addr), &reg->match);
 		break;
 	case offsetof(struct ipv6hdr, nexthdr):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
-				  sizeof(__u8), reg);
+				  sizeof(__u8), &reg->match);
 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
 		break;
 	default:
@@ -253,14 +259,16 @@ static int nft_payload_offload_tcp(struct nft_offload_ctx *ctx,
 {
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	reg->type = NFT_OFFLOAD_REG_MATCH;
+
 	switch (priv->offset) {
 	case offsetof(struct tcphdr, source):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
-				  sizeof(__be16), reg);
+				  sizeof(__be16), &reg->match);
 		break;
 	case offsetof(struct tcphdr, dest):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
-				  sizeof(__be16), reg);
+				  sizeof(__be16), &reg->match);
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -275,14 +283,16 @@ static int nft_payload_offload_udp(struct nft_offload_ctx *ctx,
 {
 	struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+	reg->type = NFT_OFFLOAD_REG_MATCH;
+
 	switch (priv->offset) {
 	case offsetof(struct udphdr, source):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
-				  sizeof(__be16), reg);
+				  sizeof(__be16), &reg->match);
 		break;
 	case offsetof(struct udphdr, dest):
 		NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
-				  sizeof(__be16), reg);
+				  sizeof(__be16), &reg->match);
 		break;
 	default:
 		return -EOPNOTSUPP;
-- 
1.8.3.1


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

* [PATCH nf-next 5/7] netfilter: nft_immediate: add offload support for actions
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
                   ` (3 preceding siblings ...)
  2019-07-23 12:52 ` [PATCH nf-next 4/7] netfilter: nf_tables_offload: split nft_offload_reg to match and action type wenxu
@ 2019-07-23 12:52 ` wenxu
  2019-07-23 12:52 ` [PATCH nf-next 6/7] netfilter: nft_fwd_netdev: add fw_netdev action support wenxu
  2019-07-23 12:52 ` [PATCH nf-next 7/7] netfilter: nft_payload: add nft_set_payload offload support wenxu
  6 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

Immediate offload support for other action to handle the offload_reg

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 net/netfilter/nft_immediate.c | 47 +++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 391f699..34facc3 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -130,29 +130,42 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx,
 				 const struct nft_expr *expr)
 {
 	const struct nft_immediate_expr *priv = nft_expr_priv(expr);
+	const struct nft_data *data = &priv->data;
 	struct flow_action_entry *entry;
-	const struct nft_data *data;
-
-	if (priv->dreg != NFT_REG_VERDICT)
-		return -EOPNOTSUPP;
-
-	entry = &flow->rule->action.entries[ctx->num_actions++];
 
-	data = &priv->data;
-	switch (data->verdict.code) {
-	case NF_ACCEPT:
-		entry->id = FLOW_ACTION_ACCEPT;
-		break;
-	case NF_DROP:
-		entry->id = FLOW_ACTION_DROP;
-		break;
-	default:
-		return -EOPNOTSUPP;
+	if (priv->dreg == NFT_REG_VERDICT) {
+		entry = &flow->rule->action.entries[ctx->num_actions++];
+
+		switch (data->verdict.code) {
+		case NF_ACCEPT:
+			entry->id = FLOW_ACTION_ACCEPT;
+			break;
+		case NF_DROP:
+			entry->id = FLOW_ACTION_DROP;
+			break;
+		default:
+			return -EOPNOTSUPP;
+		}
+	} else {
+		struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
+
+		reg->type = NFT_OFFLOAD_REG_ACTION;
+		memcpy(&reg->action.data, data, sizeof(*data));
 	}
 
 	return 0;
 }
 
+static int nft_immediate_offload_actions(const struct nft_expr *expr)
+{
+	const struct nft_immediate_expr *priv = nft_expr_priv(expr);
+
+	if (priv->dreg == NFT_REG_VERDICT)
+		return 1;
+	else
+		return 0;
+}
+
 static const struct nft_expr_ops nft_imm_ops = {
 	.type		= &nft_imm_type,
 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)),
@@ -163,7 +176,7 @@ static int nft_immediate_offload(struct nft_offload_ctx *ctx,
 	.dump		= nft_immediate_dump,
 	.validate	= nft_immediate_validate,
 	.offload	= nft_immediate_offload,
-	.offload_actions = nft_offload_action,
+	.offload_actions = nft_immediate_offload_actions,
 };
 
 struct nft_expr_type nft_imm_type __read_mostly = {
-- 
1.8.3.1


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

* [PATCH nf-next 6/7] netfilter: nft_fwd_netdev: add fw_netdev action support
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
                   ` (4 preceding siblings ...)
  2019-07-23 12:52 ` [PATCH nf-next 5/7] netfilter: nft_immediate: add offload support for actions wenxu
@ 2019-07-23 12:52 ` wenxu
  2019-07-23 12:52 ` [PATCH nf-next 7/7] netfilter: nft_payload: add nft_set_payload offload support wenxu
  6 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

fwd_netdev action offload:
nft --debug=netlink add rule netdev firewall aclout ip daddr 10.0.1.7 fwd to eth0

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 net/netfilter/nft_fwd_netdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
index 61b7f93..06dbd98 100644
--- a/net/netfilter/nft_fwd_netdev.c
+++ b/net/netfilter/nft_fwd_netdev.c
@@ -15,6 +15,7 @@
 #include <net/netfilter/nf_dup_netdev.h>
 #include <net/neighbour.h>
 #include <net/ip.h>
+#include <net/netfilter/nf_tables_offload.h>
 
 struct nft_fwd_netdev {
 	enum nft_registers	sreg_dev:8;
@@ -63,6 +64,33 @@ static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
 	return -1;
 }
 
+static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx,
+				  struct nft_flow_rule *flow,
+				  const struct nft_expr *expr)
+{
+	const struct nft_fwd_netdev *priv = nft_expr_priv(expr);
+	struct nft_offload_reg *reg = &ctx->regs[priv->sreg_dev];
+	const struct nft_data *data = &reg->action.data;
+	struct flow_action_entry *entry;
+	struct net_device *dev;
+	int oif = -1;
+
+	if (reg->type != NFT_OFFLOAD_REG_ACTION)
+		return -EOPNOTSUPP;
+
+	entry = &flow->rule->action.entries[ctx->num_actions++];
+
+	memcpy(&oif, data->data, sizeof(oif));
+	dev = __dev_get_by_index(ctx->net, oif);
+	if (!dev)
+		return -EOPNOTSUPP;
+
+	entry->id = FLOW_ACTION_REDIRECT;
+	entry->dev = dev;
+
+	return 0;
+}
+
 struct nft_fwd_neigh {
 	enum nft_registers	sreg_dev:8;
 	enum nft_registers	sreg_addr:8;
@@ -194,6 +222,8 @@ static int nft_fwd_neigh_dump(struct sk_buff *skb, const struct nft_expr *expr)
 	.eval		= nft_fwd_netdev_eval,
 	.init		= nft_fwd_netdev_init,
 	.dump		= nft_fwd_netdev_dump,
+	.offload	= nft_fwd_netdev_offload,
+	.offload_actions = nft_offload_action,
 };
 
 static const struct nft_expr_ops *
-- 
1.8.3.1


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

* [PATCH nf-next 7/7] netfilter: nft_payload: add nft_set_payload offload support
  2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
                   ` (5 preceding siblings ...)
  2019-07-23 12:52 ` [PATCH nf-next 6/7] netfilter: nft_fwd_netdev: add fw_netdev action support wenxu
@ 2019-07-23 12:52 ` wenxu
  6 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-23 12:52 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

currently payload set only support ll header

nft --debug=netlink add rule netdev firewall aclout ip daddr 10.0.1.7 @ll,0,48
set 0x00002e9ca06e2596 @ll,48,48 set 0xfaffffffffff fwd to eth0

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 net/netfilter/nft_payload.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 36efa1c..544fc40 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -572,12 +572,68 @@ static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr
 	return -1;
 }
 
+static int nft_payload_set_offload(struct nft_offload_ctx *ctx,
+				   struct nft_flow_rule *flow,
+				   const struct nft_expr *expr)
+{
+	const struct nft_payload_set *priv = nft_expr_priv(expr);
+	struct nft_offload_reg *reg = &ctx->regs[priv->sreg];
+	const struct nft_data *data = &reg->action.data;
+	struct flow_action_entry *entry;
+	u32 len = priv->len;
+	u32 offset, last;
+	int n_actions, i;
+
+	if (priv->base != NFT_PAYLOAD_LL_HEADER || len > 16)
+		return -EOPNOTSUPP;
+
+	offset = priv->offset;
+	n_actions = len >> 2;
+	last = len & 0x3;
+
+	for (i = 0; i < n_actions; i++) {
+		entry = &flow->rule->action.entries[ctx->num_actions++];
+
+		entry->id = FLOW_ACTION_MANGLE;
+		entry->mangle.htype = FLOW_ACT_MANGLE_HDR_TYPE_ETH;
+		entry->mangle.mask = 0;
+		entry->mangle.val = data->data[i];
+		entry->mangle.offset = offset;
+		offset = offset + 4;
+	}
+
+	if (last) {
+		entry = &flow->rule->action.entries[ctx->num_actions++];
+
+		entry->id = FLOW_ACTION_MANGLE;
+		entry->mangle.htype = FLOW_ACT_MANGLE_HDR_TYPE_ETH;
+		entry->mangle.mask = ~((1 << (last * 8)) - 1);
+		entry->mangle.val = data->data[i];
+		entry->mangle.offset = offset;
+	}
+
+	return 0;
+}
+
+static int nft_payload_set_offload_actions(const struct nft_expr *expr)
+{
+	const struct nft_payload_set *priv = nft_expr_priv(expr);
+	u32 len = priv->len;
+
+	if (priv->base != NFT_PAYLOAD_LL_HEADER || len > 16)
+		return 0;
+
+	return (len >> 2) + !!(len & 3);
+}
+
 static const struct nft_expr_ops nft_payload_set_ops = {
 	.type		= &nft_payload_type,
 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_payload_set)),
 	.eval		= nft_payload_set_eval,
 	.init		= nft_payload_set_init,
 	.dump		= nft_payload_set_dump,
+	.offload	= nft_payload_set_offload,
+	.offload_actions = nft_payload_set_offload_actions,
 };
 
 static const struct nft_expr_ops *
-- 
1.8.3.1


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

* Re: [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations
  2019-07-23 12:52 ` [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations wenxu
@ 2019-07-25  9:48   ` Pablo Neira Ayuso
  2019-07-25 10:14     ` Florian Westphal
  0 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-25  9:48 UTC (permalink / raw)
  To: wenxu; +Cc: fw, netfilter-devel

On Tue, Jul 23, 2019 at 08:52:40PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> The nft_setup_cb_call and ndo_setup_tc callback should be under rtnl lock
> 
> or it will report:
> kernel: RTNL: assertion failed at
> drivers/net/ethernet/mellanox/mlx5/core/en_rep.c (635)
> 
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
>  net/netfilter/nf_tables_offload.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
> index 33543f5..3e1a1a8 100644
> --- a/net/netfilter/nf_tables_offload.c
> +++ b/net/netfilter/nf_tables_offload.c
> @@ -115,14 +115,18 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
>  			     enum tc_setup_type type, void *type_data)
>  {
>  	struct flow_block_cb *block_cb;
> -	int err;
> +	int err = 0;
>  
> +	rtnl_lock();

Please, have a look at 90d2723c6d4cb2ace50fc3b932a2bcc77710450b and
review if this assumption is correct. Probably nfnl_lock() is missing
from __nft_release_basechain().

I'd like to avoid grabbing the rtnl_lock().

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

* Re: [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations
  2019-07-25  9:48   ` Pablo Neira Ayuso
@ 2019-07-25 10:14     ` Florian Westphal
  2019-07-25 10:42       ` wenxu
  0 siblings, 1 reply; 13+ messages in thread
From: Florian Westphal @ 2019-07-25 10:14 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: wenxu, fw, netfilter-devel

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Tue, Jul 23, 2019 at 08:52:40PM +0800, wenxu@ucloud.cn wrote:
> > From: wenxu <wenxu@ucloud.cn>
> > 
> > The nft_setup_cb_call and ndo_setup_tc callback should be under rtnl lock
> > 
> > or it will report:
> > kernel: RTNL: assertion failed at
> > drivers/net/ethernet/mellanox/mlx5/core/en_rep.c (635)
> > 
> > Signed-off-by: wenxu <wenxu@ucloud.cn>
> > ---
> >  net/netfilter/nf_tables_offload.c | 16 ++++++++++++----
> >  1 file changed, 12 insertions(+), 4 deletions(-)
> > 
> > diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
> > index 33543f5..3e1a1a8 100644
> > --- a/net/netfilter/nf_tables_offload.c
> > +++ b/net/netfilter/nf_tables_offload.c
> > @@ -115,14 +115,18 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
> >  			     enum tc_setup_type type, void *type_data)
> >  {
> >  	struct flow_block_cb *block_cb;
> > -	int err;
> > +	int err = 0;
> >  
> > +	rtnl_lock();
> 
> Please, have a look at 90d2723c6d4cb2ace50fc3b932a2bcc77710450b and
> review if this assumption is correct. Probably nfnl_lock() is missing
> from __nft_release_basechain().

The mlx driver has a ASSERT_RTNL() in the mlx5e_rep_indr_setup_tc_block()
callpath.  Or are you proposing to remove that assertion?  If so, what
lock should protect the callback lists?


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

* Re: [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback
  2019-07-23 12:52 ` [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback wenxu
@ 2019-07-25 10:14   ` Pablo Neira Ayuso
  2019-07-25 10:44     ` wenxu
  0 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-25 10:14 UTC (permalink / raw)
  To: wenxu; +Cc: fw, netfilter-devel

On Tue, Jul 23, 2019 at 08:52:39PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> There will be zero one or serval actions for some expr. such as
> payload set and immediate
> 
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
>  include/net/netfilter/nf_tables.h         | 7 ++++++-
>  include/net/netfilter/nf_tables_offload.h | 2 --
>  net/netfilter/nf_tables_offload.c         | 4 ++--
>  net/netfilter/nft_immediate.c             | 2 +-
>  4 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
> index 9b62456..9285df2 100644
> --- a/include/net/netfilter/nf_tables.h
> +++ b/include/net/netfilter/nf_tables.h
> @@ -785,7 +785,7 @@ struct nft_expr_ops {
>  	int				(*offload)(struct nft_offload_ctx *ctx,
>  						   struct nft_flow_rule *flow,
>  						   const struct nft_expr *expr);
> -	u32				offload_flags;
> +	int				(*offload_actions)(const struct nft_expr *expr);

I don't understand why you need to add this? is it for payload?

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

* Re: [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations
  2019-07-25 10:14     ` Florian Westphal
@ 2019-07-25 10:42       ` wenxu
  0 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-25 10:42 UTC (permalink / raw)
  To: Florian Westphal, Pablo Neira Ayuso; +Cc: netfilter-devel


On 7/25/2019 6:14 PM, Florian Westphal wrote:
> Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>> On Tue, Jul 23, 2019 at 08:52:40PM +0800, wenxu@ucloud.cn wrote:
>>> From: wenxu <wenxu@ucloud.cn>
>>>
>>> The nft_setup_cb_call and ndo_setup_tc callback should be under rtnl lock
>>>
>>> or it will report:
>>> kernel: RTNL: assertion failed at
>>> drivers/net/ethernet/mellanox/mlx5/core/en_rep.c (635)
>>>
>>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>>> ---
>>>  net/netfilter/nf_tables_offload.c | 16 ++++++++++++----
>>>  1 file changed, 12 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
>>> index 33543f5..3e1a1a8 100644
>>> --- a/net/netfilter/nf_tables_offload.c
>>> +++ b/net/netfilter/nf_tables_offload.c
>>> @@ -115,14 +115,18 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain,
>>>  			     enum tc_setup_type type, void *type_data)
>>>  {
>>>  	struct flow_block_cb *block_cb;
>>> -	int err;
>>> +	int err = 0;
>>>  
>>> +	rtnl_lock();
>> Please, have a look at 90d2723c6d4cb2ace50fc3b932a2bcc77710450b and
>> review if this assumption is correct. Probably nfnl_lock() is missing
>> from __nft_release_basechain().
> The mlx driver has a ASSERT_RTNL() in the mlx5e_rep_indr_setup_tc_block()
> callpath.  Or are you proposing to remove that assertion?  If so, what
> lock should protect the callback lists?
yes, most of the setup_tc callback in mlx driver has a 

ASSERT_RTNL() directly or indirectly. Maybe remove this is a good idear

>
>

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

* Re: [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback
  2019-07-25 10:14   ` Pablo Neira Ayuso
@ 2019-07-25 10:44     ` wenxu
  0 siblings, 0 replies; 13+ messages in thread
From: wenxu @ 2019-07-25 10:44 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: fw, netfilter-devel


On 7/25/2019 6:14 PM, Pablo Neira Ayuso wrote:
> On Tue, Jul 23, 2019 at 08:52:39PM +0800, wenxu@ucloud.cn wrote:
>> From: wenxu <wenxu@ucloud.cn>
>>
>> There will be zero one or serval actions for some expr. such as
>> payload set and immediate
>>
>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>> ---
>>  include/net/netfilter/nf_tables.h         | 7 ++++++-
>>  include/net/netfilter/nf_tables_offload.h | 2 --
>>  net/netfilter/nf_tables_offload.c         | 4 ++--
>>  net/netfilter/nft_immediate.c             | 2 +-
>>  4 files changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
>> index 9b62456..9285df2 100644
>> --- a/include/net/netfilter/nf_tables.h
>> +++ b/include/net/netfilter/nf_tables.h
>> @@ -785,7 +785,7 @@ struct nft_expr_ops {
>>  	int				(*offload)(struct nft_offload_ctx *ctx,
>>  						   struct nft_flow_rule *flow,
>>  						   const struct nft_expr *expr);
>> -	u32				offload_flags;
>> +	int				(*offload_actions)(const struct nft_expr *expr);
> I don't understand why you need to add this? is it for payload?


yes it is used for set payload  and immediately  actions. It maybe splited to several actions. The immediate action

may conatian 1 or 0 actions

>

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

end of thread, other threads:[~2019-07-25 10:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-23 12:52 [PATCH nf-next 0/7] netfilter: nf_tables_offload: support more actions wenxu
2019-07-23 12:52 ` [PATCH nf-next 1/7] netfilter: nf_flow_offload: add net in offload_ctx wenxu
2019-07-23 12:52 ` [PATCH nf-next 2/7] netfilter: nf_tables_offload: add offload_actions callback wenxu
2019-07-25 10:14   ` Pablo Neira Ayuso
2019-07-25 10:44     ` wenxu
2019-07-23 12:52 ` [PATCH nf-next 3/7] netfilter: nft_table_offload: Add rtnl for chain and rule operations wenxu
2019-07-25  9:48   ` Pablo Neira Ayuso
2019-07-25 10:14     ` Florian Westphal
2019-07-25 10:42       ` wenxu
2019-07-23 12:52 ` [PATCH nf-next 4/7] netfilter: nf_tables_offload: split nft_offload_reg to match and action type wenxu
2019-07-23 12:52 ` [PATCH nf-next 5/7] netfilter: nft_immediate: add offload support for actions wenxu
2019-07-23 12:52 ` [PATCH nf-next 6/7] netfilter: nft_fwd_netdev: add fw_netdev action support wenxu
2019-07-23 12:52 ` [PATCH nf-next 7/7] netfilter: nft_payload: add nft_set_payload offload support wenxu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.