net/mlx5: DR, Add support for rule creation with flow source hint

Skip the rule according to flow arrival source, in case of RX and the
source is local port skip and in case of TX and the source is uplink
skip, we get this info according to the flow source hint we get from
upper layers when creating the rule.
This is needed because for example in case of FDB table which has a TX
and RX tables and we are inserting a rule with an encap action which
is only a TX action, in this case rule will fail on RX, so we can rely
on the flow source hint and skip RX in such case.
Until now we relied on metadata regc_0 that upper layer mapped the
port in the regc_0, but the problem is that upper layer did not always
use regc_0 for port mapping, so now we added support to flow source
hint which upper layers will pass to SW steering when creating a rule.

Signed-off-by: Alex Vesker <valex@nvidia.com>
Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
This commit is contained in:
Hamdan Igbaria 2020-06-15 18:18:14 +03:00 committed by Saeed Mahameed
parent e6b69bf379
commit 0172391967
4 changed files with 26 additions and 22 deletions

View file

@ -985,31 +985,28 @@ static enum mlx5dr_ipv dr_rule_get_ipv(struct mlx5dr_match_spec *spec)
static bool dr_rule_skip(enum mlx5dr_domain_type domain,
enum mlx5dr_ste_entry_type ste_type,
struct mlx5dr_match_param *mask,
struct mlx5dr_match_param *value)
struct mlx5dr_match_param *value,
u32 flow_source)
{
bool rx = ste_type == MLX5DR_STE_TYPE_RX;
if (domain != MLX5DR_DOMAIN_TYPE_FDB)
return false;
if (mask->misc.source_port) {
if (ste_type == MLX5DR_STE_TYPE_RX)
if (value->misc.source_port != WIRE_PORT)
return true;
if (rx && value->misc.source_port != WIRE_PORT)
return true;
if (ste_type == MLX5DR_STE_TYPE_TX)
if (value->misc.source_port == WIRE_PORT)
return true;
if (!rx && value->misc.source_port == WIRE_PORT)
return true;
}
/* Metadata C can be used to describe the source vport */
if (mask->misc2.metadata_reg_c_0) {
if (ste_type == MLX5DR_STE_TYPE_RX)
if ((value->misc2.metadata_reg_c_0 & WIRE_PORT) != WIRE_PORT)
return true;
if (rx && flow_source == MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT)
return true;
if (!rx && flow_source == MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK)
return true;
if (ste_type == MLX5DR_STE_TYPE_TX)
if ((value->misc2.metadata_reg_c_0 & WIRE_PORT) == WIRE_PORT)
return true;
}
return false;
}
@ -1038,7 +1035,8 @@ dr_rule_create_rule_nic(struct mlx5dr_rule *rule,
INIT_LIST_HEAD(&nic_rule->rule_members_list);
if (dr_rule_skip(dmn->type, nic_dmn->ste_type, &matcher->mask, param))
if (dr_rule_skip(dmn->type, nic_dmn->ste_type, &matcher->mask, param,
rule->flow_source))
return 0;
hw_ste_arr = kzalloc(DR_RULE_MAX_STE_CHAIN * DR_STE_SIZE, GFP_KERNEL);
@ -1173,7 +1171,8 @@ static struct mlx5dr_rule *
dr_rule_create_rule(struct mlx5dr_matcher *matcher,
struct mlx5dr_match_parameters *value,
size_t num_actions,
struct mlx5dr_action *actions[])
struct mlx5dr_action *actions[],
u32 flow_source)
{
struct mlx5dr_domain *dmn = matcher->tbl->dmn;
struct mlx5dr_match_param param = {};
@ -1188,6 +1187,7 @@ dr_rule_create_rule(struct mlx5dr_matcher *matcher,
return NULL;
rule->matcher = matcher;
rule->flow_source = flow_source;
INIT_LIST_HEAD(&rule->rule_actions_list);
ret = dr_rule_add_action_members(rule, num_actions, actions);
@ -1232,13 +1232,14 @@ dr_rule_create_rule(struct mlx5dr_matcher *matcher,
struct mlx5dr_rule *mlx5dr_rule_create(struct mlx5dr_matcher *matcher,
struct mlx5dr_match_parameters *value,
size_t num_actions,
struct mlx5dr_action *actions[])
struct mlx5dr_action *actions[],
u32 flow_source)
{
struct mlx5dr_rule *rule;
refcount_inc(&matcher->refcount);
rule = dr_rule_create_rule(matcher, value, num_actions, actions);
rule = dr_rule_create_rule(matcher, value, num_actions, actions, flow_source);
if (!rule)
refcount_dec(&matcher->refcount);

View file

@ -797,6 +797,7 @@ struct mlx5dr_rule {
struct mlx5dr_rule_rx_tx rx;
struct mlx5dr_rule_rx_tx tx;
struct list_head rule_actions_list;
u32 flow_source;
};
void mlx5dr_rule_update_rule_member(struct mlx5dr_ste *new_ste,

View file

@ -487,7 +487,8 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
rule = mlx5dr_rule_create(group->fs_dr_matcher.dr_matcher,
&params,
num_actions,
actions);
actions,
fte->flow_context.flow_source);
if (!rule) {
err = -EINVAL;
goto free_actions;

View file

@ -67,7 +67,8 @@ struct mlx5dr_rule *
mlx5dr_rule_create(struct mlx5dr_matcher *matcher,
struct mlx5dr_match_parameters *value,
size_t num_actions,
struct mlx5dr_action *actions[]);
struct mlx5dr_action *actions[],
u32 flow_source);
int mlx5dr_rule_destroy(struct mlx5dr_rule *rule);