netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload
@ 2019-11-21  9:54 wenxu
  2019-11-21  9:54 ` [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup wenxu
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: wenxu @ 2019-11-21  9:54 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

This patch provide tunnel offload based on route lwtunnel. 
The first two patches support indr callback setup
Then add tunnel match and action offload

The version already test with mlx driver as following:

ip link add user1 type vrf table 1
ip l set user1 up 
ip l set dev mlx_pf0vf1 down
ip l set dev mlx_pf0vf1 master user1
ifconfig mlx_pf0vf1 10.0.0.1/24 up

ifconfig mlx_p0 172.168.152.75/24 up

ip l add dev tun1 type gretap external
ip l set dev tun1 master user1
ifconfig tun1 10.0.1.1/24 up

ip r r 10.0.0.75 dev mlx_pf0vf1 table 1
ip r r 10.0.1.241 encap ip id 1000 dst 172.168.152.241 key dev tun1 table 1

nft add table firewall
nft add chain firewall zones { type filter hook prerouting priority - 300 \; }
nft add rule firewall zones counter ct zone set iif map { "tun1" : 1, "mlx_pf0vf1" : 1 }
nft add chain firewall rule-1000-ingress
nft add rule firewall rule-1000-ingress ct zone 1 ct state established,related counter accept
nft add rule firewall rule-1000-ingress ct zone 1 ct state invalid counter drop
nft add rule firewall rule-1000-ingress ct zone 1 tcp dport 5001 ct state new counter accept
nft add rule firewall rule-1000-ingress ct zone 1 udp dport 5001 ct state new counter accept
nft add rule firewall rule-1000-ingress ct zone 1 tcp dport 22 ct state new counter accept
nft add rule firewall rule-1000-ingress ct zone 1 ip protocol icmp ct state new counter accept
nft add rule firewall rule-1000-ingress counter drop
nft add chain firewall rules-all { type filter hook prerouting priority - 150 \; }
nft add rule firewall rules-all meta iifkind "vrf" counter accept
nft add rule firewall rules-all iif vmap { "tun1" : jump rule-1000-ingress }

nft add flowtable firewall fb1 { hook ingress priority 2 \; devices = { mlx_pf0vf1, tun1 } \; }
nft add chain firewall ftb-all {type filter hook forward priority 0 \; policy accept \; }
nft add rule firewall ftb-all ct zone 1 ip protocol tcp flow offload @fb1

wenxu (4):
  netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup
    to support indir setup
  netfilter: nf_flow_table_offload: add indr block setup support
  netfilter: nf_flow_table_offload: add tunnel match offload support
  netfilter: nf_flow_table_offload: add tunnel encap/decap action
    offload support

 net/netfilter/nf_flow_table_offload.c | 253 +++++++++++++++++++++++++++++++---
 1 file changed, 236 insertions(+), 17 deletions(-)

-- 
1.8.3.1


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

* [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup
  2019-11-21  9:54 [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
@ 2019-11-21  9:54 ` wenxu
  2019-11-21 12:36   ` wenxu
  2019-11-21  9:54 ` [PATCH nf-next v2 2/4] netfilter: nf_flow_table_offload: add indr block setup support wenxu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: wenxu @ 2019-11-21  9:54 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

Refactor nf_flow_table_offload_setup to support indir setup in
the next patch

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v2: no change

 net/netfilter/nf_flow_table_offload.c | 54 ++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index c00bb76..2d92043 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -801,26 +801,31 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
 	return err;
 }
 
-int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
-				struct net_device *dev,
-				enum flow_block_command cmd)
+static void nf_flow_table_block_offload_init(struct flow_block_offload *bo,
+					     struct net *net,
+					     enum flow_block_command cmd,
+					     struct nf_flowtable *flowtable,
+					     struct netlink_ext_ack *extack)
+{
+	memset(bo, 0, sizeof(*bo));
+	bo->net		= net;
+	bo->block	= &flowtable->flow_block;
+	bo->command	= cmd;
+	bo->binder_type	= FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
+	bo->extack	= extack;
+	INIT_LIST_HEAD(&bo->cb_list);
+}
+
+static int nf_flow_table_offload_cmd(struct nf_flowtable *flowtable,
+				     struct net_device *dev,
+				     enum flow_block_command cmd)
 {
 	struct netlink_ext_ack extack = {};
-	struct flow_block_offload bo = {};
+	struct flow_block_offload bo;
 	int err;
 
-	if (!(flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD))
-		return 0;
-
-	if (!dev->netdev_ops->ndo_setup_tc)
-		return -EOPNOTSUPP;
-
-	bo.net		= dev_net(dev);
-	bo.block	= &flowtable->flow_block;
-	bo.command	= cmd;
-	bo.binder_type	= FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
-	bo.extack	= &extack;
-	INIT_LIST_HEAD(&bo.cb_list);
+	nf_flow_table_block_offload_init(&bo, dev_net(dev), cmd, flowtable,
+					 &extack);
 
 	err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
 	if (err < 0)
@@ -828,6 +833,23 @@ int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
 
 	return nf_flow_table_block_setup(flowtable, &bo, cmd);
 }
+
+int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
+				struct net_device *dev,
+				enum flow_block_command cmd)
+{
+	int err;
+
+	if (!(flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD))
+		return 0;
+
+	if (dev->netdev_ops->ndo_setup_tc)
+		err = nf_flow_table_offload_cmd(flowtable, dev, cmd);
+	else
+		err = -EOPNOTSUPP;
+
+	return err;
+}
 EXPORT_SYMBOL_GPL(nf_flow_table_offload_setup);
 
 int nf_flow_table_offload_init(void)
-- 
1.8.3.1


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

* [PATCH nf-next v2 2/4] netfilter: nf_flow_table_offload: add indr block setup support
  2019-11-21  9:54 [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
  2019-11-21  9:54 ` [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup wenxu
@ 2019-11-21  9:54 ` wenxu
  2019-11-21 12:37   ` wenxu
  2019-11-21  9:54 ` [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support wenxu
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: wenxu @ 2019-11-21  9:54 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

Nf flow table support indr-block setup. It makes flow table offload vlan
and tunnel device.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v2: no change

 net/netfilter/nf_flow_table_offload.c | 89 ++++++++++++++++++++++++++++++++++-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 2d92043..653866f 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -7,6 +7,7 @@
 #include <linux/tc_act/tc_csum.h>
 #include <net/flow_offload.h>
 #include <net/netfilter/nf_flow_table.h>
+#include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_tuple.h>
@@ -834,6 +835,24 @@ static int nf_flow_table_offload_cmd(struct nf_flowtable *flowtable,
 	return nf_flow_table_block_setup(flowtable, &bo, cmd);
 }
 
+static int nf_flow_table_indr_offload_cmd(struct nf_flowtable *flowtable,
+					  struct net_device *dev,
+					  enum flow_block_command cmd)
+{
+	struct netlink_ext_ack extack = {};
+	struct flow_block_offload bo;
+
+	nf_flow_table_block_offload_init(&bo, dev_net(dev), cmd, flowtable,
+					 &extack);
+
+	flow_indr_block_call(dev, &bo, cmd);
+
+	if (list_empty(&bo.cb_list))
+		return -EOPNOTSUPP;
+
+	return nf_flow_table_block_setup(flowtable, &bo, cmd);
+}
+
 int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
 				struct net_device *dev,
 				enum flow_block_command cmd)
@@ -846,16 +865,82 @@ int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
 	if (dev->netdev_ops->ndo_setup_tc)
 		err = nf_flow_table_offload_cmd(flowtable, dev, cmd);
 	else
-		err = -EOPNOTSUPP;
+		err = nf_flow_table_indr_offload_cmd(flowtable, dev, cmd);
 
 	return err;
 }
 EXPORT_SYMBOL_GPL(nf_flow_table_offload_setup);
 
+static struct nf_flowtable *__nf_flow_table_offload_get(struct net_device *dev)
+{
+	struct nf_flowtable *n_flowtable;
+	struct nft_flowtable *flowtable;
+	struct net *net = dev_net(dev);
+	struct nft_table *table;
+	struct nft_hook *hook;
+
+	list_for_each_entry(table, &net->nft.tables, list) {
+		list_for_each_entry(flowtable, &table->flowtables, list) {
+			list_for_each_entry(hook, &flowtable->hook_list, list) {
+				if (hook->ops.dev != dev)
+					continue;
+
+				n_flowtable = &flowtable->data;
+				return n_flowtable;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static void nf_flow_table_indr_block_ing_cmd(struct net_device *dev,
+					     struct nf_flowtable *flowtable,
+					     flow_indr_block_bind_cb_t *cb,
+					     void *cb_priv,
+					     enum flow_block_command cmd)
+{
+	struct netlink_ext_ack extack = {};
+	struct flow_block_offload bo;
+
+	if (!flowtable)
+		return;
+
+	nf_flow_table_block_offload_init(&bo, dev_net(dev), cmd, flowtable,
+					 &extack);
+
+	cb(dev, cb_priv, TC_SETUP_BLOCK, &bo);
+
+	nf_flow_table_block_setup(flowtable, &bo, cmd);
+}
+
+static void nf_flow_table_indr_block_cb(struct net_device *dev,
+					flow_indr_block_bind_cb_t *cb,
+					void *cb_priv,
+					enum flow_block_command cmd)
+{
+	struct net *net = dev_net(dev);
+	struct nf_flowtable *flowtable;
+
+	mutex_lock(&net->nft.commit_mutex);
+	flowtable = __nf_flow_table_offload_get(dev);
+	if (flowtable)
+		nf_flow_table_indr_block_ing_cmd(dev, flowtable, cb, cb_priv,
+						 cmd);
+	mutex_unlock(&net->nft.commit_mutex);
+}
+
+static struct flow_indr_block_ing_entry block_ing_entry = {
+	.cb	= nf_flow_table_indr_block_cb,
+	.list	= LIST_HEAD_INIT(block_ing_entry.list),
+};
+
 int nf_flow_table_offload_init(void)
 {
 	INIT_WORK(&nf_flow_offload_work, flow_offload_work_handler);
 
+	flow_indr_add_block_ing_cb(&block_ing_entry);
+
 	return 0;
 }
 
@@ -864,6 +949,8 @@ void nf_flow_table_offload_exit(void)
 	struct flow_offload_work *offload, *next;
 	LIST_HEAD(offload_pending_list);
 
+	flow_indr_del_block_ing_cb(&block_ing_entry);
+
 	cancel_work_sync(&nf_flow_offload_work);
 
 	list_for_each_entry_safe(offload, next, &offload_pending_list, list) {
-- 
1.8.3.1


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

* [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support
  2019-11-21  9:54 [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
  2019-11-21  9:54 ` [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup wenxu
  2019-11-21  9:54 ` [PATCH nf-next v2 2/4] netfilter: nf_flow_table_offload: add indr block setup support wenxu
@ 2019-11-21  9:54 ` wenxu
  2019-11-21 12:37   ` wenxu
  2019-11-24 21:07   ` kbuild test robot
  2019-11-21  9:54 ` [PATCH nf-next v2 4/4] netfilter: nf_flow_table_offload: add tunnel encap/decap action " wenxu
  2019-11-21 12:36 ` [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
  4 siblings, 2 replies; 11+ messages in thread
From: wenxu @ 2019-11-21  9:54 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

This patch support both ipv4 and ipv6 tunnel_id, tunnel_src and
tunnel_dst match for flowtable offload

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v2: add ecn_control to match outer addr

 net/netfilter/nf_flow_table_offload.c | 67 +++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 653866f..656095c 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -26,10 +26,16 @@ struct flow_offload_work {
 
 struct nf_flow_key {
 	struct flow_dissector_key_control		control;
+	struct flow_dissector_key_control               enc_control;
 	struct flow_dissector_key_basic			basic;
 	union {
 		struct flow_dissector_key_ipv4_addrs	ipv4;
 	};
+	struct flow_dissector_key_keyid			enc_key_id;
+	union {
+		struct flow_dissector_key_ipv4_addrs	enc_ipv4;
+		struct flow_dissector_key_ipv6_addrs	enc_ipv6;
+	};
 	struct flow_dissector_key_tcp			tcp;
 	struct flow_dissector_key_ports			tp;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
@@ -49,11 +55,61 @@ struct nf_flow_rule {
 	(__match)->dissector.offset[__type] =		\
 		offsetof(struct nf_flow_key, __field)
 
+static void nf_flow_rule_lwt_match(struct nf_flow_match *match,
+				   struct ip_tunnel_info *tun_info)
+{
+	struct nf_flow_key *mask = &match->mask;
+	struct nf_flow_key *key = &match->key;
+	unsigned int enc_keys;
+
+	if (!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX))
+		return;
+
+	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_CONTROL, enc_control);
+	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
+	key->enc_key_id.keyid = tunnel_id_to_key32(tun_info->key.tun_id);
+	mask->enc_key_id.keyid = 0xffffffff;
+	enc_keys = BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) |
+		   BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL);
+
+	if (ip_tunnel_info_af(tun_info) == AF_INET) {
+		NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
+				  enc_ipv4);
+		key->enc_ipv4.src = tun_info->key.u.ipv4.dst;
+		key->enc_ipv4.dst = tun_info->key.u.ipv4.src;
+		if (key->enc_ipv4.src)
+			mask->enc_ipv4.src = 0xffffffff;
+		if (key->enc_ipv4.dst)
+			mask->enc_ipv4.dst = 0xffffffff;
+		enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS);
+		key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+	} else {
+		memcpy(&key->enc_ipv6.src, &tun_info->key.u.ipv6.dst,
+		       sizeof(struct in6_addr));
+		memcpy(&key->enc_ipv6.dst, &tun_info->key.u.ipv6.src,
+		       sizeof(struct in6_addr));
+		if (memcmp(&key->enc_ipv6.src, &in6addr_any,
+			   sizeof(struct in6_addr)))
+			memset(&key->enc_ipv6.src, 0xff,
+			       sizeof(struct in6_addr));
+		if (memcmp(&key->enc_ipv6.dst, &in6addr_any,
+			   sizeof(struct in6_addr)))
+			memset(&key->enc_ipv6.dst, 0xff,
+			       sizeof(struct in6_addr));
+		enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS);
+		key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+	}
+
+	match->dissector.used_keys |= enc_keys;
+}
+
 static int nf_flow_rule_match(struct nf_flow_match *match,
-			      const struct flow_offload_tuple *tuple)
+			      const struct flow_offload_tuple *tuple,
+			      struct dst_entry *other_dst)
 {
 	struct nf_flow_key *mask = &match->mask;
 	struct nf_flow_key *key = &match->key;
+	struct ip_tunnel_info *tun_info;
 
 	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_CONTROL, control);
 	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_BASIC, basic);
@@ -61,6 +117,11 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
 	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_TCP, tcp);
 	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_PORTS, tp);
 
+	if (other_dst->lwtstate) {
+		tun_info = lwt_tun_info(other_dst->lwtstate);
+		nf_flow_rule_lwt_match(match, tun_info);
+	}
+
 	switch (tuple->l3proto) {
 	case AF_INET:
 		key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
@@ -468,6 +529,7 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
 	const struct flow_offload *flow = offload->flow;
 	const struct flow_offload_tuple *tuple;
 	struct nf_flow_rule *flow_rule;
+	struct dst_entry *other_dst;
 	int err = -ENOMEM;
 
 	flow_rule = kzalloc(sizeof(*flow_rule), GFP_KERNEL);
@@ -483,7 +545,8 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
 	flow_rule->rule->match.key = &flow_rule->match.key;
 
 	tuple = &flow->tuplehash[dir].tuple;
-	err = nf_flow_rule_match(&flow_rule->match, tuple);
+	other_dst = flow->tuplehash[!dir].tuple.dst_cache;
+	err = nf_flow_rule_match(&flow_rule->match, tuple, other_dst);
 	if (err < 0)
 		goto err_flow_match;
 
-- 
1.8.3.1


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

* [PATCH nf-next v2 4/4] netfilter: nf_flow_table_offload: add tunnel encap/decap action offload support
  2019-11-21  9:54 [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
                   ` (2 preceding siblings ...)
  2019-11-21  9:54 ` [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support wenxu
@ 2019-11-21  9:54 ` wenxu
  2019-11-21 12:38   ` wenxu
  2019-11-21 12:36 ` [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
  4 siblings, 1 reply; 11+ messages in thread
From: wenxu @ 2019-11-21  9:54 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

From: wenxu <wenxu@ucloud.cn>

This patch add tunnel encap decap action offload in the flowtable
offload.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
v2: put encap/decap action before redirect action

 net/netfilter/nf_flow_table_offload.c | 47 +++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 656095c..36a5103 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -469,6 +469,45 @@ static void flow_offload_redirect(const struct flow_offload *flow,
 	dev_hold(rt->dst.dev);
 }
 
+static void flow_offload_encap_tunnel(const struct flow_offload *flow,
+				      enum flow_offload_tuple_dir dir,
+				      struct nf_flow_rule *flow_rule)
+{
+	struct flow_action_entry *entry;
+	struct dst_entry *dst;
+
+	dst = flow->tuplehash[dir].tuple.dst_cache;
+	if (dst->lwtstate) {
+		struct ip_tunnel_info *tun_info;
+
+		tun_info = lwt_tun_info(dst->lwtstate);
+		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX)) {
+			entry = flow_action_entry_next(flow_rule);
+			entry->id = FLOW_ACTION_TUNNEL_ENCAP;
+			entry->tunnel = tun_info;
+		}
+	}
+}
+
+static void flow_offload_decap_tunnel(const struct flow_offload *flow,
+				      enum flow_offload_tuple_dir dir,
+				      struct nf_flow_rule *flow_rule)
+{
+	struct flow_action_entry *entry;
+	struct dst_entry *dst;
+
+	dst = flow->tuplehash[!dir].tuple.dst_cache;
+	if (dst->lwtstate) {
+		struct ip_tunnel_info *tun_info;
+
+		tun_info = lwt_tun_info(dst->lwtstate);
+		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX)) {
+			entry = flow_action_entry_next(flow_rule);
+			entry->id = FLOW_ACTION_TUNNEL_DECAP;
+		}
+	}
+}
+
 int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
 			    enum flow_offload_tuple_dir dir,
 			    struct nf_flow_rule *flow_rule)
@@ -489,6 +528,10 @@ int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
 	    flow->flags & FLOW_OFFLOAD_DNAT)
 		flow_offload_ipv4_checksum(net, flow, flow_rule);
 
+	flow_offload_encap_tunnel(flow, dir, flow_rule);
+
+	flow_offload_decap_tunnel(flow, dir, flow_rule);
+
 	flow_offload_redirect(flow, dir, flow_rule);
 
 	return 0;
@@ -512,6 +555,10 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
 		flow_offload_port_dnat(net, flow, dir, flow_rule);
 	}
 
+	flow_offload_encap_tunnel(flow, dir, flow_rule);
+
+	flow_offload_decap_tunnel(flow, dir, flow_rule);
+
 	flow_offload_redirect(flow, dir, flow_rule);
 
 	return 0;
-- 
1.8.3.1


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

* Re: [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload
  2019-11-21  9:54 [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
                   ` (3 preceding siblings ...)
  2019-11-21  9:54 ` [PATCH nf-next v2 4/4] netfilter: nf_flow_table_offload: add tunnel encap/decap action " wenxu
@ 2019-11-21 12:36 ` wenxu
  4 siblings, 0 replies; 11+ messages in thread
From: wenxu @ 2019-11-21 12:36 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, Paul Blakey

cc Paul

在 2019/11/21 17:54, wenxu@ucloud.cn 写道:
> From: wenxu <wenxu@ucloud.cn>
>
> This patch provide tunnel offload based on route lwtunnel. 
> The first two patches support indr callback setup
> Then add tunnel match and action offload
>
> The version already test with mlx driver as following:
>
> ip link add user1 type vrf table 1
> ip l set user1 up 
> ip l set dev mlx_pf0vf1 down
> ip l set dev mlx_pf0vf1 master user1
> ifconfig mlx_pf0vf1 10.0.0.1/24 up
>
> ifconfig mlx_p0 172.168.152.75/24 up
>
> ip l add dev tun1 type gretap external
> ip l set dev tun1 master user1
> ifconfig tun1 10.0.1.1/24 up
>
> ip r r 10.0.0.75 dev mlx_pf0vf1 table 1
> ip r r 10.0.1.241 encap ip id 1000 dst 172.168.152.241 key dev tun1 table 1
>
> nft add table firewall
> nft add chain firewall zones { type filter hook prerouting priority - 300 \; }
> nft add rule firewall zones counter ct zone set iif map { "tun1" : 1, "mlx_pf0vf1" : 1 }
> nft add chain firewall rule-1000-ingress
> nft add rule firewall rule-1000-ingress ct zone 1 ct state established,related counter accept
> nft add rule firewall rule-1000-ingress ct zone 1 ct state invalid counter drop
> nft add rule firewall rule-1000-ingress ct zone 1 tcp dport 5001 ct state new counter accept
> nft add rule firewall rule-1000-ingress ct zone 1 udp dport 5001 ct state new counter accept
> nft add rule firewall rule-1000-ingress ct zone 1 tcp dport 22 ct state new counter accept
> nft add rule firewall rule-1000-ingress ct zone 1 ip protocol icmp ct state new counter accept
> nft add rule firewall rule-1000-ingress counter drop
> nft add chain firewall rules-all { type filter hook prerouting priority - 150 \; }
> nft add rule firewall rules-all meta iifkind "vrf" counter accept
> nft add rule firewall rules-all iif vmap { "tun1" : jump rule-1000-ingress }
>
> nft add flowtable firewall fb1 { hook ingress priority 2 \; devices = { mlx_pf0vf1, tun1 } \; }
> nft add chain firewall ftb-all {type filter hook forward priority 0 \; policy accept \; }
> nft add rule firewall ftb-all ct zone 1 ip protocol tcp flow offload @fb1
>
> wenxu (4):
>   netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup
>     to support indir setup
>   netfilter: nf_flow_table_offload: add indr block setup support
>   netfilter: nf_flow_table_offload: add tunnel match offload support
>   netfilter: nf_flow_table_offload: add tunnel encap/decap action
>     offload support
>
>  net/netfilter/nf_flow_table_offload.c | 253 +++++++++++++++++++++++++++++++---
>  1 file changed, 236 insertions(+), 17 deletions(-)
>

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

* Re: [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup
  2019-11-21  9:54 ` [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup wenxu
@ 2019-11-21 12:36   ` wenxu
  0 siblings, 0 replies; 11+ messages in thread
From: wenxu @ 2019-11-21 12:36 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, Paul Blakey


在 2019/11/21 17:54, wenxu@ucloud.cn 写道:
> From: wenxu <wenxu@ucloud.cn>
>
> Refactor nf_flow_table_offload_setup to support indir setup in
> the next patch
>
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
> v2: no change
>
>  net/netfilter/nf_flow_table_offload.c | 54 ++++++++++++++++++++++++-----------
>  1 file changed, 38 insertions(+), 16 deletions(-)
>
> diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
> index c00bb76..2d92043 100644
> --- a/net/netfilter/nf_flow_table_offload.c
> +++ b/net/netfilter/nf_flow_table_offload.c
> @@ -801,26 +801,31 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
>  	return err;
>  }
>  
> -int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
> -				struct net_device *dev,
> -				enum flow_block_command cmd)
> +static void nf_flow_table_block_offload_init(struct flow_block_offload *bo,
> +					     struct net *net,
> +					     enum flow_block_command cmd,
> +					     struct nf_flowtable *flowtable,
> +					     struct netlink_ext_ack *extack)
> +{
> +	memset(bo, 0, sizeof(*bo));
> +	bo->net		= net;
> +	bo->block	= &flowtable->flow_block;
> +	bo->command	= cmd;
> +	bo->binder_type	= FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
> +	bo->extack	= extack;
> +	INIT_LIST_HEAD(&bo->cb_list);
> +}
> +
> +static int nf_flow_table_offload_cmd(struct nf_flowtable *flowtable,
> +				     struct net_device *dev,
> +				     enum flow_block_command cmd)
>  {
>  	struct netlink_ext_ack extack = {};
> -	struct flow_block_offload bo = {};
> +	struct flow_block_offload bo;
>  	int err;
>  
> -	if (!(flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD))
> -		return 0;
> -
> -	if (!dev->netdev_ops->ndo_setup_tc)
> -		return -EOPNOTSUPP;
> -
> -	bo.net		= dev_net(dev);
> -	bo.block	= &flowtable->flow_block;
> -	bo.command	= cmd;
> -	bo.binder_type	= FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
> -	bo.extack	= &extack;
> -	INIT_LIST_HEAD(&bo.cb_list);
> +	nf_flow_table_block_offload_init(&bo, dev_net(dev), cmd, flowtable,
> +					 &extack);
>  
>  	err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
>  	if (err < 0)
> @@ -828,6 +833,23 @@ int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
>  
>  	return nf_flow_table_block_setup(flowtable, &bo, cmd);
>  }
> +
> +int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
> +				struct net_device *dev,
> +				enum flow_block_command cmd)
> +{
> +	int err;
> +
> +	if (!(flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD))
> +		return 0;
> +
> +	if (dev->netdev_ops->ndo_setup_tc)
> +		err = nf_flow_table_offload_cmd(flowtable, dev, cmd);
> +	else
> +		err = -EOPNOTSUPP;
> +
> +	return err;
> +}
>  EXPORT_SYMBOL_GPL(nf_flow_table_offload_setup);
>  
>  int nf_flow_table_offload_init(void)

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

* Re: [PATCH nf-next v2 2/4] netfilter: nf_flow_table_offload: add indr block setup support
  2019-11-21  9:54 ` [PATCH nf-next v2 2/4] netfilter: nf_flow_table_offload: add indr block setup support wenxu
@ 2019-11-21 12:37   ` wenxu
  0 siblings, 0 replies; 11+ messages in thread
From: wenxu @ 2019-11-21 12:37 UTC (permalink / raw)
  Cc: netfilter-devel, Paul Blakey


在 2019/11/21 17:54, wenxu@ucloud.cn 写道:
> From: wenxu <wenxu@ucloud.cn>
>
> Nf flow table support indr-block setup. It makes flow table offload vlan
> and tunnel device.
>
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
> v2: no change
>
>  net/netfilter/nf_flow_table_offload.c | 89 ++++++++++++++++++++++++++++++++++-
>  1 file changed, 88 insertions(+), 1 deletion(-)
>
> diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
> index 2d92043..653866f 100644
> --- a/net/netfilter/nf_flow_table_offload.c
> +++ b/net/netfilter/nf_flow_table_offload.c
> @@ -7,6 +7,7 @@
>  #include <linux/tc_act/tc_csum.h>
>  #include <net/flow_offload.h>
>  #include <net/netfilter/nf_flow_table.h>
> +#include <net/netfilter/nf_tables.h>
>  #include <net/netfilter/nf_conntrack.h>
>  #include <net/netfilter/nf_conntrack_core.h>
>  #include <net/netfilter/nf_conntrack_tuple.h>
> @@ -834,6 +835,24 @@ static int nf_flow_table_offload_cmd(struct nf_flowtable *flowtable,
>  	return nf_flow_table_block_setup(flowtable, &bo, cmd);
>  }
>  
> +static int nf_flow_table_indr_offload_cmd(struct nf_flowtable *flowtable,
> +					  struct net_device *dev,
> +					  enum flow_block_command cmd)
> +{
> +	struct netlink_ext_ack extack = {};
> +	struct flow_block_offload bo;
> +
> +	nf_flow_table_block_offload_init(&bo, dev_net(dev), cmd, flowtable,
> +					 &extack);
> +
> +	flow_indr_block_call(dev, &bo, cmd);
> +
> +	if (list_empty(&bo.cb_list))
> +		return -EOPNOTSUPP;
> +
> +	return nf_flow_table_block_setup(flowtable, &bo, cmd);
> +}
> +
>  int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
>  				struct net_device *dev,
>  				enum flow_block_command cmd)
> @@ -846,16 +865,82 @@ int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
>  	if (dev->netdev_ops->ndo_setup_tc)
>  		err = nf_flow_table_offload_cmd(flowtable, dev, cmd);
>  	else
> -		err = -EOPNOTSUPP;
> +		err = nf_flow_table_indr_offload_cmd(flowtable, dev, cmd);
>  
>  	return err;
>  }
>  EXPORT_SYMBOL_GPL(nf_flow_table_offload_setup);
>  
> +static struct nf_flowtable *__nf_flow_table_offload_get(struct net_device *dev)
> +{
> +	struct nf_flowtable *n_flowtable;
> +	struct nft_flowtable *flowtable;
> +	struct net *net = dev_net(dev);
> +	struct nft_table *table;
> +	struct nft_hook *hook;
> +
> +	list_for_each_entry(table, &net->nft.tables, list) {
> +		list_for_each_entry(flowtable, &table->flowtables, list) {
> +			list_for_each_entry(hook, &flowtable->hook_list, list) {
> +				if (hook->ops.dev != dev)
> +					continue;
> +
> +				n_flowtable = &flowtable->data;
> +				return n_flowtable;
> +			}
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +static void nf_flow_table_indr_block_ing_cmd(struct net_device *dev,
> +					     struct nf_flowtable *flowtable,
> +					     flow_indr_block_bind_cb_t *cb,
> +					     void *cb_priv,
> +					     enum flow_block_command cmd)
> +{
> +	struct netlink_ext_ack extack = {};
> +	struct flow_block_offload bo;
> +
> +	if (!flowtable)
> +		return;
> +
> +	nf_flow_table_block_offload_init(&bo, dev_net(dev), cmd, flowtable,
> +					 &extack);
> +
> +	cb(dev, cb_priv, TC_SETUP_BLOCK, &bo);
> +
> +	nf_flow_table_block_setup(flowtable, &bo, cmd);
> +}
> +
> +static void nf_flow_table_indr_block_cb(struct net_device *dev,
> +					flow_indr_block_bind_cb_t *cb,
> +					void *cb_priv,
> +					enum flow_block_command cmd)
> +{
> +	struct net *net = dev_net(dev);
> +	struct nf_flowtable *flowtable;
> +
> +	mutex_lock(&net->nft.commit_mutex);
> +	flowtable = __nf_flow_table_offload_get(dev);
> +	if (flowtable)
> +		nf_flow_table_indr_block_ing_cmd(dev, flowtable, cb, cb_priv,
> +						 cmd);
> +	mutex_unlock(&net->nft.commit_mutex);
> +}
> +
> +static struct flow_indr_block_ing_entry block_ing_entry = {
> +	.cb	= nf_flow_table_indr_block_cb,
> +	.list	= LIST_HEAD_INIT(block_ing_entry.list),
> +};
> +
>  int nf_flow_table_offload_init(void)
>  {
>  	INIT_WORK(&nf_flow_offload_work, flow_offload_work_handler);
>  
> +	flow_indr_add_block_ing_cb(&block_ing_entry);
> +
>  	return 0;
>  }
>  
> @@ -864,6 +949,8 @@ void nf_flow_table_offload_exit(void)
>  	struct flow_offload_work *offload, *next;
>  	LIST_HEAD(offload_pending_list);
>  
> +	flow_indr_del_block_ing_cb(&block_ing_entry);
> +
>  	cancel_work_sync(&nf_flow_offload_work);
>  
>  	list_for_each_entry_safe(offload, next, &offload_pending_list, list) {

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

* Re: [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support
  2019-11-21  9:54 ` [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support wenxu
@ 2019-11-21 12:37   ` wenxu
  2019-11-24 21:07   ` kbuild test robot
  1 sibling, 0 replies; 11+ messages in thread
From: wenxu @ 2019-11-21 12:37 UTC (permalink / raw)
  Cc: netfilter-devel, paulb@mellanox.com >> Paul Blakey


在 2019/11/21 17:54, wenxu@ucloud.cn 写道:
> From: wenxu <wenxu@ucloud.cn>
>
> This patch support both ipv4 and ipv6 tunnel_id, tunnel_src and
> tunnel_dst match for flowtable offload
>
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
> v2: add ecn_control to match outer addr
>
>  net/netfilter/nf_flow_table_offload.c | 67 +++++++++++++++++++++++++++++++++--
>  1 file changed, 65 insertions(+), 2 deletions(-)
>
> diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
> index 653866f..656095c 100644
> --- a/net/netfilter/nf_flow_table_offload.c
> +++ b/net/netfilter/nf_flow_table_offload.c
> @@ -26,10 +26,16 @@ struct flow_offload_work {
>  
>  struct nf_flow_key {
>  	struct flow_dissector_key_control		control;
> +	struct flow_dissector_key_control               enc_control;
>  	struct flow_dissector_key_basic			basic;
>  	union {
>  		struct flow_dissector_key_ipv4_addrs	ipv4;
>  	};
> +	struct flow_dissector_key_keyid			enc_key_id;
> +	union {
> +		struct flow_dissector_key_ipv4_addrs	enc_ipv4;
> +		struct flow_dissector_key_ipv6_addrs	enc_ipv6;
> +	};
>  	struct flow_dissector_key_tcp			tcp;
>  	struct flow_dissector_key_ports			tp;
>  } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
> @@ -49,11 +55,61 @@ struct nf_flow_rule {
>  	(__match)->dissector.offset[__type] =		\
>  		offsetof(struct nf_flow_key, __field)
>  
> +static void nf_flow_rule_lwt_match(struct nf_flow_match *match,
> +				   struct ip_tunnel_info *tun_info)
> +{
> +	struct nf_flow_key *mask = &match->mask;
> +	struct nf_flow_key *key = &match->key;
> +	unsigned int enc_keys;
> +
> +	if (!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX))
> +		return;
> +
> +	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_CONTROL, enc_control);
> +	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
> +	key->enc_key_id.keyid = tunnel_id_to_key32(tun_info->key.tun_id);
> +	mask->enc_key_id.keyid = 0xffffffff;
> +	enc_keys = BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) |
> +		   BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL);
> +
> +	if (ip_tunnel_info_af(tun_info) == AF_INET) {
> +		NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
> +				  enc_ipv4);
> +		key->enc_ipv4.src = tun_info->key.u.ipv4.dst;
> +		key->enc_ipv4.dst = tun_info->key.u.ipv4.src;
> +		if (key->enc_ipv4.src)
> +			mask->enc_ipv4.src = 0xffffffff;
> +		if (key->enc_ipv4.dst)
> +			mask->enc_ipv4.dst = 0xffffffff;
> +		enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS);
> +		key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
> +	} else {
> +		memcpy(&key->enc_ipv6.src, &tun_info->key.u.ipv6.dst,
> +		       sizeof(struct in6_addr));
> +		memcpy(&key->enc_ipv6.dst, &tun_info->key.u.ipv6.src,
> +		       sizeof(struct in6_addr));
> +		if (memcmp(&key->enc_ipv6.src, &in6addr_any,
> +			   sizeof(struct in6_addr)))
> +			memset(&key->enc_ipv6.src, 0xff,
> +			       sizeof(struct in6_addr));
> +		if (memcmp(&key->enc_ipv6.dst, &in6addr_any,
> +			   sizeof(struct in6_addr)))
> +			memset(&key->enc_ipv6.dst, 0xff,
> +			       sizeof(struct in6_addr));
> +		enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS);
> +		key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
> +	}
> +
> +	match->dissector.used_keys |= enc_keys;
> +}
> +
>  static int nf_flow_rule_match(struct nf_flow_match *match,
> -			      const struct flow_offload_tuple *tuple)
> +			      const struct flow_offload_tuple *tuple,
> +			      struct dst_entry *other_dst)
>  {
>  	struct nf_flow_key *mask = &match->mask;
>  	struct nf_flow_key *key = &match->key;
> +	struct ip_tunnel_info *tun_info;
>  
>  	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_CONTROL, control);
>  	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_BASIC, basic);
> @@ -61,6 +117,11 @@ static int nf_flow_rule_match(struct nf_flow_match *match,
>  	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_TCP, tcp);
>  	NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_PORTS, tp);
>  
> +	if (other_dst->lwtstate) {
> +		tun_info = lwt_tun_info(other_dst->lwtstate);
> +		nf_flow_rule_lwt_match(match, tun_info);
> +	}
> +
>  	switch (tuple->l3proto) {
>  	case AF_INET:
>  		key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
> @@ -468,6 +529,7 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
>  	const struct flow_offload *flow = offload->flow;
>  	const struct flow_offload_tuple *tuple;
>  	struct nf_flow_rule *flow_rule;
> +	struct dst_entry *other_dst;
>  	int err = -ENOMEM;
>  
>  	flow_rule = kzalloc(sizeof(*flow_rule), GFP_KERNEL);
> @@ -483,7 +545,8 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
>  	flow_rule->rule->match.key = &flow_rule->match.key;
>  
>  	tuple = &flow->tuplehash[dir].tuple;
> -	err = nf_flow_rule_match(&flow_rule->match, tuple);
> +	other_dst = flow->tuplehash[!dir].tuple.dst_cache;
> +	err = nf_flow_rule_match(&flow_rule->match, tuple, other_dst);
>  	if (err < 0)
>  		goto err_flow_match;
>  

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

* Re: [PATCH nf-next v2 4/4] netfilter: nf_flow_table_offload: add tunnel encap/decap action offload support
  2019-11-21  9:54 ` [PATCH nf-next v2 4/4] netfilter: nf_flow_table_offload: add tunnel encap/decap action " wenxu
@ 2019-11-21 12:38   ` wenxu
  0 siblings, 0 replies; 11+ messages in thread
From: wenxu @ 2019-11-21 12:38 UTC (permalink / raw)
  Cc: netfilter-devel, Paul Blakey

Hi paul,

encap in this patch.

在 2019/11/21 17:54, wenxu@ucloud.cn 写道:
> From: wenxu <wenxu@ucloud.cn>
>
> This patch add tunnel encap decap action offload in the flowtable
> offload.
>
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
> v2: put encap/decap action before redirect action
>
>  net/netfilter/nf_flow_table_offload.c | 47 +++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
> index 656095c..36a5103 100644
> --- a/net/netfilter/nf_flow_table_offload.c
> +++ b/net/netfilter/nf_flow_table_offload.c
> @@ -469,6 +469,45 @@ static void flow_offload_redirect(const struct flow_offload *flow,
>  	dev_hold(rt->dst.dev);
>  }
>  
> +static void flow_offload_encap_tunnel(const struct flow_offload *flow,
> +				      enum flow_offload_tuple_dir dir,
> +				      struct nf_flow_rule *flow_rule)
> +{
> +	struct flow_action_entry *entry;
> +	struct dst_entry *dst;
> +
> +	dst = flow->tuplehash[dir].tuple.dst_cache;
> +	if (dst->lwtstate) {
> +		struct ip_tunnel_info *tun_info;
> +
> +		tun_info = lwt_tun_info(dst->lwtstate);
> +		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX)) {
> +			entry = flow_action_entry_next(flow_rule);
> +			entry->id = FLOW_ACTION_TUNNEL_ENCAP;
> +			entry->tunnel = tun_info;
> +		}
> +	}
> +}
> +
> +static void flow_offload_decap_tunnel(const struct flow_offload *flow,
> +				      enum flow_offload_tuple_dir dir,
> +				      struct nf_flow_rule *flow_rule)
> +{
> +	struct flow_action_entry *entry;
> +	struct dst_entry *dst;
> +
> +	dst = flow->tuplehash[!dir].tuple.dst_cache;
> +	if (dst->lwtstate) {
> +		struct ip_tunnel_info *tun_info;
> +
> +		tun_info = lwt_tun_info(dst->lwtstate);
> +		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX)) {
> +			entry = flow_action_entry_next(flow_rule);
> +			entry->id = FLOW_ACTION_TUNNEL_DECAP;
> +		}
> +	}
> +}
> +
>  int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
>  			    enum flow_offload_tuple_dir dir,
>  			    struct nf_flow_rule *flow_rule)
> @@ -489,6 +528,10 @@ int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
>  	    flow->flags & FLOW_OFFLOAD_DNAT)
>  		flow_offload_ipv4_checksum(net, flow, flow_rule);
>  
> +	flow_offload_encap_tunnel(flow, dir, flow_rule);
> +
> +	flow_offload_decap_tunnel(flow, dir, flow_rule);
> +
>  	flow_offload_redirect(flow, dir, flow_rule);
>  
>  	return 0;
> @@ -512,6 +555,10 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
>  		flow_offload_port_dnat(net, flow, dir, flow_rule);
>  	}
>  
> +	flow_offload_encap_tunnel(flow, dir, flow_rule);
> +
> +	flow_offload_decap_tunnel(flow, dir, flow_rule);
> +
>  	flow_offload_redirect(flow, dir, flow_rule);
>  
>  	return 0;

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

* Re: [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support
  2019-11-21  9:54 ` [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support wenxu
  2019-11-21 12:37   ` wenxu
@ 2019-11-24 21:07   ` kbuild test robot
  1 sibling, 0 replies; 11+ messages in thread
From: kbuild test robot @ 2019-11-24 21:07 UTC (permalink / raw)
  To: wenxu; +Cc: kbuild-all, pablo, netfilter-devel

Hi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on nf-next/master]
[also build test WARNING on next-20191122]
[cannot apply to v5.4-rc8]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/wenxu-ucloud-cn/netfilter-nf_flow_table_offload-support-tunnel-offload/20191123-192226
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-36-g9305d48-dirty
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)

>> net/netfilter/nf_flow_table_offload.c:71:32: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be32 [usertype] keyid @@    got  [usertype] keyid @@
>> net/netfilter/nf_flow_table_offload.c:71:32: sparse:    expected restricted __be32 [usertype] keyid
   net/netfilter/nf_flow_table_offload.c:71:32: sparse:    got unsigned int
   net/netfilter/nf_flow_table_offload.c:81:44: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be32 [usertype] src @@    got  [usertype] src @@
   net/netfilter/nf_flow_table_offload.c:81:44: sparse:    expected restricted __be32 [usertype] src
   net/netfilter/nf_flow_table_offload.c:81:44: sparse:    got unsigned int
   net/netfilter/nf_flow_table_offload.c:83:44: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be32 [usertype] dst @@    got  [usertype] dst @@
   net/netfilter/nf_flow_table_offload.c:83:44: sparse:    expected restricted __be32 [usertype] dst
   net/netfilter/nf_flow_table_offload.c:83:44: sparse:    got unsigned int
   net/netfilter/nf_flow_table_offload.c:130:32: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be32 [usertype] src @@    got  [usertype] src @@
   net/netfilter/nf_flow_table_offload.c:130:32: sparse:    expected restricted __be32 [usertype] src
   net/netfilter/nf_flow_table_offload.c:130:32: sparse:    got unsigned int
   net/netfilter/nf_flow_table_offload.c:132:32: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be32 [usertype] dst @@    got  [usertype] dst @@
   net/netfilter/nf_flow_table_offload.c:132:32: sparse:    expected restricted __be32 [usertype] dst
   net/netfilter/nf_flow_table_offload.c:132:32: sparse:    got unsigned int
   net/netfilter/nf_flow_table_offload.c:137:29: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] n_proto @@    got e] n_proto @@
   net/netfilter/nf_flow_table_offload.c:137:29: sparse:    expected restricted __be16 [usertype] n_proto
   net/netfilter/nf_flow_table_offload.c:137:29: sparse:    got int
   net/netfilter/nf_flow_table_offload.c:142:33: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] flags @@    got _be16 [usertype] flags @@
   net/netfilter/nf_flow_table_offload.c:142:33: sparse:    expected restricted __be16 [usertype] flags
   net/netfilter/nf_flow_table_offload.c:142:33: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:155:22: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] src @@    got e] src @@
   net/netfilter/nf_flow_table_offload.c:155:22: sparse:    expected restricted __be16 [usertype] src
   net/netfilter/nf_flow_table_offload.c:155:22: sparse:    got int
   net/netfilter/nf_flow_table_offload.c:157:22: sparse: sparse: incorrect type in assignment (different base types) @@    expected restricted __be16 [usertype] dst @@    got e] dst @@
   net/netfilter/nf_flow_table_offload.c:157:22: sparse:    expected restricted __be16 [usertype] dst
   net/netfilter/nf_flow_table_offload.c:157:22: sparse:    got int
   net/netfilter/nf_flow_table_offload.c:253:20: sparse: sparse: incorrect type in initializer (different base types) @@    expected unsigned int [usertype] mask @@    got d int [usertype] mask @@
   net/netfilter/nf_flow_table_offload.c:253:20: sparse:    expected unsigned int [usertype] mask
   net/netfilter/nf_flow_table_offload.c:253:20: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:280:20: sparse: sparse: incorrect type in initializer (different base types) @@    expected unsigned int [usertype] mask @@    got d int [usertype] mask @@
   net/netfilter/nf_flow_table_offload.c:280:20: sparse:    expected unsigned int [usertype] mask
   net/netfilter/nf_flow_table_offload.c:280:20: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:321:20: sparse: sparse: incorrect type in initializer (different base types) @@    expected unsigned int [usertype] mask @@    got d int [usertype] mask @@
   net/netfilter/nf_flow_table_offload.c:321:20: sparse:    expected unsigned int [usertype] mask
   net/netfilter/nf_flow_table_offload.c:321:20: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:346:20: sparse: sparse: incorrect type in initializer (different base types) @@    expected unsigned int [usertype] mask @@    got d int [usertype] mask @@
   net/netfilter/nf_flow_table_offload.c:346:20: sparse:    expected unsigned int [usertype] mask
   net/netfilter/nf_flow_table_offload.c:346:20: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:391:20: sparse: sparse: incorrect type in initializer (different base types) @@    expected unsigned int [usertype] mask @@    got d int [usertype] mask @@
   net/netfilter/nf_flow_table_offload.c:391:20: sparse:    expected unsigned int [usertype] mask
   net/netfilter/nf_flow_table_offload.c:391:20: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:418:20: sparse: sparse: incorrect type in initializer (different base types) @@    expected unsigned int [usertype] mask @@    got d int [usertype] mask @@
   net/netfilter/nf_flow_table_offload.c:418:20: sparse:    expected unsigned int [usertype] mask
   net/netfilter/nf_flow_table_offload.c:418:20: sparse:    got restricted __be32
   net/netfilter/nf_flow_table_offload.c:632:24: sparse: sparse: incorrect type in initializer (different base types) @@    expected restricted __be16 [usertype] proto @@    got e] proto @@
   net/netfilter/nf_flow_table_offload.c:632:24: sparse:    expected restricted __be16 [usertype] proto
   net/netfilter/nf_flow_table_offload.c:632:24: sparse:    got int
   net/netfilter/nf_flow_table_offload.c:659:24: sparse: sparse: incorrect type in initializer (different base types) @@    expected restricted __be16 [usertype] proto @@    got e] proto @@
   net/netfilter/nf_flow_table_offload.c:659:24: sparse:    expected restricted __be16 [usertype] proto
   net/netfilter/nf_flow_table_offload.c:659:24: sparse:    got int
   net/netfilter/nf_flow_table_offload.c:716:24: sparse: sparse: incorrect type in initializer (different base types) @@    expected restricted __be16 [usertype] proto @@    got e] proto @@
   net/netfilter/nf_flow_table_offload.c:716:24: sparse:    expected restricted __be16 [usertype] proto
   net/netfilter/nf_flow_table_offload.c:716:24: sparse:    got int

vim +71 net/netfilter/nf_flow_table_offload.c

    53	
    54	#define NF_FLOW_DISSECTOR(__match, __type, __field)	\
    55		(__match)->dissector.offset[__type] =		\
    56			offsetof(struct nf_flow_key, __field)
    57	
    58	static void nf_flow_rule_lwt_match(struct nf_flow_match *match,
    59					   struct ip_tunnel_info *tun_info)
    60	{
    61		struct nf_flow_key *mask = &match->mask;
    62		struct nf_flow_key *key = &match->key;
    63		unsigned int enc_keys;
    64	
    65		if (!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX))
    66			return;
    67	
    68		NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_CONTROL, enc_control);
    69		NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
    70		key->enc_key_id.keyid = tunnel_id_to_key32(tun_info->key.tun_id);
  > 71		mask->enc_key_id.keyid = 0xffffffff;
    72		enc_keys = BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) |
    73			   BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL);
    74	
    75		if (ip_tunnel_info_af(tun_info) == AF_INET) {
    76			NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
    77					  enc_ipv4);
    78			key->enc_ipv4.src = tun_info->key.u.ipv4.dst;
    79			key->enc_ipv4.dst = tun_info->key.u.ipv4.src;
    80			if (key->enc_ipv4.src)
    81				mask->enc_ipv4.src = 0xffffffff;
    82			if (key->enc_ipv4.dst)
    83				mask->enc_ipv4.dst = 0xffffffff;
    84			enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS);
    85			key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
    86		} else {
    87			memcpy(&key->enc_ipv6.src, &tun_info->key.u.ipv6.dst,
    88			       sizeof(struct in6_addr));
    89			memcpy(&key->enc_ipv6.dst, &tun_info->key.u.ipv6.src,
    90			       sizeof(struct in6_addr));
    91			if (memcmp(&key->enc_ipv6.src, &in6addr_any,
    92				   sizeof(struct in6_addr)))
    93				memset(&key->enc_ipv6.src, 0xff,
    94				       sizeof(struct in6_addr));
    95			if (memcmp(&key->enc_ipv6.dst, &in6addr_any,
    96				   sizeof(struct in6_addr)))
    97				memset(&key->enc_ipv6.dst, 0xff,
    98				       sizeof(struct in6_addr));
    99			enc_keys |= BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS);
   100			key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
   101		}
   102	
   103		match->dissector.used_keys |= enc_keys;
   104	}
   105	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation

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

end of thread, other threads:[~2019-11-24 21:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-21  9:54 [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu
2019-11-21  9:54 ` [PATCH nf-next v2 1/4] netfilter: nf_flow_table_offload: refactor nf_flow_table_offload_setup to support indir setup wenxu
2019-11-21 12:36   ` wenxu
2019-11-21  9:54 ` [PATCH nf-next v2 2/4] netfilter: nf_flow_table_offload: add indr block setup support wenxu
2019-11-21 12:37   ` wenxu
2019-11-21  9:54 ` [PATCH nf-next v2 3/4] netfilter: nf_flow_table_offload: add tunnel match offload support wenxu
2019-11-21 12:37   ` wenxu
2019-11-24 21:07   ` kbuild test robot
2019-11-21  9:54 ` [PATCH nf-next v2 4/4] netfilter: nf_flow_table_offload: add tunnel encap/decap action " wenxu
2019-11-21 12:38   ` wenxu
2019-11-21 12:36 ` [PATCH nf-next v2 0/4] netfilter: nf_flow_table_offload: support tunnel offload wenxu

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).