mlx5: Implement flow steering helper functions for TCP sockets.
This change adds convenience functions to setup a flow steering rule based on a TCP socket. The helper function gets all the address information from the socket and returns a steering rule, to be used with HW TLS RX offload. MFC after: 1 week Sponsored by: NVIDIA Networking
This commit is contained in:
parent
0ee1b09eaa
commit
2c0ade806a
@ -4870,6 +4870,8 @@ dev/mlx5/mlx5_core/mlx5_eswitch.c optional mlx5 pci \
|
||||
compile-with "${OFED_C}"
|
||||
dev/mlx5/mlx5_core/mlx5_fs_cmd.c optional mlx5 pci \
|
||||
compile-with "${OFED_C}"
|
||||
dev/mlx5/mlx5_core/mlx5_fs_tcp.c optional mlx5 pci \
|
||||
compile-with "${OFED_C}"
|
||||
dev/mlx5/mlx5_core/mlx5_fs_tree.c optional mlx5 pci \
|
||||
compile-with "${OFED_C}"
|
||||
dev/mlx5/mlx5_core/mlx5_fw.c optional mlx5 pci \
|
||||
|
@ -1039,6 +1039,12 @@ enum mlx5_mcam_feature_groups {
|
||||
#define MLX5_CAP_FLOWTABLE_MAX(mdev, cap) \
|
||||
MLX5_GET(flow_table_nic_cap, mdev->hca_caps_max[MLX5_CAP_FLOW_TABLE], cap)
|
||||
|
||||
#define MLX5_CAP_FLOWTABLE_NIC_RX(mdev, cap) \
|
||||
MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.cap)
|
||||
|
||||
#define MLX5_CAP_FLOWTABLE_NIC_RX_MAX(mdev, cap) \
|
||||
MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_receive.cap)
|
||||
|
||||
#define MLX5_CAP_ESW_FLOWTABLE(mdev, cap) \
|
||||
MLX5_GET(flow_table_eswitch_cap, \
|
||||
mdev->hca_caps_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap)
|
||||
|
41
sys/dev/mlx5/mlx5_core/fs_tcp.h
Normal file
41
sys/dev/mlx5/mlx5_core/fs_tcp.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 2020-2021, Mellanox Technologies, Ltd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __MLX5E_ACCEL_FS_TCP_H__
|
||||
#define __MLX5E_ACCEL_FS_TCP_H__
|
||||
|
||||
struct inpcb;
|
||||
struct mlx5_flow_rule;
|
||||
struct mlx5e_priv;
|
||||
|
||||
int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *);
|
||||
void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *);
|
||||
struct mlx5_flow_rule *
|
||||
mlx5e_accel_fs_add_inpcb(struct mlx5e_priv *,
|
||||
struct inpcb *, uint32_t tirn, uint32_t flow_tag, uint16_t vlan_id);
|
||||
#define MLX5E_ACCEL_FS_ADD_INPCB_NO_VLAN 0xFFFF
|
||||
void mlx5e_accel_fs_del_inpcb(struct mlx5_flow_rule *);
|
||||
|
||||
#endif /* __MLX5E_ACCEL_FS_TCP_H__ */
|
404
sys/dev/mlx5/mlx5_core/mlx5_fs_tcp.c
Normal file
404
sys/dev/mlx5/mlx5_core/mlx5_fs_tcp.c
Normal file
@ -0,0 +1,404 @@
|
||||
/*-
|
||||
* Copyright (c) 2020-2021, Mellanox Technologies, Ltd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <dev/mlx5/mlx5_en/en.h>
|
||||
|
||||
#include <dev/mlx5/mlx5_core/fs_core.h>
|
||||
#include <dev/mlx5/mlx5_core/fs_tcp.h>
|
||||
#include <dev/mlx5/device.h>
|
||||
|
||||
#include <sys/domain.h>
|
||||
|
||||
#include <netinet/in_pcb.h>
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
static void
|
||||
accel_fs_tcp_set_ipv4_flow(struct mlx5_flow_spec *spec, struct inpcb *inp)
|
||||
{
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_TCP);
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, 4);
|
||||
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
|
||||
outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4),
|
||||
&inp->inp_faddr, 4);
|
||||
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
|
||||
outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
|
||||
&inp->inp_laddr, 4);
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
|
||||
outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4);
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
|
||||
outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
static void
|
||||
accel_fs_tcp_set_ipv6_flow(struct mlx5_flow_spec *spec, struct inpcb *inp)
|
||||
{
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_TCP);
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, 6);
|
||||
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
|
||||
outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
|
||||
&inp->in6p_faddr, 16);
|
||||
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
|
||||
outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
|
||||
&inp->in6p_laddr, 16);
|
||||
memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
|
||||
outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),
|
||||
0xff, 16);
|
||||
memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
|
||||
outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
|
||||
0xff, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
mlx5e_accel_fs_del_inpcb(struct mlx5_flow_rule *rule)
|
||||
{
|
||||
mlx5_del_flow_rule(rule);
|
||||
}
|
||||
|
||||
struct mlx5_flow_rule *
|
||||
mlx5e_accel_fs_add_inpcb(struct mlx5e_priv *priv,
|
||||
struct inpcb *inp, uint32_t tirn, uint32_t flow_tag,
|
||||
uint16_t vlan_id)
|
||||
{
|
||||
struct mlx5_flow_destination dest = {};
|
||||
struct mlx5e_flow_table *ft = NULL;
|
||||
struct mlx5e_accel_fs_tcp *fs_tcp;
|
||||
struct mlx5_flow_rule *flow;
|
||||
struct mlx5_flow_spec *spec;
|
||||
|
||||
spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
return (ERR_PTR(-ENOMEM));
|
||||
|
||||
fs_tcp = &priv->fts.accel_tcp;
|
||||
|
||||
spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
|
||||
|
||||
INP_RLOCK(inp);
|
||||
/* Set VLAN ID to match, if any. */
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.cvlan_tag);
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.first_vid);
|
||||
if (vlan_id != MLX5E_ACCEL_FS_ADD_INPCB_NO_VLAN) {
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_value, outer_headers.cvlan_tag);
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid, vlan_id);
|
||||
}
|
||||
|
||||
/* Set TCP port numbers. */
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
|
||||
outer_headers.tcp_dport);
|
||||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
|
||||
outer_headers.tcp_sport);
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.tcp_dport,
|
||||
ntohs(inp->inp_lport));
|
||||
MLX5_SET(fte_match_param, spec->match_value, outer_headers.tcp_sport,
|
||||
ntohs(inp->inp_fport));
|
||||
|
||||
/* Set IP addresses. */
|
||||
switch (INP_SOCKAF(inp->inp_socket)) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
accel_fs_tcp_set_ipv4_flow(spec, inp);
|
||||
ft = &fs_tcp->tables[MLX5E_ACCEL_FS_IPV4_TCP];
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&inp->in6p_faddr)) {
|
||||
accel_fs_tcp_set_ipv4_flow(spec, inp);
|
||||
ft = &fs_tcp->tables[MLX5E_ACCEL_FS_IPV4_TCP];
|
||||
} else {
|
||||
accel_fs_tcp_set_ipv6_flow(spec, inp);
|
||||
ft = &fs_tcp->tables[MLX5E_ACCEL_FS_IPV6_TCP];
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
INP_RUNLOCK(inp);
|
||||
|
||||
if (!ft) {
|
||||
flow = ERR_PTR(-EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
|
||||
dest.tir_num = tirn;
|
||||
|
||||
flow = mlx5_add_flow_rule(ft->t, spec->match_criteria_enable,
|
||||
spec->match_criteria,
|
||||
spec->match_value,
|
||||
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
|
||||
flow_tag,
|
||||
&dest);
|
||||
out:
|
||||
kvfree(spec);
|
||||
return (flow);
|
||||
}
|
||||
|
||||
static int
|
||||
accel_fs_tcp_add_default_rule(struct mlx5e_priv *priv, int type)
|
||||
{
|
||||
static u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)];
|
||||
static u32 match_value[MLX5_ST_SZ_DW(fte_match_param)];
|
||||
struct mlx5_flow_destination dest = {};
|
||||
struct mlx5e_accel_fs_tcp *fs_tcp;
|
||||
struct mlx5_flow_rule *rule;
|
||||
|
||||
fs_tcp = &priv->fts.accel_tcp;
|
||||
|
||||
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
|
||||
|
||||
/*
|
||||
* Traffic not matched by flow table rules should be forwarded
|
||||
* to the next flow table in order to not be dropped by the
|
||||
* default action. Refer to the diagram in
|
||||
* mlx5_en_flow_table.c for more information about the order
|
||||
* of flow tables.
|
||||
*/
|
||||
dest.ft = (type == MLX5E_ACCEL_FS_TCP_NUM_TYPES - 1) ?
|
||||
priv->fts.vlan.t : fs_tcp->tables[type + 1].t;
|
||||
|
||||
rule = mlx5_add_flow_rule(fs_tcp->tables[type].t, 0, match_criteria, match_value,
|
||||
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, MLX5_FS_DEFAULT_FLOW_TAG, &dest);
|
||||
if (IS_ERR(rule))
|
||||
return (PTR_ERR(rule));
|
||||
|
||||
fs_tcp->default_rules[type] = rule;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define MLX5E_ACCEL_FS_TCP_NUM_GROUPS (2)
|
||||
#define MLX5E_ACCEL_FS_TCP_GROUP1_SIZE (BIT(16) - 1)
|
||||
#define MLX5E_ACCEL_FS_TCP_GROUP2_SIZE (BIT(0))
|
||||
#define MLX5E_ACCEL_FS_TCP_TABLE_SIZE (MLX5E_ACCEL_FS_TCP_GROUP1_SIZE +\
|
||||
MLX5E_ACCEL_FS_TCP_GROUP2_SIZE)
|
||||
static int
|
||||
accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft, int type)
|
||||
{
|
||||
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
|
||||
void *outer_headers_c;
|
||||
int ix = 0;
|
||||
u32 *in;
|
||||
int err;
|
||||
u8 *mc;
|
||||
|
||||
ft->g = kcalloc(MLX5E_ACCEL_FS_TCP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
|
||||
in = kvzalloc(inlen, GFP_KERNEL);
|
||||
if (!in || !ft->g) {
|
||||
kfree(ft->g);
|
||||
kvfree(in);
|
||||
return (-ENOMEM);
|
||||
}
|
||||
|
||||
mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
|
||||
outer_headers_c = MLX5_ADDR_OF(fte_match_param, mc, outer_headers);
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol);
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_version);
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, cvlan_tag);
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, first_vid);
|
||||
|
||||
switch (type) {
|
||||
case MLX5E_ACCEL_FS_IPV4_TCP:
|
||||
case MLX5E_ACCEL_FS_IPV6_TCP:
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport);
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MLX5E_ACCEL_FS_IPV4_TCP:
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c,
|
||||
src_ipv4_src_ipv6.ipv4_layout.ipv4);
|
||||
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c,
|
||||
dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
|
||||
break;
|
||||
case MLX5E_ACCEL_FS_IPV6_TCP:
|
||||
memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
|
||||
src_ipv4_src_ipv6.ipv6_layout.ipv6),
|
||||
0xff, 16);
|
||||
memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
|
||||
dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
|
||||
0xff, 16);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
|
||||
MLX5_SET_CFG(in, start_flow_index, ix);
|
||||
ix += MLX5E_ACCEL_FS_TCP_GROUP1_SIZE;
|
||||
MLX5_SET_CFG(in, end_flow_index, ix - 1);
|
||||
ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
|
||||
if (IS_ERR(ft->g[ft->num_groups]))
|
||||
goto err;
|
||||
ft->num_groups++;
|
||||
|
||||
/* Default Flow Group */
|
||||
memset(in, 0, inlen);
|
||||
MLX5_SET_CFG(in, start_flow_index, ix);
|
||||
ix += MLX5E_ACCEL_FS_TCP_GROUP2_SIZE;
|
||||
MLX5_SET_CFG(in, end_flow_index, ix - 1);
|
||||
ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
|
||||
if (IS_ERR(ft->g[ft->num_groups]))
|
||||
goto err;
|
||||
ft->num_groups++;
|
||||
|
||||
kvfree(in);
|
||||
return (0);
|
||||
|
||||
err:
|
||||
err = PTR_ERR(ft->g[ft->num_groups]);
|
||||
ft->g[ft->num_groups] = NULL;
|
||||
out:
|
||||
kvfree(in);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
accel_fs_tcp_destroy_groups(struct mlx5e_flow_table *ft)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ft->num_groups - 1; i >= 0; i--) {
|
||||
if (!IS_ERR_OR_NULL(ft->g[i]))
|
||||
mlx5_destroy_flow_group(ft->g[i]);
|
||||
ft->g[i] = NULL;
|
||||
}
|
||||
ft->num_groups = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
accel_fs_tcp_create_table(struct mlx5e_priv *priv, int type)
|
||||
{
|
||||
struct mlx5e_flow_table *ft = &priv->fts.accel_tcp.tables[type];
|
||||
int err;
|
||||
|
||||
ft->num_groups = 0;
|
||||
ft->t = mlx5_create_flow_table(priv->fts.accel_tcp.ns, 0, "tcp",
|
||||
MLX5E_ACCEL_FS_TCP_TABLE_SIZE);
|
||||
if (IS_ERR(ft->t)) {
|
||||
err = PTR_ERR(ft->t);
|
||||
ft->t = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
||||
err = accel_fs_tcp_create_groups(ft, type);
|
||||
if (err)
|
||||
goto err_destroy_flow_table;
|
||||
|
||||
return (0);
|
||||
|
||||
err_destroy_flow_table:
|
||||
mlx5_destroy_flow_table(ft->t);
|
||||
ft->t = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
accel_fs_tcp_destroy_table(struct mlx5e_priv *priv, int i)
|
||||
{
|
||||
struct mlx5e_accel_fs_tcp *fs_tcp;
|
||||
struct mlx5e_flow_table *ft;
|
||||
|
||||
fs_tcp = &priv->fts.accel_tcp;
|
||||
ft = fs_tcp->tables + i;
|
||||
|
||||
mlx5_del_flow_rule(fs_tcp->default_rules[i]);
|
||||
|
||||
accel_fs_tcp_destroy_groups(ft);
|
||||
kfree(ft->g);
|
||||
ft->g = NULL;
|
||||
mlx5_destroy_flow_table(ft->t);
|
||||
ft->t = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version))
|
||||
return;
|
||||
|
||||
for (i = 0; i < MLX5E_ACCEL_FS_TCP_NUM_TYPES; i++)
|
||||
accel_fs_tcp_destroy_table(priv, i);
|
||||
}
|
||||
|
||||
int
|
||||
mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version))
|
||||
return (0);
|
||||
|
||||
/* Setup namespace pointer. */
|
||||
priv->fts.accel_tcp.ns = mlx5_get_flow_namespace(
|
||||
priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
|
||||
|
||||
/*
|
||||
* Create flow tables first, because the priority level is
|
||||
* assigned at allocation time.
|
||||
*/
|
||||
for (i = 0; i != MLX5E_ACCEL_FS_TCP_NUM_TYPES; i++) {
|
||||
err = accel_fs_tcp_create_table(priv, i);
|
||||
if (err)
|
||||
goto err_destroy_tables;
|
||||
}
|
||||
|
||||
/* Create default rules last. */
|
||||
for (i = 0; i != MLX5E_ACCEL_FS_TCP_NUM_TYPES; i++) {
|
||||
err = accel_fs_tcp_add_default_rule(priv, i);
|
||||
if (err)
|
||||
goto err_destroy_rules;
|
||||
}
|
||||
return (0);
|
||||
|
||||
err_destroy_rules:
|
||||
while (i--)
|
||||
mlx5_del_flow_rule(priv->fts.accel_tcp.default_rules[i]);
|
||||
i = MLX5E_ACCEL_FS_TCP_NUM_TYPES;
|
||||
|
||||
err_destroy_tables:
|
||||
while (i--)
|
||||
accel_fs_tcp_destroy_table(priv, i);
|
||||
return (err);
|
||||
}
|
@ -72,6 +72,8 @@
|
||||
#include <dev/mlx5/mlx5_core/transobj.h>
|
||||
#include <dev/mlx5/mlx5_core/mlx5_core.h>
|
||||
|
||||
#define MLX5_SET_CFG(p, f, v) MLX5_SET(create_flow_group_in, p, f, v)
|
||||
|
||||
#define MLX5E_MAX_PRIORITY 8
|
||||
|
||||
#define MLX5E_MAX_FEC_10X_25X 4
|
||||
@ -1015,6 +1017,18 @@ struct mlx5e_flow_table {
|
||||
struct mlx5_flow_group **g;
|
||||
};
|
||||
|
||||
enum accel_fs_tcp_type {
|
||||
MLX5E_ACCEL_FS_IPV4_TCP,
|
||||
MLX5E_ACCEL_FS_IPV6_TCP,
|
||||
MLX5E_ACCEL_FS_TCP_NUM_TYPES,
|
||||
};
|
||||
|
||||
struct mlx5e_accel_fs_tcp {
|
||||
struct mlx5_flow_namespace *ns;
|
||||
struct mlx5e_flow_table tables[MLX5E_ACCEL_FS_TCP_NUM_TYPES];
|
||||
struct mlx5_flow_rule *default_rules[MLX5E_ACCEL_FS_TCP_NUM_TYPES];
|
||||
};
|
||||
|
||||
struct mlx5e_flow_tables {
|
||||
struct mlx5_flow_namespace *ns;
|
||||
struct mlx5e_flow_table vlan;
|
||||
@ -1024,6 +1038,7 @@ struct mlx5e_flow_tables {
|
||||
struct mlx5e_flow_table main_vxlan;
|
||||
struct mlx5_flow_rule *main_vxlan_rule[MLX5E_NUM_TT];
|
||||
struct mlx5e_flow_table inner_rss;
|
||||
struct mlx5e_accel_fs_tcp accel_tcp;
|
||||
};
|
||||
|
||||
struct mlx5e_xmit_args {
|
||||
|
@ -33,28 +33,44 @@
|
||||
#include <linux/list.h>
|
||||
#include <dev/mlx5/fs.h>
|
||||
#include <dev/mlx5/mpfs.h>
|
||||
#include <dev/mlx5/mlx5_core/fs_tcp.h>
|
||||
|
||||
/*
|
||||
* The flow tables with rules define the packet processing on receive.
|
||||
* Currently, the following structure is set up to handle different offloads
|
||||
* like VLAN decapsulation, packet classification, RSS hashing, VxLAN checksum
|
||||
* offloading:
|
||||
* Currently the following structure is set up to handle different
|
||||
* offloads like TLS RX offload, VLAN decapsulation, packet
|
||||
* classification, RSS hashing, VxLAN checksum offloading:
|
||||
*
|
||||
*
|
||||
* +=========+ +=========+ +=================+
|
||||
* |VLAN ft: | |VxLAN | |VxLAN Main |
|
||||
* +=========+ +=========+ +=================+
|
||||
* |TCP/IPv4 | |TCP/IPv4 | |TCP/IPv4 Match |
|
||||
* |Flowtable|------>| |----->|Outer Proto Match|=====> TLS TIR n
|
||||
* | | |Catch-all|\ | |
|
||||
* +=========+ +=========+| +=================+
|
||||
* |
|
||||
* +------------------------+
|
||||
* V
|
||||
* +=========+ +=========+ +=================+
|
||||
* |TCP/IPv6 | |TCP/IPv6 | |TCP/IPv6 Match |
|
||||
* |Flowtable|------>| |----->|Outer Proto Match|=====> TLS TIR n
|
||||
* | | |Catch-all|\ | |
|
||||
* +=========+ +=========+| +=================+
|
||||
* |
|
||||
* +------------------------+
|
||||
* V
|
||||
* +=========+ +=========+ +=================+
|
||||
* |VLAN ft: | |VxLAN | |VxLAN Main |
|
||||
* |CTAG/STAG|------>| VNI|----->|Inner Proto Match|=====> Inner TIR n
|
||||
* |VID/noVID|/ |Catch-all|\ | |
|
||||
* +=========+ +=========+| +=================+
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* v
|
||||
* +=================+
|
||||
* |Main |
|
||||
* |Outer Proto Match|=====> TIR n
|
||||
* | |
|
||||
* +=================+
|
||||
* |VID/noVID|/ |Catch-all|\ | |
|
||||
* +=========+ +=========+| +=================+
|
||||
* |
|
||||
* |
|
||||
* |
|
||||
* v
|
||||
* +=================+
|
||||
* |Main |
|
||||
* |Outer Proto Match|=====> TIR n
|
||||
* | |
|
||||
* +=================+
|
||||
*
|
||||
* The path through flow rules directs each packet into an appropriate TIR,
|
||||
* according to the:
|
||||
@ -2292,8 +2308,14 @@ mlx5e_open_flow_tables(struct mlx5e_priv *priv)
|
||||
if (err)
|
||||
goto err_destroy_inner_rss_flow_table;
|
||||
|
||||
err = mlx5e_accel_fs_tcp_create(priv);
|
||||
if (err)
|
||||
goto err_del_vxlan_catchall_rule;
|
||||
|
||||
return (0);
|
||||
|
||||
err_del_vxlan_catchall_rule:
|
||||
mlx5e_del_vxlan_catchall_rule(priv);
|
||||
err_destroy_inner_rss_flow_table:
|
||||
mlx5e_destroy_inner_rss_flow_table(priv);
|
||||
err_destroy_main_vxlan_flow_table:
|
||||
@ -2311,6 +2333,7 @@ mlx5e_open_flow_tables(struct mlx5e_priv *priv)
|
||||
void
|
||||
mlx5e_close_flow_tables(struct mlx5e_priv *priv)
|
||||
{
|
||||
mlx5e_accel_fs_tcp_destroy(priv);
|
||||
mlx5e_del_vxlan_catchall_rule(priv);
|
||||
mlx5e_destroy_inner_rss_flow_table(priv);
|
||||
mlx5e_destroy_main_vxlan_flow_table(priv);
|
||||
|
@ -339,7 +339,7 @@ struct mlx5_ifc_flow_table_fields_supported_bits {
|
||||
u8 outer_dmac[0x1];
|
||||
u8 outer_smac[0x1];
|
||||
u8 outer_ether_type[0x1];
|
||||
u8 reserved_0[0x1];
|
||||
u8 outer_ip_version[0x1];
|
||||
u8 outer_first_prio[0x1];
|
||||
u8 outer_first_cfi[0x1];
|
||||
u8 outer_first_vid[0x1];
|
||||
@ -372,7 +372,7 @@ struct mlx5_ifc_flow_table_fields_supported_bits {
|
||||
u8 inner_dmac[0x1];
|
||||
u8 inner_smac[0x1];
|
||||
u8 inner_ether_type[0x1];
|
||||
u8 reserved_3[0x1];
|
||||
u8 inner_ip_version[0x1];
|
||||
u8 inner_first_prio[0x1];
|
||||
u8 inner_first_cfi[0x1];
|
||||
u8 inner_first_vid[0x1];
|
||||
@ -562,7 +562,7 @@ struct mlx5_ifc_fte_match_set_lyr_2_4_bits {
|
||||
u8 cvlan_tag[0x1];
|
||||
u8 svlan_tag[0x1];
|
||||
u8 frag[0x1];
|
||||
u8 reserved_1[0x4];
|
||||
u8 ip_version[0x4];
|
||||
u8 tcp_flags[0x9];
|
||||
|
||||
u8 tcp_sport[0x10];
|
||||
|
@ -12,6 +12,7 @@ mlx5_diagnostics.c \
|
||||
mlx5_eq.c \
|
||||
mlx5_eswitch.c \
|
||||
mlx5_fs_cmd.c \
|
||||
mlx5_fs_tcp.c \
|
||||
mlx5_fs_tree.c \
|
||||
mlx5_fw.c \
|
||||
mlx5_fwdump.c \
|
||||
|
Loading…
Reference in New Issue
Block a user