Commit 54b154ec authored by Eli Britstein's avatar Eli Britstein Committed by Saeed Mahameed

net/mlx5e: CT: Map 128 bits labels to 32 bit map ID

The 128 bits ct_label field is matched using a 32 bit hardware register.
As such, only the lower 32 bits of ct_label field are offloaded. Change
this logic to support setting and matching higher bits too.
Map the 128 bits data to a unique 32 bits ID. Matching is done as exact
match of the mapping ID of key & mask.
Signed-off-by: default avatarEli Britstein <elibr@mellanox.com>
Reviewed-by: default avatarOz Shlomo <ozsh@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Reviewed-by: default avatarMaor Dickman <maord@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 0bdc89b3
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#define MLX5_FTE_ID_MAX GENMASK(MLX5_FTE_ID_BITS - 1, 0) #define MLX5_FTE_ID_MAX GENMASK(MLX5_FTE_ID_BITS - 1, 0)
#define MLX5_FTE_ID_MASK MLX5_FTE_ID_MAX #define MLX5_FTE_ID_MASK MLX5_FTE_ID_MAX
#define MLX5_CT_LABELS_BITS (mlx5e_tc_attr_to_reg_mappings[LABELS_TO_REG].mlen * 8)
#define MLX5_CT_LABELS_MASK GENMASK(MLX5_CT_LABELS_BITS - 1, 0)
#define ct_dbg(fmt, args...)\ #define ct_dbg(fmt, args...)\
netdev_dbg(ct_priv->netdev, "ct_debug: " fmt "\n", ##args) netdev_dbg(ct_priv->netdev, "ct_debug: " fmt "\n", ##args)
...@@ -48,6 +51,7 @@ struct mlx5_tc_ct_priv { ...@@ -48,6 +51,7 @@ struct mlx5_tc_ct_priv {
struct mlx5_flow_table *post_ct; struct mlx5_flow_table *post_ct;
struct mutex control_lock; /* guards parallel adds/dels */ struct mutex control_lock; /* guards parallel adds/dels */
struct mapping_ctx *zone_mapping; struct mapping_ctx *zone_mapping;
struct mapping_ctx *labels_mapping;
}; };
struct mlx5_ct_flow { struct mlx5_ct_flow {
...@@ -404,6 +408,7 @@ mlx5_tc_ct_entry_del_rule(struct mlx5_tc_ct_priv *ct_priv, ...@@ -404,6 +408,7 @@ mlx5_tc_ct_entry_del_rule(struct mlx5_tc_ct_priv *ct_priv,
mlx5_eswitch_del_offloaded_rule(esw, zone_rule->rule, attr); mlx5_eswitch_del_offloaded_rule(esw, zone_rule->rule, attr);
mlx5e_mod_hdr_detach(ct_priv->esw->dev, mlx5e_mod_hdr_detach(ct_priv->esw->dev,
&esw->offloads.mod_hdr, zone_rule->mh); &esw->offloads.mod_hdr, zone_rule->mh);
mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
} }
static void static void
...@@ -436,7 +441,7 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv, ...@@ -436,7 +441,7 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv,
struct mlx5e_tc_mod_hdr_acts *mod_acts, struct mlx5e_tc_mod_hdr_acts *mod_acts,
u8 ct_state, u8 ct_state,
u32 mark, u32 mark,
u32 label, u32 labels_id,
u8 zone_restore_id) u8 zone_restore_id)
{ {
struct mlx5_eswitch *esw = ct_priv->esw; struct mlx5_eswitch *esw = ct_priv->esw;
...@@ -453,7 +458,7 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv, ...@@ -453,7 +458,7 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv,
return err; return err;
err = mlx5e_tc_match_to_reg_set(esw->dev, mod_acts, err = mlx5e_tc_match_to_reg_set(esw->dev, mod_acts,
LABELS_TO_REG, label); LABELS_TO_REG, labels_id);
if (err) if (err)
return err; return err;
...@@ -597,13 +602,10 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv, ...@@ -597,13 +602,10 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
if (!meta) if (!meta)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (meta->ct_metadata.labels[1] || err = mapping_add(ct_priv->labels_mapping, meta->ct_metadata.labels,
meta->ct_metadata.labels[2] || &attr->ct_attr.ct_labels_id);
meta->ct_metadata.labels[3]) { if (err)
ct_dbg("Failed to offload ct entry due to unsupported label");
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
if (nat) { if (nat) {
err = mlx5_tc_ct_entry_create_nat(ct_priv, flow_rule, err = mlx5_tc_ct_entry_create_nat(ct_priv, flow_rule,
&mod_acts); &mod_acts);
...@@ -617,7 +619,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv, ...@@ -617,7 +619,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
err = mlx5_tc_ct_entry_set_registers(ct_priv, &mod_acts, err = mlx5_tc_ct_entry_set_registers(ct_priv, &mod_acts,
ct_state, ct_state,
meta->ct_metadata.mark, meta->ct_metadata.mark,
meta->ct_metadata.labels[0], attr->ct_attr.ct_labels_id,
zone_restore_id); zone_restore_id);
if (err) if (err)
goto err_mapping; goto err_mapping;
...@@ -637,6 +639,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv, ...@@ -637,6 +639,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
err_mapping: err_mapping:
dealloc_mod_hdr_actions(&mod_acts); dealloc_mod_hdr_actions(&mod_acts);
mapping_remove(ct_priv->labels_mapping, attr->ct_attr.ct_labels_id);
return err; return err;
} }
...@@ -959,6 +962,7 @@ int ...@@ -959,6 +962,7 @@ int
mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec, struct mlx5_flow_spec *spec,
struct flow_cls_offload *f, struct flow_cls_offload *f,
struct mlx5_ct_attr *ct_attr,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv); struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
...@@ -969,6 +973,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, ...@@ -969,6 +973,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
u16 ct_state_on, ct_state_off; u16 ct_state_on, ct_state_off;
u16 ct_state, ct_state_mask; u16 ct_state, ct_state_mask;
struct flow_match_ct match; struct flow_match_ct match;
u32 ct_labels[4];
if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT)) if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT))
return 0; return 0;
...@@ -995,12 +1000,6 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, ...@@ -995,12 +1000,6 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (mask->ct_labels[1] || mask->ct_labels[2] || mask->ct_labels[3]) {
NL_SET_ERR_MSG_MOD(extack,
"only lower 32bits of ct_labels are supported for offload");
return -EOPNOTSUPP;
}
ct_state_on = ct_state & ct_state_mask; ct_state_on = ct_state & ct_state_mask;
ct_state_off = (ct_state & ct_state_mask) ^ ct_state_mask; ct_state_off = (ct_state & ct_state_mask) ^ ct_state_mask;
trk = ct_state_on & TCA_FLOWER_KEY_CT_FLAGS_TRACKED; trk = ct_state_on & TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
...@@ -1029,10 +1028,17 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, ...@@ -1029,10 +1028,17 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
if (mask->ct_mark) if (mask->ct_mark)
mlx5e_tc_match_to_reg_match(spec, MARK_TO_REG, mlx5e_tc_match_to_reg_match(spec, MARK_TO_REG,
key->ct_mark, mask->ct_mark); key->ct_mark, mask->ct_mark);
if (mask->ct_labels[0]) if (mask->ct_labels[0] || mask->ct_labels[1] || mask->ct_labels[2] ||
mlx5e_tc_match_to_reg_match(spec, LABELS_TO_REG, mask->ct_labels[3]) {
key->ct_labels[0], ct_labels[0] = key->ct_labels[0] & mask->ct_labels[0];
mask->ct_labels[0]); 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(ct_priv->labels_mapping, 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);
}
return 0; return 0;
} }
...@@ -1398,7 +1404,7 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft) ...@@ -1398,7 +1404,7 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
* + tuple + zone match + * + tuple + zone match +
* +--------------------+ * +--------------------+
* | set mark * | set mark
* | set label * | set labels_id
* | set established * | set established
* | set zone_restore * | set zone_restore
* | do nat (if needed) * | do nat (if needed)
...@@ -1789,7 +1795,13 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv) ...@@ -1789,7 +1795,13 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv)
ct_priv->zone_mapping = mapping_create(sizeof(u16), 0, true); ct_priv->zone_mapping = mapping_create(sizeof(u16), 0, true);
if (IS_ERR(ct_priv->zone_mapping)) { if (IS_ERR(ct_priv->zone_mapping)) {
err = PTR_ERR(ct_priv->zone_mapping); err = PTR_ERR(ct_priv->zone_mapping);
goto err_mapping; goto err_mapping_zone;
}
ct_priv->labels_mapping = mapping_create(sizeof(u32) * 4, 0, true);
if (IS_ERR(ct_priv->labels_mapping)) {
err = PTR_ERR(ct_priv->labels_mapping);
goto err_mapping_labels;
} }
ct_priv->esw = esw; ct_priv->esw = esw;
...@@ -1833,8 +1845,10 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv) ...@@ -1833,8 +1845,10 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv)
err_ct_nat_tbl: err_ct_nat_tbl:
mlx5_esw_chains_destroy_global_table(esw, ct_priv->ct); mlx5_esw_chains_destroy_global_table(esw, ct_priv->ct);
err_ct_tbl: err_ct_tbl:
mapping_destroy(ct_priv->labels_mapping);
err_mapping_labels:
mapping_destroy(ct_priv->zone_mapping); mapping_destroy(ct_priv->zone_mapping);
err_mapping: err_mapping_zone:
kfree(ct_priv); kfree(ct_priv);
err_alloc: err_alloc:
err_support: err_support:
...@@ -1854,6 +1868,7 @@ mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv) ...@@ -1854,6 +1868,7 @@ mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv)
mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->ct_nat); mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->ct_nat);
mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->ct); mlx5_esw_chains_destroy_global_table(ct_priv->esw, ct_priv->ct);
mapping_destroy(ct_priv->zone_mapping); mapping_destroy(ct_priv->zone_mapping);
mapping_destroy(ct_priv->labels_mapping);
rhashtable_destroy(&ct_priv->ct_tuples_ht); rhashtable_destroy(&ct_priv->ct_tuples_ht);
rhashtable_destroy(&ct_priv->ct_tuples_nat_ht); rhashtable_destroy(&ct_priv->ct_tuples_nat_ht);
......
...@@ -25,6 +25,7 @@ struct mlx5_ct_attr { ...@@ -25,6 +25,7 @@ struct mlx5_ct_attr {
u16 ct_action; u16 ct_action;
struct mlx5_ct_flow *ct_flow; struct mlx5_ct_flow *ct_flow;
struct nf_flowtable *nf_ft; struct nf_flowtable *nf_ft;
u32 ct_labels_id;
}; };
#define zone_to_reg_ct {\ #define zone_to_reg_ct {\
...@@ -90,6 +91,7 @@ int ...@@ -90,6 +91,7 @@ int
mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec, struct mlx5_flow_spec *spec,
struct flow_cls_offload *f, struct flow_cls_offload *f,
struct mlx5_ct_attr *ct_attr,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int int
mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv, mlx5_tc_ct_add_no_trk_match(struct mlx5e_priv *priv,
...@@ -132,6 +134,7 @@ static inline int ...@@ -132,6 +134,7 @@ static inline int
mlx5_tc_ct_parse_match(struct mlx5e_priv *priv, mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
struct mlx5_flow_spec *spec, struct mlx5_flow_spec *spec,
struct flow_cls_offload *f, struct flow_cls_offload *f,
struct mlx5_ct_attr *ct_attr,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct flow_rule *rule = flow_cls_offload_flow_rule(f);
......
...@@ -4401,7 +4401,8 @@ __mlx5e_add_fdb_flow(struct mlx5e_priv *priv, ...@@ -4401,7 +4401,8 @@ __mlx5e_add_fdb_flow(struct mlx5e_priv *priv,
goto err_free; goto err_free;
/* actions validation depends on parsing the ct matches first */ /* actions validation depends on parsing the ct matches first */
err = mlx5_tc_ct_parse_match(priv, &parse_attr->spec, f, extack); err = mlx5_tc_ct_parse_match(priv, &parse_attr->spec, f,
&flow->esw_attr->ct_attr, extack);
if (err) if (err)
goto err_free; goto err_free;
......
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