Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb35da0c authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller
Browse files

mlxsw: spectrum_router: Make IPMR-related APIs family agnostic



spectrum_router and spectrum_mr have several APIs that are used to
manipulate configurations originating from ipmr fib notifications.
Following previous patches all the protocol-specifics that are necessary
for the configuration are hidden within spectrum_mr. This allows us to
clean the API and make sure that other than choosing the mr_table based
on the fib notification family, spectrum_router wouldn't care about the
source of the notification when passing it onward to spectrum_mr.

This would later allow us to leverage the same code for fib
notifications originating from ip6mr.

Signed-off-by: default avatarYuval Mintz <yuvalm@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4caef463
Loading
Loading
Loading
Loading
+19 −33
Original line number Original line Diff line number Diff line
@@ -323,8 +323,8 @@ static void mlxsw_sp_mr_route_erase(struct mlxsw_sp_mr_table *mr_table,
}
}


static struct mlxsw_sp_mr_route *
static struct mlxsw_sp_mr_route *
mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,
mlxsw_sp_mr_route_create(struct mlxsw_sp_mr_table *mr_table,
			  struct mfc_cache *mfc)
			 struct mr_mfc *mfc)
{
{
	struct mlxsw_sp_mr_route_vif_entry *rve, *tmp;
	struct mlxsw_sp_mr_route_vif_entry *rve, *tmp;
	struct mlxsw_sp_mr_route *mr_route;
	struct mlxsw_sp_mr_route *mr_route;
@@ -339,13 +339,13 @@ mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,


	/* Find min_mtu and link iVIF and eVIFs */
	/* Find min_mtu and link iVIF and eVIFs */
	mr_route->min_mtu = ETH_MAX_MTU;
	mr_route->min_mtu = ETH_MAX_MTU;
	mr_cache_hold(&mfc->_c);
	mr_cache_hold(mfc);
	mr_route->mfc = &mfc->_c;
	mr_route->mfc = mfc;
	mr_table->ops->key_create(mr_table, &mr_route->key, mr_route->mfc);
	mr_table->ops->key_create(mr_table, &mr_route->key, mr_route->mfc);


	mr_route->mr_table = mr_table;
	mr_route->mr_table = mr_table;
	for (i = 0; i < MAXVIFS; i++) {
	for (i = 0; i < MAXVIFS; i++) {
		if (mfc->_c.mfc_un.res.ttls[i] != 255) {
		if (mfc->mfc_un.res.ttls[i] != 255) {
			err = mlxsw_sp_mr_route_evif_link(mr_route,
			err = mlxsw_sp_mr_route_evif_link(mr_route,
							  &mr_table->vifs[i]);
							  &mr_table->vifs[i]);
			if (err)
			if (err)
@@ -356,44 +356,30 @@ mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,
		}
		}
	}
	}
	mlxsw_sp_mr_route_ivif_link(mr_route,
	mlxsw_sp_mr_route_ivif_link(mr_route,
				    &mr_table->vifs[mfc->_c.mfc_parent]);
				    &mr_table->vifs[mfc->mfc_parent]);


	mr_route->route_action = mlxsw_sp_mr_route_action(mr_route);
	mr_route->route_action = mlxsw_sp_mr_route_action(mr_route);
	return mr_route;
	return mr_route;
err:
err:
	mr_cache_put(&mfc->_c);
	mr_cache_put(mfc);
	list_for_each_entry_safe(rve, tmp, &mr_route->evif_list, route_node)
	list_for_each_entry_safe(rve, tmp, &mr_route->evif_list, route_node)
		mlxsw_sp_mr_route_evif_unlink(rve);
		mlxsw_sp_mr_route_evif_unlink(rve);
	kfree(mr_route);
	kfree(mr_route);
	return ERR_PTR(err);
	return ERR_PTR(err);
}
}


static void mlxsw_sp_mr_route4_destroy(struct mlxsw_sp_mr_table *mr_table,
static void mlxsw_sp_mr_route_destroy(struct mlxsw_sp_mr_table *mr_table,
				      struct mlxsw_sp_mr_route *mr_route)
				      struct mlxsw_sp_mr_route *mr_route)
{
{
	struct mlxsw_sp_mr_route_vif_entry *rve, *tmp;
	struct mlxsw_sp_mr_route_vif_entry *rve, *tmp;


	mlxsw_sp_mr_route_ivif_unlink(mr_route);
	mlxsw_sp_mr_route_ivif_unlink(mr_route);
	mr_cache_put((struct mr_mfc *)mr_route->mfc);
	mr_cache_put(mr_route->mfc);
	list_for_each_entry_safe(rve, tmp, &mr_route->evif_list, route_node)
	list_for_each_entry_safe(rve, tmp, &mr_route->evif_list, route_node)
		mlxsw_sp_mr_route_evif_unlink(rve);
		mlxsw_sp_mr_route_evif_unlink(rve);
	kfree(mr_route);
	kfree(mr_route);
}
}


static void mlxsw_sp_mr_route_destroy(struct mlxsw_sp_mr_table *mr_table,
				      struct mlxsw_sp_mr_route *mr_route)
{
	switch (mr_table->proto) {
	case MLXSW_SP_L3_PROTO_IPV4:
		mlxsw_sp_mr_route4_destroy(mr_table, mr_route);
		break;
	case MLXSW_SP_L3_PROTO_IPV6:
		/* fall through */
	default:
		WARN_ON_ONCE(1);
	}
}

static void mlxsw_sp_mr_mfc_offload_set(struct mlxsw_sp_mr_route *mr_route,
static void mlxsw_sp_mr_mfc_offload_set(struct mlxsw_sp_mr_route *mr_route,
					bool offload)
					bool offload)
{
{
@@ -422,18 +408,18 @@ static void __mlxsw_sp_mr_route_del(struct mlxsw_sp_mr_table *mr_table,
	mlxsw_sp_mr_route_destroy(mr_table, mr_route);
	mlxsw_sp_mr_route_destroy(mr_table, mr_route);
}
}


int mlxsw_sp_mr_route4_add(struct mlxsw_sp_mr_table *mr_table,
int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
			   struct mfc_cache *mfc, bool replace)
			  struct mr_mfc *mfc, bool replace)
{
{
	struct mlxsw_sp_mr_route *mr_orig_route = NULL;
	struct mlxsw_sp_mr_route *mr_orig_route = NULL;
	struct mlxsw_sp_mr_route *mr_route;
	struct mlxsw_sp_mr_route *mr_route;
	int err;
	int err;


	if (!mr_table->ops->is_route_valid(mr_table, &mfc->_c))
	if (!mr_table->ops->is_route_valid(mr_table, mfc))
		return -EINVAL;
		return -EINVAL;


	/* Create a new route */
	/* Create a new route */
	mr_route = mlxsw_sp_mr_route4_create(mr_table, mfc);
	mr_route = mlxsw_sp_mr_route_create(mr_table, mfc);
	if (IS_ERR(mr_route))
	if (IS_ERR(mr_route))
		return PTR_ERR(mr_route);
		return PTR_ERR(mr_route);


@@ -478,7 +464,7 @@ int mlxsw_sp_mr_route4_add(struct mlxsw_sp_mr_table *mr_table,
				       &mr_orig_route->ht_node,
				       &mr_orig_route->ht_node,
				       mlxsw_sp_mr_route_ht_params);
				       mlxsw_sp_mr_route_ht_params);
		list_del(&mr_orig_route->node);
		list_del(&mr_orig_route->node);
		mlxsw_sp_mr_route4_destroy(mr_table, mr_orig_route);
		mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
	}
	}


	mlxsw_sp_mr_mfc_offload_update(mr_route);
	mlxsw_sp_mr_mfc_offload_update(mr_route);
@@ -491,17 +477,17 @@ int mlxsw_sp_mr_route4_add(struct mlxsw_sp_mr_table *mr_table,
	list_del(&mr_route->node);
	list_del(&mr_route->node);
err_no_orig_route:
err_no_orig_route:
err_duplicate_route:
err_duplicate_route:
	mlxsw_sp_mr_route4_destroy(mr_table, mr_route);
	mlxsw_sp_mr_route_destroy(mr_table, mr_route);
	return err;
	return err;
}
}


void mlxsw_sp_mr_route4_del(struct mlxsw_sp_mr_table *mr_table,
void mlxsw_sp_mr_route_del(struct mlxsw_sp_mr_table *mr_table,
			    struct mfc_cache *mfc)
			   struct mr_mfc *mfc)
{
{
	struct mlxsw_sp_mr_route *mr_route;
	struct mlxsw_sp_mr_route *mr_route;
	struct mlxsw_sp_mr_route_key key;
	struct mlxsw_sp_mr_route_key key;


	mr_table->ops->key_create(mr_table, &key, &mfc->_c);
	mr_table->ops->key_create(mr_table, &key, mfc);
	mr_route = rhashtable_lookup_fast(&mr_table->route_ht, &key,
	mr_route = rhashtable_lookup_fast(&mr_table->route_ht, &key,
					  mlxsw_sp_mr_route_ht_params);
					  mlxsw_sp_mr_route_ht_params);
	if (mr_route)
	if (mr_route)
+4 −4
Original line number Original line Diff line number Diff line
@@ -109,10 +109,10 @@ struct mlxsw_sp_mr_table;
int mlxsw_sp_mr_init(struct mlxsw_sp *mlxsw_sp,
int mlxsw_sp_mr_init(struct mlxsw_sp *mlxsw_sp,
		     const struct mlxsw_sp_mr_ops *mr_ops);
		     const struct mlxsw_sp_mr_ops *mr_ops);
void mlxsw_sp_mr_fini(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_mr_fini(struct mlxsw_sp *mlxsw_sp);
int mlxsw_sp_mr_route4_add(struct mlxsw_sp_mr_table *mr_table,
int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
			   struct mfc_cache *mfc, bool replace);
			  struct mr_mfc *mfc, bool replace);
void mlxsw_sp_mr_route4_del(struct mlxsw_sp_mr_table *mr_table,
void mlxsw_sp_mr_route_del(struct mlxsw_sp_mr_table *mr_table,
			    struct mfc_cache *mfc);
			   struct mr_mfc *mfc);
int mlxsw_sp_mr_vif_add(struct mlxsw_sp_mr_table *mr_table,
int mlxsw_sp_mr_vif_add(struct mlxsw_sp_mr_table *mr_table,
			struct net_device *dev, vifi_t vif_index,
			struct net_device *dev, vifi_t vif_index,
			unsigned long vif_flags,
			unsigned long vif_flags,
+24 −9
Original line number Original line Diff line number Diff line
@@ -5393,10 +5393,23 @@ static int __mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp,
	return 0;
	return 0;
}
}


static struct mlxsw_sp_mr_table *
mlxsw_sp_router_fibmr_family_to_table(struct mlxsw_sp_vr *vr, int family)
{
	switch (family) {
	case RTNL_FAMILY_IPMR:
		return vr->mr_table[MLXSW_SP_L3_PROTO_IPV4];
	default:
		WARN_ON(1);
		return vr->mr_table[MLXSW_SP_L3_PROTO_IPV4];
	}
}

static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
				     struct mfc_entry_notifier_info *men_info,
				     struct mfc_entry_notifier_info *men_info,
				     bool replace)
				     bool replace)
{
{
	struct mlxsw_sp_mr_table *mrt;
	struct mlxsw_sp_vr *vr;
	struct mlxsw_sp_vr *vr;


	if (mlxsw_sp->router->aborted)
	if (mlxsw_sp->router->aborted)
@@ -5406,14 +5419,14 @@ static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
	if (IS_ERR(vr))
	if (IS_ERR(vr))
		return PTR_ERR(vr);
		return PTR_ERR(vr);


	return mlxsw_sp_mr_route4_add(vr->mr_table[MLXSW_SP_L3_PROTO_IPV4],
	mrt = mlxsw_sp_router_fibmr_family_to_table(vr, men_info->info.family);
				      (struct mfc_cache *) men_info->mfc,
	return mlxsw_sp_mr_route_add(mrt, men_info->mfc, replace);
				      replace);
}
}


static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp,
static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp,
				      struct mfc_entry_notifier_info *men_info)
				      struct mfc_entry_notifier_info *men_info)
{
{
	struct mlxsw_sp_mr_table *mrt;
	struct mlxsw_sp_vr *vr;
	struct mlxsw_sp_vr *vr;


	if (mlxsw_sp->router->aborted)
	if (mlxsw_sp->router->aborted)
@@ -5423,8 +5436,8 @@ static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp,
	if (WARN_ON(!vr))
	if (WARN_ON(!vr))
		return;
		return;


	mlxsw_sp_mr_route4_del(vr->mr_table[MLXSW_SP_L3_PROTO_IPV4],
	mrt = mlxsw_sp_router_fibmr_family_to_table(vr, men_info->info.family);
			       (struct mfc_cache *) men_info->mfc);
	mlxsw_sp_mr_route_del(mrt, men_info->mfc);
	mlxsw_sp_vr_put(mlxsw_sp, vr);
	mlxsw_sp_vr_put(mlxsw_sp, vr);
}
}


@@ -5432,6 +5445,7 @@ static int
mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
			      struct vif_entry_notifier_info *ven_info)
			      struct vif_entry_notifier_info *ven_info)
{
{
	struct mlxsw_sp_mr_table *mrt;
	struct mlxsw_sp_rif *rif;
	struct mlxsw_sp_rif *rif;
	struct mlxsw_sp_vr *vr;
	struct mlxsw_sp_vr *vr;


@@ -5442,9 +5456,9 @@ mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
	if (IS_ERR(vr))
	if (IS_ERR(vr))
		return PTR_ERR(vr);
		return PTR_ERR(vr);


	mrt = mlxsw_sp_router_fibmr_family_to_table(vr, ven_info->info.family);
	rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, ven_info->dev);
	rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, ven_info->dev);
	return mlxsw_sp_mr_vif_add(vr->mr_table[MLXSW_SP_L3_PROTO_IPV4],
	return mlxsw_sp_mr_vif_add(mrt, ven_info->dev,
				   ven_info->dev,
				   ven_info->vif_index,
				   ven_info->vif_index,
				   ven_info->vif_flags, rif);
				   ven_info->vif_flags, rif);
}
}
@@ -5453,6 +5467,7 @@ static void
mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
			      struct vif_entry_notifier_info *ven_info)
			      struct vif_entry_notifier_info *ven_info)
{
{
	struct mlxsw_sp_mr_table *mrt;
	struct mlxsw_sp_vr *vr;
	struct mlxsw_sp_vr *vr;


	if (mlxsw_sp->router->aborted)
	if (mlxsw_sp->router->aborted)
@@ -5462,8 +5477,8 @@ mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
	if (WARN_ON(!vr))
	if (WARN_ON(!vr))
		return;
		return;


	mlxsw_sp_mr_vif_del(vr->mr_table[MLXSW_SP_L3_PROTO_IPV4],
	mrt = mlxsw_sp_router_fibmr_family_to_table(vr, ven_info->info.family);
			    ven_info->vif_index);
	mlxsw_sp_mr_vif_del(mrt, ven_info->vif_index);
	mlxsw_sp_vr_put(mlxsw_sp, vr);
	mlxsw_sp_vr_put(mlxsw_sp, vr);
}
}