Commit d24f847e authored by Ariel Levkovich's avatar Ariel Levkovich Committed by Saeed Mahameed
Browse files

net/mlx5e: Fix mapping of ct_label zero



ct_label 0 is a default label each flow has and therefore
there can be rules that match on ct_label=0 without a prior
rule that set the ct_label to this value.

The ct_label value is not used directly in the HW rules and
instead it is mapped to some id within a defined range and this
id is used to set and match the metadata register which carries
the ct_label.

If we have a rule that matches on ct_label=0, the hw rule will
perform matching on a value that is != 0 because of the mapping
from label to id. Since the metadata register default value is
0 and it was never set before to anything else by an action that
sets the ct_label, there will always be a mismatch between that
register and the value in the rule.

To support such rule, a forced mapping of ct_label 0 to id=0
is done so that it will match the metadata register default
value of 0.

Fixes: 54b154ec ("net/mlx5e: CT: Map 128 bits labels to 32 bit map ID")
Signed-off-by: default avatarAriel Levkovich <lariel@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 61431a59
Loading
Loading
Loading
Loading
+29 −7
Original line number Diff line number Diff line
@@ -185,6 +185,28 @@ mlx5_tc_ct_entry_has_nat(struct mlx5_ct_entry *entry)
	return !!(entry->tuple_nat_node.next);
}

static int
mlx5_get_label_mapping(struct mlx5_tc_ct_priv *ct_priv,
		       u32 *labels, u32 *id)
{
	if (!memchr_inv(labels, 0, sizeof(u32) * 4)) {
		*id = 0;
		return 0;
	}

	if (mapping_add(ct_priv->labels_mapping, labels, id))
		return -EOPNOTSUPP;

	return 0;
}

static void
mlx5_put_label_mapping(struct mlx5_tc_ct_priv *ct_priv, u32 id)
{
	if (id)
		mapping_remove(ct_priv->labels_mapping, id);
}

static int
mlx5_tc_ct_rule_to_tuple(struct mlx5_ct_tuple *tuple, struct flow_rule *rule)
{
@@ -436,7 +458,7 @@ mlx5_tc_ct_entry_del_rule(struct mlx5_tc_ct_priv *ct_priv,
	mlx5_tc_rule_delete(netdev_priv(ct_priv->netdev), zone_rule->rule, attr);
	mlx5e_mod_hdr_detach(ct_priv->dev,
			     ct_priv->mod_hdr_tbl, zone_rule->mh);
	mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
	mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
	kfree(attr);
}

@@ -639,7 +661,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
	if (!meta)
		return -EOPNOTSUPP;

	err = mapping_add(ct_priv->labels_mapping, meta->ct_metadata.labels,
	err = mlx5_get_label_mapping(ct_priv, meta->ct_metadata.labels,
				     &attr->ct_attr.ct_labels_id);
	if (err)
		return -EOPNOTSUPP;
@@ -677,7 +699,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,

err_mapping:
	dealloc_mod_hdr_actions(&mod_acts);
	mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
	mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
	return err;
}

@@ -745,7 +767,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
err_rule:
	mlx5e_mod_hdr_detach(ct_priv->dev,
			     ct_priv->mod_hdr_tbl, zone_rule->mh);
	mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
	mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
err_mod_hdr:
	kfree(attr);
err_attr:
@@ -1197,7 +1219,7 @@ void mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_
	if (!priv || !ct_attr->ct_labels_id)
		return;

	mapping_remove(priv->labels_mapping, ct_attr->ct_labels_id);
	mlx5_put_label_mapping(priv, ct_attr->ct_labels_id);
}

int
@@ -1280,7 +1302,7 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
		ct_labels[1] = key->ct_labels[1] & mask->ct_labels[1];
		ct_labels[2] = key->ct_labels[2] & mask->ct_labels[2];
		ct_labels[3] = key->ct_labels[3] & mask->ct_labels[3];
		if (mapping_add(priv->labels_mapping, ct_labels, &ct_attr->ct_labels_id))
		if (mlx5_get_label_mapping(priv, ct_labels, &ct_attr->ct_labels_id))
			return -EOPNOTSUPP;
		mlx5e_tc_match_to_reg_match(spec, LABELS_TO_REG, ct_attr->ct_labels_id,
					    MLX5_CT_LABELS_MASK);