mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-10 07:44:23 +08:00
mlxsw: spectrum_router: Add support for blackhole nexthops
Add support for blackhole nexthops by programming them to the adjacency table with a discard action. Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
18c4b79d28
commit
68e92ad855
@ -913,7 +913,8 @@ static u64 mlxsw_sp_dpipe_table_adj_size(struct mlxsw_sp *mlxsw_sp)
|
||||
|
||||
mlxsw_sp_nexthop_for_each(nh, mlxsw_sp->router)
|
||||
if (mlxsw_sp_nexthop_offload(nh) &&
|
||||
!mlxsw_sp_nexthop_group_has_ipip(nh))
|
||||
!mlxsw_sp_nexthop_group_has_ipip(nh) &&
|
||||
!mlxsw_sp_nexthop_is_discard(nh))
|
||||
size++;
|
||||
return size;
|
||||
}
|
||||
@ -1105,7 +1106,8 @@ start_again:
|
||||
nh_count = 0;
|
||||
mlxsw_sp_nexthop_for_each(nh, mlxsw_sp->router) {
|
||||
if (!mlxsw_sp_nexthop_offload(nh) ||
|
||||
mlxsw_sp_nexthop_group_has_ipip(nh))
|
||||
mlxsw_sp_nexthop_group_has_ipip(nh) ||
|
||||
mlxsw_sp_nexthop_is_discard(nh))
|
||||
continue;
|
||||
|
||||
if (nh_count < nh_skip)
|
||||
@ -1186,7 +1188,8 @@ static int mlxsw_sp_dpipe_table_adj_counters_update(void *priv, bool enable)
|
||||
|
||||
mlxsw_sp_nexthop_for_each(nh, mlxsw_sp->router) {
|
||||
if (!mlxsw_sp_nexthop_offload(nh) ||
|
||||
mlxsw_sp_nexthop_group_has_ipip(nh))
|
||||
mlxsw_sp_nexthop_group_has_ipip(nh) ||
|
||||
mlxsw_sp_nexthop_is_discard(nh))
|
||||
continue;
|
||||
|
||||
mlxsw_sp_nexthop_indexes(nh, &adj_index, &adj_size,
|
||||
|
@ -2858,9 +2858,10 @@ struct mlxsw_sp_nexthop {
|
||||
offloaded:1, /* set in case the neigh is actually put into
|
||||
* KVD linear area of this group.
|
||||
*/
|
||||
update:1; /* set indicates that MAC of this neigh should be
|
||||
update:1, /* set indicates that MAC of this neigh should be
|
||||
* updated in HW
|
||||
*/
|
||||
discard:1; /* nexthop is programmed to discard packets */
|
||||
enum mlxsw_sp_nexthop_type type;
|
||||
union {
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry;
|
||||
@ -3011,6 +3012,11 @@ bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mlxsw_sp_nexthop_is_discard(const struct mlxsw_sp_nexthop *nh)
|
||||
{
|
||||
return nh->discard;
|
||||
}
|
||||
|
||||
struct mlxsw_sp_nexthop_group_cmp_arg {
|
||||
enum mlxsw_sp_nexthop_group_type type;
|
||||
union {
|
||||
@ -3285,7 +3291,11 @@ static int __mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
|
||||
mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY,
|
||||
true, MLXSW_REG_RATR_TYPE_ETHERNET,
|
||||
adj_index, nh->rif->rif_index);
|
||||
mlxsw_reg_ratr_eth_entry_pack(ratr_pl, neigh_entry->ha);
|
||||
if (nh->discard)
|
||||
mlxsw_reg_ratr_trap_action_set(ratr_pl,
|
||||
MLXSW_REG_RATR_TRAP_ACTION_DISCARD_ERRORS);
|
||||
else
|
||||
mlxsw_reg_ratr_eth_entry_pack(ratr_pl, neigh_entry->ha);
|
||||
if (nh->counter_valid)
|
||||
mlxsw_reg_ratr_counter_pack(ratr_pl, nh->counter_index, true);
|
||||
else
|
||||
@ -4128,9 +4138,7 @@ mlxsw_sp_nexthop_obj_single_validate(struct mlxsw_sp *mlxsw_sp,
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (nh->is_reject)
|
||||
NL_SET_ERR_MSG_MOD(extack, "Blackhole nexthops are not supported");
|
||||
else if (nh->is_fdb)
|
||||
if (nh->is_fdb)
|
||||
NL_SET_ERR_MSG_MOD(extack, "FDB nexthops are not supported");
|
||||
else if (nh->has_encap)
|
||||
NL_SET_ERR_MSG_MOD(extack, "Encapsulating nexthops are not supported");
|
||||
@ -4165,7 +4173,7 @@ mlxsw_sp_nexthop_obj_group_validate(struct mlxsw_sp *mlxsw_sp,
|
||||
/* Device only nexthops with an IPIP device are programmed as
|
||||
* encapsulating adjacency entries.
|
||||
*/
|
||||
if (!nh->gw_family &&
|
||||
if (!nh->gw_family && !nh->is_reject &&
|
||||
!mlxsw_sp_netdev_ipip_type(mlxsw_sp, nh->dev, NULL)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Nexthop group entry does not have a gateway");
|
||||
return -EINVAL;
|
||||
@ -4199,10 +4207,31 @@ static bool mlxsw_sp_nexthop_obj_is_gateway(struct mlxsw_sp *mlxsw_sp,
|
||||
return true;
|
||||
|
||||
dev = info->nh->dev;
|
||||
return info->nh->gw_family ||
|
||||
return info->nh->gw_family || info->nh->is_reject ||
|
||||
mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_nexthop *nh)
|
||||
{
|
||||
u16 lb_rif_index = mlxsw_sp->router->lb_rif_index;
|
||||
|
||||
nh->discard = 1;
|
||||
nh->should_offload = 1;
|
||||
/* While nexthops that discard packets do not forward packets
|
||||
* via an egress RIF, they still need to be programmed using a
|
||||
* valid RIF, so use the loopback RIF created during init.
|
||||
*/
|
||||
nh->rif = mlxsw_sp->router->rifs[lb_rif_index];
|
||||
}
|
||||
|
||||
static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_nexthop *nh)
|
||||
{
|
||||
nh->rif = NULL;
|
||||
nh->should_offload = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_nexthop_obj_init(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_nexthop_group *nh_grp,
|
||||
@ -4236,6 +4265,9 @@ mlxsw_sp_nexthop_obj_init(struct mlxsw_sp *mlxsw_sp,
|
||||
if (err)
|
||||
goto err_type_init;
|
||||
|
||||
if (nh_obj->is_reject)
|
||||
mlxsw_sp_nexthop_obj_blackhole_init(mlxsw_sp, nh);
|
||||
|
||||
return 0;
|
||||
|
||||
err_type_init:
|
||||
@ -4247,6 +4279,8 @@ err_type_init:
|
||||
static void mlxsw_sp_nexthop_obj_fini(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_nexthop *nh)
|
||||
{
|
||||
if (nh->discard)
|
||||
mlxsw_sp_nexthop_obj_blackhole_fini(mlxsw_sp, nh);
|
||||
mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
|
||||
list_del(&nh->router_list_node);
|
||||
mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh);
|
||||
|
@ -201,6 +201,7 @@ int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index,
|
||||
u32 *p_adj_size, u32 *p_adj_hash_index);
|
||||
struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh);
|
||||
bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh);
|
||||
bool mlxsw_sp_nexthop_is_discard(const struct mlxsw_sp_nexthop *nh);
|
||||
#define mlxsw_sp_nexthop_for_each(nh, router) \
|
||||
for (nh = mlxsw_sp_nexthop_next(router, NULL); nh; \
|
||||
nh = mlxsw_sp_nexthop_next(router, nh))
|
||||
|
Loading…
Reference in New Issue
Block a user