Commit 68e92ad8 authored by Ido Schimmel's avatar Ido Schimmel Committed by Jakub Kicinski
Browse files

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: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 18c4b79d
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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 @@ mlxsw_sp_dpipe_table_adj_entries_get(struct mlxsw_sp *mlxsw_sp,
	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,
+41 −7
Original line number Diff line number Diff line
@@ -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,6 +3291,10 @@ 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);
	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);
@@ -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 @@ mlxsw_sp_nexthop_obj_init(struct mlxsw_sp *mlxsw_sp,
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);
+1 −0
Original line number Diff line number Diff line
@@ -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))