mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
mlxsw: spectrum_acl: Add replace rule action operation
Multicast routes actions may be updated after creation. An example for that is an addition of an egress interface to an existing route. So far, as tc flower API dictated, ACL rules were either created or deleted. Since multicast routes in Spectrum-2 are written to ACL as any rule, it is required to allow the update of a rule's action as it may change. Add methods and operations to support updating rule's action. This is supported only for Spectrum-2. Signed-off-by: Nir Dotan <nird@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1a29d29394
commit
2507a64c17
@ -658,6 +658,9 @@ int mlxsw_sp_acl_rule_add(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_rule *rule);
|
||||
void mlxsw_sp_acl_rule_del(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_rule *rule);
|
||||
int mlxsw_sp_acl_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_rule *rule,
|
||||
struct mlxsw_afa_block *afa_block);
|
||||
struct mlxsw_sp_acl_rule *
|
||||
mlxsw_sp_acl_rule_lookup(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ruleset *ruleset,
|
||||
@ -702,6 +705,10 @@ struct mlxsw_sp_acl_tcam_ops {
|
||||
void (*entry_del)(struct mlxsw_sp *mlxsw_sp,
|
||||
void *region_priv, void *chunk_priv,
|
||||
void *entry_priv);
|
||||
int (*entry_action_replace)(struct mlxsw_sp *mlxsw_sp,
|
||||
void *region_priv, void *chunk_priv,
|
||||
void *entry_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei);
|
||||
int (*entry_activity_get)(struct mlxsw_sp *mlxsw_sp,
|
||||
void *region_priv, void *entry_priv,
|
||||
bool *activity);
|
||||
|
@ -192,6 +192,15 @@ static void mlxsw_sp1_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
&chunk->cchunk, &entry->centry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp1_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
void *region_priv, void *chunk_priv,
|
||||
void *entry_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp1_acl_tcam_region_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_region *_region,
|
||||
@ -240,5 +249,6 @@ const struct mlxsw_sp_acl_tcam_ops mlxsw_sp1_acl_tcam_ops = {
|
||||
.entry_priv_size = sizeof(struct mlxsw_sp1_acl_tcam_entry),
|
||||
.entry_add = mlxsw_sp1_acl_tcam_entry_add,
|
||||
.entry_del = mlxsw_sp1_acl_tcam_entry_del,
|
||||
.entry_action_replace = mlxsw_sp1_acl_tcam_entry_action_replace,
|
||||
.entry_activity_get = mlxsw_sp1_acl_tcam_entry_activity_get,
|
||||
};
|
||||
|
@ -210,6 +210,23 @@ static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
&entry->aentry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp2_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
void *region_priv, void *chunk_priv,
|
||||
void *entry_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
|
||||
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
|
||||
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
|
||||
|
||||
entry->act_block = rulei->act_block;
|
||||
return mlxsw_sp_acl_atcam_entry_action_replace(mlxsw_sp,
|
||||
®ion->aregion,
|
||||
&chunk->achunk,
|
||||
&entry->aentry, rulei);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp2_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
void *region_priv, void *entry_priv,
|
||||
@ -235,5 +252,6 @@ const struct mlxsw_sp_acl_tcam_ops mlxsw_sp2_acl_tcam_ops = {
|
||||
.entry_priv_size = sizeof(struct mlxsw_sp2_acl_tcam_entry),
|
||||
.entry_add = mlxsw_sp2_acl_tcam_entry_add,
|
||||
.entry_del = mlxsw_sp2_acl_tcam_entry_del,
|
||||
.entry_action_replace = mlxsw_sp2_acl_tcam_entry_action_replace,
|
||||
.entry_activity_get = mlxsw_sp2_acl_tcam_entry_activity_get,
|
||||
};
|
||||
|
@ -721,6 +721,21 @@ void mlxsw_sp_acl_rule_del(struct mlxsw_sp *mlxsw_sp,
|
||||
ops->rule_del(mlxsw_sp, rule->priv);
|
||||
}
|
||||
|
||||
int mlxsw_sp_acl_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_rule *rule,
|
||||
struct mlxsw_afa_block *afa_block)
|
||||
{
|
||||
struct mlxsw_sp_acl_ruleset *ruleset = rule->ruleset;
|
||||
const struct mlxsw_sp_acl_profile_ops *ops = ruleset->ht_key.ops;
|
||||
struct mlxsw_sp_acl_rule_info *rulei;
|
||||
|
||||
rulei = mlxsw_sp_acl_rule_rulei(rule);
|
||||
rulei->act_block = afa_block;
|
||||
|
||||
return ops->rule_action_replace(mlxsw_sp, ruleset->priv, rule->priv,
|
||||
rule->rulei);
|
||||
}
|
||||
|
||||
struct mlxsw_sp_acl_rule *
|
||||
mlxsw_sp_acl_rule_lookup(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ruleset *ruleset,
|
||||
|
@ -437,6 +437,34 @@ mlxsw_sp_acl_atcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp,
|
||||
aregion->ops->lkey_id_put(aregion, lkey_id);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_atcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
struct mlxsw_sp_acl_atcam_entry *aentry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
struct mlxsw_sp_acl_atcam_lkey_id *lkey_id = aentry->lkey_id;
|
||||
u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask);
|
||||
struct mlxsw_sp_acl_tcam_region *region = aregion->region;
|
||||
char ptce3_pl[MLXSW_REG_PTCE3_LEN];
|
||||
u32 kvdl_index, priority;
|
||||
int err;
|
||||
|
||||
err = mlxsw_sp_acl_tcam_priority_get(mlxsw_sp, rulei, &priority, true);
|
||||
if (err)
|
||||
return err;
|
||||
kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
|
||||
mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE,
|
||||
priority, region->tcam_region_info,
|
||||
aentry->ht_key.enc_key, erp_id,
|
||||
aentry->delta_info.start,
|
||||
aentry->delta_info.mask,
|
||||
aentry->delta_info.value,
|
||||
refcount_read(&lkey_id->refcnt) != 1, lkey_id->id,
|
||||
kvdl_index);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce3), ptce3_pl);
|
||||
}
|
||||
|
||||
static int
|
||||
__mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
@ -506,6 +534,16 @@ __mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
mlxsw_sp_acl_erp_mask_put(aregion, aentry->erp_mask);
|
||||
}
|
||||
|
||||
static int
|
||||
__mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
struct mlxsw_sp_acl_atcam_entry *aentry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
return mlxsw_sp_acl_atcam_region_entry_action_replace(mlxsw_sp, aregion,
|
||||
aentry, rulei);
|
||||
}
|
||||
|
||||
int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
struct mlxsw_sp_acl_atcam_chunk *achunk,
|
||||
@ -542,6 +580,29 @@ void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
__mlxsw_sp_acl_atcam_entry_del(mlxsw_sp, aregion, aentry);
|
||||
}
|
||||
|
||||
int
|
||||
mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
struct mlxsw_sp_acl_atcam_chunk *achunk,
|
||||
struct mlxsw_sp_acl_atcam_entry *aentry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (mlxsw_sp_acl_atcam_is_centry(aentry))
|
||||
err = mlxsw_sp_acl_ctcam_entry_action_replace(mlxsw_sp,
|
||||
&aregion->cregion,
|
||||
&achunk->cchunk,
|
||||
&aentry->centry,
|
||||
rulei);
|
||||
else
|
||||
err = __mlxsw_sp_acl_atcam_entry_action_replace(mlxsw_sp,
|
||||
aregion, aentry,
|
||||
rulei);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam *atcam)
|
||||
{
|
||||
|
@ -89,6 +89,27 @@ mlxsw_sp_acl_ctcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp,
|
||||
cregion->ops->entry_remove(cregion, centry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_ctcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ctcam_region *cregion,
|
||||
struct mlxsw_sp_acl_ctcam_entry *centry,
|
||||
struct mlxsw_afa_block *afa_block,
|
||||
unsigned int priority)
|
||||
{
|
||||
char ptce2_pl[MLXSW_REG_PTCE2_LEN];
|
||||
char *act_set;
|
||||
|
||||
mlxsw_reg_ptce2_pack(ptce2_pl, true, MLXSW_REG_PTCE2_OP_WRITE_UPDATE,
|
||||
cregion->region->tcam_region_info,
|
||||
centry->parman_item.index, priority);
|
||||
|
||||
act_set = mlxsw_afa_block_first_set(afa_block);
|
||||
mlxsw_reg_ptce2_flex_action_set_memcpy_to(ptce2_pl, act_set);
|
||||
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl);
|
||||
}
|
||||
|
||||
|
||||
static int mlxsw_sp_acl_ctcam_region_parman_resize(void *priv,
|
||||
unsigned long new_count)
|
||||
{
|
||||
@ -191,3 +212,15 @@ void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
parman_item_remove(cregion->parman, &cchunk->parman_prio,
|
||||
¢ry->parman_item);
|
||||
}
|
||||
|
||||
int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ctcam_region *cregion,
|
||||
struct mlxsw_sp_acl_ctcam_chunk *cchunk,
|
||||
struct mlxsw_sp_acl_ctcam_entry *centry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
return mlxsw_sp_acl_ctcam_region_entry_action_replace(mlxsw_sp, cregion,
|
||||
centry,
|
||||
rulei->act_block,
|
||||
rulei->priority);
|
||||
}
|
||||
|
@ -778,6 +778,20 @@ static void mlxsw_sp_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
mlxsw_sp_acl_tcam_chunk_put(mlxsw_sp, chunk);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_group *group,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
|
||||
struct mlxsw_sp_acl_tcam_chunk *chunk = entry->chunk;
|
||||
struct mlxsw_sp_acl_tcam_region *region = chunk->region;
|
||||
|
||||
return ops->entry_action_replace(mlxsw_sp, region->priv, chunk->priv,
|
||||
entry->priv, rulei);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_entry *entry,
|
||||
@ -938,6 +952,15 @@ mlxsw_sp_acl_tcam_flower_rule_del(struct mlxsw_sp *mlxsw_sp, void *rule_priv)
|
||||
mlxsw_sp_acl_tcam_entry_del(mlxsw_sp, &rule->entry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_flower_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
void *ruleset_priv,
|
||||
void *rule_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_flower_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
void *rule_priv, bool *activity)
|
||||
@ -958,6 +981,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
|
||||
.rule_priv_size = mlxsw_sp_acl_tcam_flower_rule_priv_size,
|
||||
.rule_add = mlxsw_sp_acl_tcam_flower_rule_add,
|
||||
.rule_del = mlxsw_sp_acl_tcam_flower_rule_del,
|
||||
.rule_action_replace = mlxsw_sp_acl_tcam_flower_rule_action_replace,
|
||||
.rule_activity_get = mlxsw_sp_acl_tcam_flower_rule_activity_get,
|
||||
};
|
||||
|
||||
@ -1057,6 +1081,18 @@ mlxsw_sp_acl_tcam_mr_rule_del(struct mlxsw_sp *mlxsw_sp, void *rule_priv)
|
||||
mlxsw_sp_acl_tcam_entry_del(mlxsw_sp, &rule->entry);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_mr_rule_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
void *ruleset_priv, void *rule_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei)
|
||||
{
|
||||
struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
|
||||
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
|
||||
|
||||
return mlxsw_sp_acl_tcam_entry_action_replace(mlxsw_sp, &ruleset->group,
|
||||
&rule->entry, rulei);
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
|
||||
void *rule_priv, bool *activity)
|
||||
@ -1077,6 +1113,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
|
||||
.rule_priv_size = mlxsw_sp_acl_tcam_mr_rule_priv_size,
|
||||
.rule_add = mlxsw_sp_acl_tcam_mr_rule_add,
|
||||
.rule_del = mlxsw_sp_acl_tcam_mr_rule_del,
|
||||
.rule_action_replace = mlxsw_sp_acl_tcam_mr_rule_action_replace,
|
||||
.rule_activity_get = mlxsw_sp_acl_tcam_mr_rule_activity_get,
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,9 @@ struct mlxsw_sp_acl_profile_ops {
|
||||
void *ruleset_priv, void *rule_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei);
|
||||
void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
|
||||
int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp,
|
||||
void *ruleset_priv, void *rule_priv,
|
||||
struct mlxsw_sp_acl_rule_info *rulei);
|
||||
int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
|
||||
bool *activity);
|
||||
};
|
||||
@ -121,6 +124,11 @@ void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ctcam_region *cregion,
|
||||
struct mlxsw_sp_acl_ctcam_chunk *cchunk,
|
||||
struct mlxsw_sp_acl_ctcam_entry *centry);
|
||||
int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ctcam_region *cregion,
|
||||
struct mlxsw_sp_acl_ctcam_chunk *cchunk,
|
||||
struct mlxsw_sp_acl_ctcam_entry *centry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei);
|
||||
static inline unsigned int
|
||||
mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
|
||||
{
|
||||
@ -212,6 +220,11 @@ void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
struct mlxsw_sp_acl_atcam_chunk *achunk,
|
||||
struct mlxsw_sp_acl_atcam_entry *aentry);
|
||||
int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
struct mlxsw_sp_acl_atcam_chunk *achunk,
|
||||
struct mlxsw_sp_acl_atcam_entry *aentry,
|
||||
struct mlxsw_sp_acl_rule_info *rulei);
|
||||
int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam *atcam);
|
||||
void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
|
||||
|
Loading…
Reference in New Issue
Block a user