mlxsw: spectrum_acl: Include delta bits into hashtable key
Currently only ERP mask masked bits in key are considered for the hashtable key. That leads to false negative collisions and fallbacks to C-TCAM in case two keys differ only in delta bits. Fix this by taking full encoded key as a hashtable key, including delta bits. Reported-by: Nir Dotan <nird@mellanox.com> Signed-off-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
804a15cdbb
commit
cb56e21467
@ -390,8 +390,7 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
lkey_id = aregion->ops->lkey_id_get(aregion, aentry->ht_key.enc_key,
|
||||
erp_id);
|
||||
lkey_id = aregion->ops->lkey_id_get(aregion, aentry->enc_key, erp_id);
|
||||
if (IS_ERR(lkey_id))
|
||||
return PTR_ERR(lkey_id);
|
||||
aentry->lkey_id = lkey_id;
|
||||
@ -399,7 +398,7 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp,
|
||||
kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
|
||||
mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE,
|
||||
priority, region->tcam_region_info,
|
||||
aentry->ht_key.enc_key, erp_id,
|
||||
aentry->enc_key, erp_id,
|
||||
aentry->delta_info.start,
|
||||
aentry->delta_info.mask,
|
||||
aentry->delta_info.value,
|
||||
@ -424,12 +423,11 @@ mlxsw_sp_acl_atcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_atcam_lkey_id *lkey_id = aentry->lkey_id;
|
||||
struct mlxsw_sp_acl_tcam_region *region = aregion->region;
|
||||
u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask);
|
||||
char *enc_key = aentry->ht_key.enc_key;
|
||||
char ptce3_pl[MLXSW_REG_PTCE3_LEN];
|
||||
|
||||
mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0,
|
||||
region->tcam_region_info,
|
||||
enc_key, erp_id,
|
||||
aentry->enc_key, erp_id,
|
||||
aentry->delta_info.start,
|
||||
aentry->delta_info.mask,
|
||||
aentry->delta_info.value,
|
||||
@ -458,7 +456,7 @@ mlxsw_sp_acl_atcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
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->enc_key, erp_id,
|
||||
aentry->delta_info.start,
|
||||
aentry->delta_info.mask,
|
||||
aentry->delta_info.value,
|
||||
@ -481,15 +479,15 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
|
||||
int err;
|
||||
|
||||
mlxsw_afk_encode(afk, region->key_info, &rulei->values,
|
||||
aentry->full_enc_key, mask);
|
||||
aentry->ht_key.full_enc_key, mask);
|
||||
|
||||
erp_mask = mlxsw_sp_acl_erp_mask_get(aregion, mask, false);
|
||||
if (IS_ERR(erp_mask))
|
||||
return PTR_ERR(erp_mask);
|
||||
aentry->erp_mask = erp_mask;
|
||||
aentry->ht_key.erp_id = mlxsw_sp_acl_erp_mask_erp_id(erp_mask);
|
||||
memcpy(aentry->ht_key.enc_key, aentry->full_enc_key,
|
||||
sizeof(aentry->ht_key.enc_key));
|
||||
memcpy(aentry->enc_key, aentry->ht_key.full_enc_key,
|
||||
sizeof(aentry->enc_key));
|
||||
|
||||
/* Compute all needed delta information and clear the delta bits
|
||||
* from the encrypted key.
|
||||
@ -498,8 +496,9 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
|
||||
aentry->delta_info.start = mlxsw_sp_acl_erp_delta_start(delta);
|
||||
aentry->delta_info.mask = mlxsw_sp_acl_erp_delta_mask(delta);
|
||||
aentry->delta_info.value =
|
||||
mlxsw_sp_acl_erp_delta_value(delta, aentry->full_enc_key);
|
||||
mlxsw_sp_acl_erp_delta_clear(delta, aentry->ht_key.enc_key);
|
||||
mlxsw_sp_acl_erp_delta_value(delta,
|
||||
aentry->ht_key.full_enc_key);
|
||||
mlxsw_sp_acl_erp_delta_clear(delta, aentry->enc_key);
|
||||
|
||||
/* Add rule to the list of A-TCAM rules, assuming this
|
||||
* rule is intended to A-TCAM. In case this rule does
|
||||
|
@ -133,7 +133,7 @@ mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
memcpy(chunk + MLXSW_BLOOM_CHUNK_PAD_BYTES, &erp_region_id,
|
||||
sizeof(erp_region_id));
|
||||
memcpy(chunk + MLXSW_BLOOM_CHUNK_KEY_OFFSET,
|
||||
&aentry->ht_key.enc_key[chunk_key_offsets[chunk_index]],
|
||||
&aentry->enc_key[chunk_key_offsets[chunk_index]],
|
||||
MLXSW_BLOOM_CHUNK_KEY_BYTES);
|
||||
chunk += MLXSW_BLOOM_KEY_CHUNK_BYTES;
|
||||
}
|
||||
|
@ -161,9 +161,9 @@ struct mlxsw_sp_acl_atcam_region {
|
||||
};
|
||||
|
||||
struct mlxsw_sp_acl_atcam_entry_ht_key {
|
||||
char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
|
||||
* minus delta bits.
|
||||
*/
|
||||
char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
|
||||
* key.
|
||||
*/
|
||||
u8 erp_id;
|
||||
};
|
||||
|
||||
@ -175,7 +175,9 @@ struct mlxsw_sp_acl_atcam_entry {
|
||||
struct rhash_head ht_node;
|
||||
struct list_head list; /* Member in entries_list */
|
||||
struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
|
||||
char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key */
|
||||
char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
|
||||
* minus delta bits.
|
||||
*/
|
||||
struct {
|
||||
u16 start;
|
||||
u8 mask;
|
||||
|
Loading…
Reference in New Issue
Block a user