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

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
...@@ -323,8 +323,8 @@ static void mlxsw_sp_mr_route_erase(struct mlxsw_sp_mr_table *mr_table, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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)
......
...@@ -109,10 +109,10 @@ struct mlxsw_sp_mr_table; ...@@ -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,
......
...@@ -5393,10 +5393,23 @@ static int __mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment