netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf-next] netfilter: nf_tables_offload: support offload iif types meta offload
@ 2019-10-25  7:46 wenxu
  2019-10-28 15:05 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 4+ messages in thread
From: wenxu @ 2019-10-25  7:46 UTC (permalink / raw)
  To: pablo, fw; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

The offload basechain is based on ingress devices. The netdev chain can
bypass offload the iif types meta in the rule build status

The ether header payload match rely on the iiftype meta

nft --debug=netlink add rule netdev firewall zones ether daddr fa:ff:ff:ff:ff:ff
netdev firewall zones
  [ meta load iiftype => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 6b @ link header + 0 => reg 1 ]
  [ cmp eq reg 1 0xfffffffa 0x0000ffff ]

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

diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h
index 03cf585..1dcce48 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -19,12 +19,21 @@ enum nft_offload_dep_type {
 	NFT_OFFLOAD_DEP_TRANSPORT,
 };
 
+enum nft_offload_idevice_type {
+	NFT_OFFLOAD_IDEVICE_UNSPEC = 0,
+	NFT_OFFLOAD_IDEVICE_IIF,
+	NFT_OFFLOAD_IDEVICE_IIFTYPE,
+	NFT_OFFLOAD_IDEVICE_IIFGROUP,
+};
+
 struct nft_offload_ctx {
 	struct {
 		enum nft_offload_dep_type	type;
 		__be16				l3num;
 		u8				protonum;
 	} dep;
+	enum nft_offload_idevice_type		idevice_type;
+	struct list_head			*hook_list;
 	unsigned int				num_actions;
 	struct net				*net;
 	struct nft_offload_reg			regs[NFT_REG32_15 + 1];
@@ -34,6 +43,10 @@ void nft_offload_set_dependency(struct nft_offload_ctx *ctx,
 				enum nft_offload_dep_type type);
 void nft_offload_update_dependency(struct nft_offload_ctx *ctx,
 				   const void *data, u32 len);
+void nft_offload_set_idevice(struct nft_offload_ctx *ctx,
+			     enum nft_offload_idevice_type type);
+int nft_offload_check_idevice(struct nft_offload_ctx *ctx,
+			       const void *data, u32 len);
 
 struct nft_flow_key {
 	struct flow_dissector_key_basic			basic;
@@ -62,7 +75,9 @@ struct nft_flow_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);
+struct nft_flow_rule *nft_flow_rule_create(struct net *net,
+					   const struct nft_rule *rule,
+					   struct nft_chain *chain);
 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 13f0941..3990685 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3108,7 +3108,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(net, rule);
+		flow = nft_flow_rule_create(net, rule, chain);
 		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 4e0625c..bfa5ac5 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -29,8 +29,10 @@ static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions)
 }
 
 struct nft_flow_rule *nft_flow_rule_create(struct net *net,
-					   const struct nft_rule *rule)
+					   const struct nft_rule *rule,
+					   struct nft_chain *chain)
 {
+	struct nft_base_chain *basechain;
 	struct nft_offload_ctx *ctx;
 	struct nft_flow_rule *flow;
 	int num_actions = 0, err;
@@ -58,6 +60,9 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
 	ctx->net = net;
 	ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
 
+	basechain = nft_base_chain(chain);
+	ctx->hook_list = &basechain->hook_list;
+
 	while (expr->ops && expr != nft_expr_last(rule)) {
 		if (!expr->ops->offload) {
 			err = -EOPNOTSUPP;
@@ -123,6 +128,63 @@ void nft_offload_update_dependency(struct nft_offload_ctx *ctx,
 	ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
 }
 
+void nft_offload_set_idevice(struct nft_offload_ctx *ctx,
+			     enum nft_offload_idevice_type type)
+{
+	ctx->idevice_type = type;
+}
+
+int nft_offload_check_idevice(struct nft_offload_ctx *ctx,
+			      const void *data, u32 len)
+{
+	struct list_head *hook_list;
+	struct net_device *dev;
+	struct nft_hook *hook;
+	int ret = -EOPNOTSUPP;
+	__u32 data32;
+	__u16 data16;
+
+	hook_list = ctx->hook_list;
+	list_for_each_entry(hook, hook_list, list) {
+		dev = hook->ops.dev;
+
+		ret = 0;
+		switch (ctx->idevice_type) {
+		case NFT_OFFLOAD_IDEVICE_IIF:
+			WARN_ON(len != sizeof(__u32));
+			memcpy(&data32, data, sizeof(__u32));
+			if (data32 != dev->ifindex) {
+				ret = -EINVAL;
+				goto out;
+			}
+			break;
+		case NFT_OFFLOAD_IDEVICE_IIFTYPE:
+			WARN_ON(len != sizeof(__u16));
+			memcpy(&data16, data, sizeof(__u16));
+			if (data16 != dev->type) {
+				ret = -EINVAL;
+				goto out;
+			}
+			break;
+		case NFT_OFFLOAD_IDEVICE_IIFGROUP:
+			WARN_ON(len != sizeof(__u32));
+			memcpy(&data32, data, sizeof(__u32));
+			if (data32 != dev->group) {
+				ret = -EINVAL;
+				goto out;
+			}
+			break;
+		default:
+			ret = -EOPNOTSUPP;
+			goto out;
+		}
+	}
+
+out:
+	ctx->idevice_type = NFT_OFFLOAD_IDEVICE_UNSPEC;
+	return ret;
+}
+
 static void nft_flow_offload_common_init(struct flow_cls_common_offload *common,
 					 __be16 proto, int priority,
 					 struct netlink_ext_ack *extack)
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index bd173b1..25344bc 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -119,6 +119,9 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx,
 	if (priv->op != NFT_CMP_EQ)
 		return -EOPNOTSUPP;
 
+	if (ctx->idevice_type != NFT_OFFLOAD_IDEVICE_UNSPEC)
+		return nft_offload_check_idevice(ctx, &priv->data, priv->len);
+
 	memcpy(key + reg->offset, &priv->data, priv->len);
 	memcpy(mask + reg->offset, &reg->mask, priv->len);
 
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 317e3a9..1038dc8 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -547,6 +547,15 @@ static int nft_meta_get_offload(struct nft_offload_ctx *ctx,
 				  sizeof(__u8), reg);
 		nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
 		break;
+	case NFT_META_IIF:
+		nft_offload_set_idevice(ctx, NFT_OFFLOAD_IDEVICE_IIF);
+		break;
+	case NFT_META_IIFTYPE:
+		nft_offload_set_idevice(ctx, NFT_OFFLOAD_IDEVICE_IIFTYPE);
+		break;
+	case NFT_META_IIFGROUP:
+		nft_offload_set_idevice(ctx, NFT_OFFLOAD_IDEVICE_IIFGROUP);
+		break;
 	default:
 		return -EOPNOTSUPP;
 	}
-- 
1.8.3.1


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

* Re: [PATCH nf-next] netfilter: nf_tables_offload: support offload iif types meta offload
  2019-10-25  7:46 [PATCH nf-next] netfilter: nf_tables_offload: support offload iif types meta offload wenxu
@ 2019-10-28 15:05 ` Pablo Neira Ayuso
  2019-10-29  8:23   ` wenxu
  0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-10-28 15:05 UTC (permalink / raw)
  To: wenxu; +Cc: fw, netfilter-devel

Please, have a look at:

https://patchwork.ozlabs.org/patch/1185472/

for supporting iif matching.

Thanks.

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

* Re: [PATCH nf-next] netfilter: nf_tables_offload: support offload iif types meta offload
  2019-10-28 15:05 ` Pablo Neira Ayuso
@ 2019-10-29  8:23   ` wenxu
  2019-10-29  9:11     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 4+ messages in thread
From: wenxu @ 2019-10-29  8:23 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: fw, netfilter-devel

So it is better to extend the flow_dissector_key_meta to support iiftype match?


BR

wenxu

On 10/28/2019 11:05 PM, Pablo Neira Ayuso wrote:
> Please, have a look at:
>
> https://patchwork.ozlabs.org/patch/1185472/
>
> for supporting iif matching.
>
> Thanks.
>

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

* Re: [PATCH nf-next] netfilter: nf_tables_offload: support offload iif types meta offload
  2019-10-29  8:23   ` wenxu
@ 2019-10-29  9:11     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-10-29  9:11 UTC (permalink / raw)
  To: wenxu; +Cc: fw, netfilter-devel

On Tue, Oct 29, 2019 at 04:23:56PM +0800, wenxu wrote:
> So it is better to extend the flow_dissector_key_meta to support iiftype match?

This is what the patches that I'm just about to send are doing, yes.

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

end of thread, other threads:[~2019-10-29  9:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-25  7:46 [PATCH nf-next] netfilter: nf_tables_offload: support offload iif types meta offload wenxu
2019-10-28 15:05 ` Pablo Neira Ayuso
2019-10-29  8:23   ` wenxu
2019-10-29  9:11     ` 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).