Commit dcf19b9c authored by Maor Dickman's avatar Maor Dickman Committed by Saeed Mahameed

net/mlx5e: TC, Add offload support for trap with additional actions

TC trap action offload is currently supported only when trap is the sole action
in the flow.

This patch remove this limitation by changing trap action offload to not use
MLX5_ATTR_FLAG_SLOW_PATH flag and instead set the flow destination table
explicitly to be the slow table. This will allow offload of the additional
actions.

TC flow example:
tc filter add dev $REP2 protocol ip prio 2 root \
	flower skip_sw dst_mac $mac0 \
	action mirred egress redirect dev $REP3 \
	action pedit ex munge eth dst set $mac2  pipe \
	action trap
Signed-off-by: default avatarMaor Dickman <maord@nvidia.com>
Reviewed-by: default avatarRaed Salem <raeds@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 42760d95
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "act.h" #include "act.h"
#include "en/tc_priv.h" #include "en/tc_priv.h"
#include "eswitch.h"
static bool static bool
tc_act_can_offload_trap(struct mlx5e_tc_act_parse_state *parse_state, tc_act_can_offload_trap(struct mlx5e_tc_act_parse_state *parse_state,
...@@ -10,13 +11,6 @@ tc_act_can_offload_trap(struct mlx5e_tc_act_parse_state *parse_state, ...@@ -10,13 +11,6 @@ tc_act_can_offload_trap(struct mlx5e_tc_act_parse_state *parse_state,
int act_index, int act_index,
struct mlx5_flow_attr *attr) struct mlx5_flow_attr *attr)
{ {
struct netlink_ext_ack *extack = parse_state->extack;
if (parse_state->flow_action->num_entries != 1) {
NL_SET_ERR_MSG_MOD(extack, "action trap is supported as a sole action only");
return false;
}
return true; return true;
} }
...@@ -27,7 +21,7 @@ tc_act_parse_trap(struct mlx5e_tc_act_parse_state *parse_state, ...@@ -27,7 +21,7 @@ tc_act_parse_trap(struct mlx5e_tc_act_parse_state *parse_state,
struct mlx5_flow_attr *attr) struct mlx5_flow_attr *attr)
{ {
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH; attr->dest_ft = mlx5_eswitch_get_slow_fdb(priv->mdev->priv.eswitch);
return 0; return 0;
} }
......
...@@ -744,6 +744,11 @@ static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw) ...@@ -744,6 +744,11 @@ static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
return 0; return 0;
} }
static inline struct mlx5_flow_table *
mlx5_eswitch_get_slow_fdb(struct mlx5_eswitch *esw)
{
return esw->fdb_table.offloads.slow_fdb;
}
#else /* CONFIG_MLX5_ESWITCH */ #else /* CONFIG_MLX5_ESWITCH */
/* eswitch API stubs */ /* eswitch API stubs */
static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; } static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
......
...@@ -248,7 +248,7 @@ esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_ac ...@@ -248,7 +248,7 @@ esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_ac
if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level)) if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level))
flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest[i].ft = esw->fdb_table.offloads.slow_fdb; dest[i].ft = mlx5_eswitch_get_slow_fdb(esw);
} }
static int static int
...@@ -1049,7 +1049,7 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw, ...@@ -1049,7 +1049,7 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw,
if (rep->vport == MLX5_VPORT_UPLINK) if (rep->vport == MLX5_VPORT_UPLINK)
spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT; spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT;
flow_rule = mlx5_add_flow_rules(on_esw->fdb_table.offloads.slow_fdb, flow_rule = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(on_esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow_rule)) if (IS_ERR(flow_rule))
esw_warn(on_esw->dev, "FDB: Failed to add send to vport rule err %ld\n", esw_warn(on_esw->dev, "FDB: Failed to add send to vport rule err %ld\n",
...@@ -1098,7 +1098,7 @@ mlx5_eswitch_add_send_to_vport_meta_rule(struct mlx5_eswitch *esw, u16 vport_num ...@@ -1098,7 +1098,7 @@ mlx5_eswitch_add_send_to_vport_meta_rule(struct mlx5_eswitch *esw, u16 vport_num
mlx5_eswitch_get_vport_metadata_for_match(esw, vport_num)); mlx5_eswitch_get_vport_metadata_for_match(esw, vport_num));
dest.vport.num = vport_num; dest.vport.num = vport_num;
flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, flow_rule = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow_rule)) if (IS_ERR(flow_rule))
esw_warn(esw->dev, "FDB: Failed to add send to vport meta rule vport %d, err %ld\n", esw_warn(esw->dev, "FDB: Failed to add send to vport meta rule vport %d, err %ld\n",
...@@ -1251,7 +1251,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, ...@@ -1251,7 +1251,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw,
esw_set_peer_miss_rule_source_port(esw, peer_dev->priv.eswitch, esw_set_peer_miss_rule_source_port(esw, peer_dev->priv.eswitch,
spec, MLX5_VPORT_PF); spec, MLX5_VPORT_PF);
flow = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow)) { if (IS_ERR(flow)) {
err = PTR_ERR(flow); err = PTR_ERR(flow);
...@@ -1263,7 +1263,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, ...@@ -1263,7 +1263,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw,
if (mlx5_ecpf_vport_exists(esw->dev)) { if (mlx5_ecpf_vport_exists(esw->dev)) {
vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF); vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_ECPF);
MLX5_SET(fte_match_set_misc, misc, source_port, MLX5_VPORT_ECPF); MLX5_SET(fte_match_set_misc, misc, source_port, MLX5_VPORT_ECPF);
flow = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow)) { if (IS_ERR(flow)) {
err = PTR_ERR(flow); err = PTR_ERR(flow);
...@@ -1277,7 +1277,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, ...@@ -1277,7 +1277,7 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw,
peer_dev->priv.eswitch, peer_dev->priv.eswitch,
spec, vport->vport); spec, vport->vport);
flow = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow)) { if (IS_ERR(flow)) {
err = PTR_ERR(flow); err = PTR_ERR(flow);
...@@ -1366,7 +1366,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw) ...@@ -1366,7 +1366,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
dest.vport.num = esw->manager_vport; dest.vport.num = esw->manager_vport;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, flow_rule = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow_rule)) { if (IS_ERR(flow_rule)) {
err = PTR_ERR(flow_rule); err = PTR_ERR(flow_rule);
...@@ -1381,7 +1381,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw) ...@@ -1381,7 +1381,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v,
outer_headers.dmac_47_16); outer_headers.dmac_47_16);
dmac_v[0] = 0x01; dmac_v[0] = 0x01;
flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.slow_fdb, flow_rule = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw),
spec, &flow_act, &dest, 1); spec, &flow_act, &dest, 1);
if (IS_ERR(flow_rule)) { if (IS_ERR(flow_rule)) {
err = PTR_ERR(flow_rule); err = PTR_ERR(flow_rule);
...@@ -1930,7 +1930,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw) ...@@ -1930,7 +1930,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
fdb_chains_err: fdb_chains_err:
mlx5_destroy_flow_table(esw->fdb_table.offloads.tc_miss_table); mlx5_destroy_flow_table(esw->fdb_table.offloads.tc_miss_table);
tc_miss_table_err: tc_miss_table_err:
mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb); mlx5_destroy_flow_table(mlx5_eswitch_get_slow_fdb(esw));
slow_fdb_err: slow_fdb_err:
/* Holds true only as long as DMFS is the default */ /* Holds true only as long as DMFS is the default */
mlx5_flow_namespace_set_mode(root_ns, MLX5_FLOW_STEERING_MODE_DMFS); mlx5_flow_namespace_set_mode(root_ns, MLX5_FLOW_STEERING_MODE_DMFS);
...@@ -1941,7 +1941,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw) ...@@ -1941,7 +1941,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw) static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
{ {
if (!esw->fdb_table.offloads.slow_fdb) if (!mlx5_eswitch_get_slow_fdb(esw))
return; return;
esw_debug(esw->dev, "Destroy offloads FDB Tables\n"); esw_debug(esw->dev, "Destroy offloads FDB Tables\n");
...@@ -1957,7 +1957,7 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw) ...@@ -1957,7 +1957,7 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
esw_chains_destroy(esw, esw_chains(esw)); esw_chains_destroy(esw, esw_chains(esw));
mlx5_destroy_flow_table(esw->fdb_table.offloads.tc_miss_table); mlx5_destroy_flow_table(esw->fdb_table.offloads.tc_miss_table);
mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb); mlx5_destroy_flow_table(mlx5_eswitch_get_slow_fdb(esw));
/* Holds true only as long as DMFS is the default */ /* Holds true only as long as DMFS is the default */
mlx5_flow_namespace_set_mode(esw->fdb_table.offloads.ns, mlx5_flow_namespace_set_mode(esw->fdb_table.offloads.ns,
MLX5_FLOW_STEERING_MODE_DMFS); MLX5_FLOW_STEERING_MODE_DMFS);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment