* [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* 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
* [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* 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
* [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* 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 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
* [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 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 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