mlxsw: spectrum_router: Add / delete multiple IPv6 nexthops
Currently, the functions that take care of populating IPv6 nexthop groups only add / delete a single nexthop. Prepare them to handle multiple routes in one notification by passing an array of routes and adding / deleting all of them. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
921bc539cb
commit
d21afd3029
@ -5278,17 +5278,21 @@ err_nexthop6_group_get:
|
|||||||
static int
|
static int
|
||||||
mlxsw_sp_fib6_entry_nexthop_add(struct mlxsw_sp *mlxsw_sp,
|
mlxsw_sp_fib6_entry_nexthop_add(struct mlxsw_sp *mlxsw_sp,
|
||||||
struct mlxsw_sp_fib6_entry *fib6_entry,
|
struct mlxsw_sp_fib6_entry *fib6_entry,
|
||||||
struct fib6_info *rt)
|
struct fib6_info **rt_arr, unsigned int nrt6)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
|
struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
|
||||||
int err;
|
int err, i;
|
||||||
|
|
||||||
mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt);
|
for (i = 0; i < nrt6; i++) {
|
||||||
if (IS_ERR(mlxsw_sp_rt6))
|
mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt_arr[i]);
|
||||||
return PTR_ERR(mlxsw_sp_rt6);
|
if (IS_ERR(mlxsw_sp_rt6)) {
|
||||||
|
err = PTR_ERR(mlxsw_sp_rt6);
|
||||||
|
goto err_rt6_create;
|
||||||
|
}
|
||||||
|
|
||||||
list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
|
list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
|
||||||
fib6_entry->nrt6++;
|
fib6_entry->nrt6++;
|
||||||
|
}
|
||||||
|
|
||||||
err = mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry);
|
err = mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry);
|
||||||
if (err)
|
if (err)
|
||||||
@ -5297,27 +5301,38 @@ mlxsw_sp_fib6_entry_nexthop_add(struct mlxsw_sp *mlxsw_sp,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_nexthop6_group_update:
|
err_nexthop6_group_update:
|
||||||
fib6_entry->nrt6--;
|
i = nrt6;
|
||||||
list_del(&mlxsw_sp_rt6->list);
|
err_rt6_create:
|
||||||
mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
|
for (i--; i >= 0; i--) {
|
||||||
|
fib6_entry->nrt6--;
|
||||||
|
mlxsw_sp_rt6 = list_last_entry(&fib6_entry->rt6_list,
|
||||||
|
struct mlxsw_sp_rt6, list);
|
||||||
|
list_del(&mlxsw_sp_rt6->list);
|
||||||
|
mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp,
|
mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp,
|
||||||
struct mlxsw_sp_fib6_entry *fib6_entry,
|
struct mlxsw_sp_fib6_entry *fib6_entry,
|
||||||
struct fib6_info *rt)
|
struct fib6_info **rt_arr, unsigned int nrt6)
|
||||||
{
|
{
|
||||||
struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
|
struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
|
||||||
|
int i;
|
||||||
|
|
||||||
mlxsw_sp_rt6 = mlxsw_sp_fib6_entry_rt_find(fib6_entry, rt);
|
for (i = 0; i < nrt6; i++) {
|
||||||
if (WARN_ON(!mlxsw_sp_rt6))
|
mlxsw_sp_rt6 = mlxsw_sp_fib6_entry_rt_find(fib6_entry,
|
||||||
return;
|
rt_arr[i]);
|
||||||
|
if (WARN_ON_ONCE(!mlxsw_sp_rt6))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fib6_entry->nrt6--;
|
||||||
|
list_del(&mlxsw_sp_rt6->list);
|
||||||
|
mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
|
||||||
|
}
|
||||||
|
|
||||||
fib6_entry->nrt6--;
|
|
||||||
list_del(&mlxsw_sp_rt6->list);
|
|
||||||
mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry);
|
mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry);
|
||||||
mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,
|
static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,
|
||||||
@ -5586,7 +5601,8 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
|
|||||||
*/
|
*/
|
||||||
fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, replace);
|
fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, replace);
|
||||||
if (fib6_entry) {
|
if (fib6_entry) {
|
||||||
err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt);
|
err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry,
|
||||||
|
rt_arr, nrt6);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_fib6_entry_nexthop_add;
|
goto err_fib6_entry_nexthop_add;
|
||||||
return 0;
|
return 0;
|
||||||
@ -5632,11 +5648,12 @@ static void mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp,
|
|||||||
if (WARN_ON(!fib6_entry))
|
if (WARN_ON(!fib6_entry))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If route is part of a multipath entry, but not the last one
|
/* If not all the nexthops are deleted, then only reduce the nexthop
|
||||||
* removed, then only reduce its nexthop group.
|
* group.
|
||||||
*/
|
*/
|
||||||
if (!list_is_singular(&fib6_entry->rt6_list)) {
|
if (nrt6 != fib6_entry->nrt6) {
|
||||||
mlxsw_sp_fib6_entry_nexthop_del(mlxsw_sp, fib6_entry, rt);
|
mlxsw_sp_fib6_entry_nexthop_del(mlxsw_sp, fib6_entry, rt_arr,
|
||||||
|
nrt6);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user