mlxsw: spectrum_router: Increase parsing depth for multipath hash
Commit01848e05f8
("mlxsw: spectrum_router: Add support for inner layer 3 multipath hash policy") and commitdaeabf89eb
("mlxsw: spectrum_router: Add support for custom multipath hash policy") added support for multipath hash policies where the hash is calculated based on inner packet fields. For IPv6-in-IPv6 packets, the default parsing depth (96 bytes) is not enough when these policies are used. Therefore, for such cases, call the new API to increase / decrease the parsing depth as necessary. Care is taken to ensure the API is not called multiple times. Signed-off-by: Amit Cohen <amcohen@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c3d2ed93b1
commit
43c1b83305
@ -9484,6 +9484,7 @@ struct mlxsw_sp_mp_hash_config {
|
||||
DECLARE_BITMAP(fields, __MLXSW_REG_RECR2_FIELD_CNT);
|
||||
DECLARE_BITMAP(inner_headers, __MLXSW_REG_RECR2_HEADER_CNT);
|
||||
DECLARE_BITMAP(inner_fields, __MLXSW_REG_RECR2_INNER_FIELD_CNT);
|
||||
bool inc_parsing_depth;
|
||||
};
|
||||
|
||||
#define MLXSW_SP_MP_HASH_HEADER_SET(_headers, _header) \
|
||||
@ -9654,6 +9655,7 @@ static void mlxsw_sp_mp6_hash_init(struct mlxsw_sp *mlxsw_sp,
|
||||
MLXSW_SP_MP_HASH_FIELD_SET(fields, IPV6_FLOW_LABEL);
|
||||
/* Inner */
|
||||
mlxsw_sp_mp_hash_inner_l3(config);
|
||||
config->inc_parsing_depth = true;
|
||||
break;
|
||||
case 3:
|
||||
/* Outer */
|
||||
@ -9678,22 +9680,53 @@ static void mlxsw_sp_mp6_hash_init(struct mlxsw_sp *mlxsw_sp,
|
||||
MLXSW_SP_MP_HASH_FIELD_SET(fields, TCP_UDP_DPORT);
|
||||
/* Inner */
|
||||
mlxsw_sp_mp_hash_inner_custom(config, hash_fields);
|
||||
if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_MASK)
|
||||
config->inc_parsing_depth = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int mlxsw_sp_mp_hash_parsing_depth_adjust(struct mlxsw_sp *mlxsw_sp,
|
||||
bool old_inc_parsing_depth,
|
||||
bool new_inc_parsing_depth)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!old_inc_parsing_depth && new_inc_parsing_depth) {
|
||||
err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
|
||||
if (err)
|
||||
return err;
|
||||
mlxsw_sp->router->inc_parsing_depth = true;
|
||||
} else if (old_inc_parsing_depth && !new_inc_parsing_depth) {
|
||||
mlxsw_sp_parsing_depth_dec(mlxsw_sp);
|
||||
mlxsw_sp->router->inc_parsing_depth = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
bool old_inc_parsing_depth, new_inc_parsing_depth;
|
||||
struct mlxsw_sp_mp_hash_config config = {};
|
||||
char recr2_pl[MLXSW_REG_RECR2_LEN];
|
||||
unsigned long bit;
|
||||
u32 seed;
|
||||
int err;
|
||||
|
||||
seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac), 0);
|
||||
mlxsw_reg_recr2_pack(recr2_pl, seed);
|
||||
mlxsw_sp_mp4_hash_init(mlxsw_sp, &config);
|
||||
mlxsw_sp_mp6_hash_init(mlxsw_sp, &config);
|
||||
|
||||
old_inc_parsing_depth = mlxsw_sp->router->inc_parsing_depth;
|
||||
new_inc_parsing_depth = config.inc_parsing_depth;
|
||||
err = mlxsw_sp_mp_hash_parsing_depth_adjust(mlxsw_sp,
|
||||
old_inc_parsing_depth,
|
||||
new_inc_parsing_depth);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
for_each_set_bit(bit, config.headers, __MLXSW_REG_RECR2_HEADER_CNT)
|
||||
mlxsw_reg_recr2_outer_header_enables_set(recr2_pl, bit, 1);
|
||||
for_each_set_bit(bit, config.fields, __MLXSW_REG_RECR2_FIELD_CNT)
|
||||
@ -9703,7 +9736,16 @@ static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
|
||||
for_each_set_bit(bit, config.inner_fields, __MLXSW_REG_RECR2_INNER_FIELD_CNT)
|
||||
mlxsw_reg_recr2_inner_header_fields_enable_set(recr2_pl, bit, 1);
|
||||
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(recr2), recr2_pl);
|
||||
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(recr2), recr2_pl);
|
||||
if (err)
|
||||
goto err_reg_write;
|
||||
|
||||
return 0;
|
||||
|
||||
err_reg_write:
|
||||
mlxsw_sp_mp_hash_parsing_depth_adjust(mlxsw_sp, new_inc_parsing_depth,
|
||||
old_inc_parsing_depth);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
|
||||
|
@ -81,6 +81,7 @@ struct mlxsw_sp_router {
|
||||
size_t adj_grp_size_ranges_count;
|
||||
struct delayed_work nh_grp_activity_dw;
|
||||
struct list_head nh_res_grp_list;
|
||||
bool inc_parsing_depth;
|
||||
};
|
||||
|
||||
struct mlxsw_sp_fib_entry_priv {
|
||||
|
Loading…
Reference in New Issue
Block a user