mlxsw: spectrum_acl: Include delta bits into hashtable key
authorJiri Pirko <jiri@mellanox.com>
Wed, 30 Jan 2019 08:58:33 +0000 (08:58 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Jan 2019 18:00:40 +0000 (10:00 -0800)
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>
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h

index 40dc76a5c4128691c087f505f21df7a0cee9cca0..cda0a7170c34015f3698d93bf5e2b9f808c5046b 100644 (file)
@@ -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
index f5c381dcb015a2bc5389983381e1048ff7472f78..9545b572747eed236266fc47e3fb4a956b3039be 100644 (file)
@@ -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;
        }
index 10512b7c6d50836706234cfaaa17a31be2f68a02..0858d5b0635361841c9e2e1b5a4bbf373cfcde78 100644 (file)
@@ -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;