Commit cb56e214 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

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: default avatarNir Dotan <nird@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 804a15cd
...@@ -390,8 +390,7 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, ...@@ -390,8 +390,7 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
return err; return err;
lkey_id = aregion->ops->lkey_id_get(aregion, aentry->ht_key.enc_key, lkey_id = aregion->ops->lkey_id_get(aregion, aentry->enc_key, erp_id);
erp_id);
if (IS_ERR(lkey_id)) if (IS_ERR(lkey_id))
return PTR_ERR(lkey_id); return PTR_ERR(lkey_id);
aentry->lkey_id = lkey_id; aentry->lkey_id = lkey_id;
...@@ -399,7 +398,7 @@ mlxsw_sp_acl_atcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp, ...@@ -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); kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE, mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE,
priority, region->tcam_region_info, priority, region->tcam_region_info,
aentry->ht_key.enc_key, erp_id, aentry->enc_key, erp_id,
aentry->delta_info.start, aentry->delta_info.start,
aentry->delta_info.mask, aentry->delta_info.mask,
aentry->delta_info.value, aentry->delta_info.value,
...@@ -424,12 +423,11 @@ mlxsw_sp_acl_atcam_region_entry_remove(struct mlxsw_sp *mlxsw_sp, ...@@ -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_atcam_lkey_id *lkey_id = aentry->lkey_id;
struct mlxsw_sp_acl_tcam_region *region = aregion->region; struct mlxsw_sp_acl_tcam_region *region = aregion->region;
u8 erp_id = mlxsw_sp_acl_erp_mask_erp_id(aentry->erp_mask); 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]; char ptce3_pl[MLXSW_REG_PTCE3_LEN];
mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0, mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0,
region->tcam_region_info, region->tcam_region_info,
enc_key, erp_id, aentry->enc_key, erp_id,
aentry->delta_info.start, aentry->delta_info.start,
aentry->delta_info.mask, aentry->delta_info.mask,
aentry->delta_info.value, aentry->delta_info.value,
...@@ -458,7 +456,7 @@ mlxsw_sp_acl_atcam_region_entry_action_replace(struct mlxsw_sp *mlxsw_sp, ...@@ -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); kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE, mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE,
priority, region->tcam_region_info, priority, region->tcam_region_info,
aentry->ht_key.enc_key, erp_id, aentry->enc_key, erp_id,
aentry->delta_info.start, aentry->delta_info.start,
aentry->delta_info.mask, aentry->delta_info.mask,
aentry->delta_info.value, aentry->delta_info.value,
...@@ -481,15 +479,15 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, ...@@ -481,15 +479,15 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
int err; int err;
mlxsw_afk_encode(afk, region->key_info, &rulei->values, 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); erp_mask = mlxsw_sp_acl_erp_mask_get(aregion, mask, false);
if (IS_ERR(erp_mask)) if (IS_ERR(erp_mask))
return PTR_ERR(erp_mask); return PTR_ERR(erp_mask);
aentry->erp_mask = erp_mask; aentry->erp_mask = erp_mask;
aentry->ht_key.erp_id = mlxsw_sp_acl_erp_mask_erp_id(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, memcpy(aentry->enc_key, aentry->ht_key.full_enc_key,
sizeof(aentry->ht_key.enc_key)); sizeof(aentry->enc_key));
/* Compute all needed delta information and clear the delta bits /* Compute all needed delta information and clear the delta bits
* from the encrypted key. * from the encrypted key.
...@@ -498,8 +496,9 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, ...@@ -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.start = mlxsw_sp_acl_erp_delta_start(delta);
aentry->delta_info.mask = mlxsw_sp_acl_erp_delta_mask(delta); aentry->delta_info.mask = mlxsw_sp_acl_erp_delta_mask(delta);
aentry->delta_info.value = aentry->delta_info.value =
mlxsw_sp_acl_erp_delta_value(delta, aentry->full_enc_key); mlxsw_sp_acl_erp_delta_value(delta,
mlxsw_sp_acl_erp_delta_clear(delta, aentry->ht_key.enc_key); 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 /* Add rule to the list of A-TCAM rules, assuming this
* rule is intended to A-TCAM. In case this rule does * 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, ...@@ -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, memcpy(chunk + MLXSW_BLOOM_CHUNK_PAD_BYTES, &erp_region_id,
sizeof(erp_region_id)); sizeof(erp_region_id));
memcpy(chunk + MLXSW_BLOOM_CHUNK_KEY_OFFSET, 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); MLXSW_BLOOM_CHUNK_KEY_BYTES);
chunk += MLXSW_BLOOM_KEY_CHUNK_BYTES; chunk += MLXSW_BLOOM_KEY_CHUNK_BYTES;
} }
......
...@@ -161,8 +161,8 @@ struct mlxsw_sp_acl_atcam_region { ...@@ -161,8 +161,8 @@ struct mlxsw_sp_acl_atcam_region {
}; };
struct mlxsw_sp_acl_atcam_entry_ht_key { struct mlxsw_sp_acl_atcam_entry_ht_key {
char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key, char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
* minus delta bits. * key.
*/ */
u8 erp_id; u8 erp_id;
}; };
...@@ -175,7 +175,9 @@ struct mlxsw_sp_acl_atcam_entry { ...@@ -175,7 +175,9 @@ struct mlxsw_sp_acl_atcam_entry {
struct rhash_head ht_node; struct rhash_head ht_node;
struct list_head list; /* Member in entries_list */ struct list_head list; /* Member in entries_list */
struct mlxsw_sp_acl_atcam_entry_ht_key ht_key; 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 { struct {
u16 start; u16 start;
u8 mask; u8 mask;
......
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