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:
Hans Petter Selasky 2022-02-01 16:20:13 +01:00
parent 0ee1b09eaa
commit 2c0ade806a
8 changed files with 512 additions and 20 deletions

View File

@ -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 \

View File

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

View 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__ */

View 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);
}

View File

@ -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 {

View File

@ -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);

View File

@ -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];

View File

@ -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 \