Skip to content

Commit 8c5a5b9

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum_router: Separate nexthop offload indication from route
The driver currently uses the 'RTNH_F_OFFLOAD' flag for both routes and nexthops, which is cumbersome and unnecessary now that we have separate flag for the route itself. Separate the offload indication for nexthops from routes and call it whenever the offload state within the nexthop group changes. Note that IPv6 (unlike IPv4) does not share the same nexthop group between different routes, whereas mlxsw does. Therefore, whenever the offload indication within an IPv6 nexthop group changes, all the linked routes need to be updated. Signed-off-by: Ido Schimmel <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bb3c4ab commit 8c5a5b9

File tree

1 file changed

+75
-17
lines changed

1 file changed

+75
-17
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3235,20 +3235,6 @@ mlxsw_sp_nexthop_fib_entries_update(struct mlxsw_sp *mlxsw_sp,
32353235
return 0;
32363236
}
32373237

3238-
static void
3239-
mlxsw_sp_fib_entry_offload_refresh(struct mlxsw_sp_fib_entry *fib_entry,
3240-
enum mlxsw_reg_ralue_op op, int err);
3241-
3242-
static void
3243-
mlxsw_sp_nexthop_fib_entries_refresh(struct mlxsw_sp_nexthop_group *nh_grp)
3244-
{
3245-
enum mlxsw_reg_ralue_op op = MLXSW_REG_RALUE_OP_WRITE_WRITE;
3246-
struct mlxsw_sp_fib_entry *fib_entry;
3247-
3248-
list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node)
3249-
mlxsw_sp_fib_entry_offload_refresh(fib_entry, op, 0);
3250-
}
3251-
32523238
static void mlxsw_sp_adj_grp_size_round_up(u16 *p_adj_grp_size)
32533239
{
32543240
/* Valid sizes for an adjacency group are:
@@ -3352,6 +3338,73 @@ mlxsw_sp_nexthop_group_rebalance(struct mlxsw_sp_nexthop_group *nh_grp)
33523338
}
33533339
}
33543340

3341+
static struct mlxsw_sp_nexthop *
3342+
mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
3343+
const struct mlxsw_sp_rt6 *mlxsw_sp_rt6);
3344+
3345+
static void
3346+
mlxsw_sp_nexthop4_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
3347+
struct mlxsw_sp_nexthop_group *nh_grp)
3348+
{
3349+
int i;
3350+
3351+
for (i = 0; i < nh_grp->count; i++) {
3352+
struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i];
3353+
3354+
if (nh->offloaded)
3355+
nh->key.fib_nh->fib_nh_flags |= RTNH_F_OFFLOAD;
3356+
else
3357+
nh->key.fib_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
3358+
}
3359+
}
3360+
3361+
static void
3362+
__mlxsw_sp_nexthop6_group_offload_refresh(struct mlxsw_sp_nexthop_group *nh_grp,
3363+
struct mlxsw_sp_fib6_entry *fib6_entry)
3364+
{
3365+
struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
3366+
3367+
list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
3368+
struct fib6_nh *fib6_nh = mlxsw_sp_rt6->rt->fib6_nh;
3369+
struct mlxsw_sp_nexthop *nh;
3370+
3371+
nh = mlxsw_sp_rt6_nexthop(nh_grp, mlxsw_sp_rt6);
3372+
if (nh && nh->offloaded)
3373+
fib6_nh->fib_nh_flags |= RTNH_F_OFFLOAD;
3374+
else
3375+
fib6_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
3376+
}
3377+
}
3378+
3379+
static void
3380+
mlxsw_sp_nexthop6_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
3381+
struct mlxsw_sp_nexthop_group *nh_grp)
3382+
{
3383+
struct mlxsw_sp_fib6_entry *fib6_entry;
3384+
3385+
/* Unfortunately, in IPv6 the route and the nexthop are described by
3386+
* the same struct, so we need to iterate over all the routes using the
3387+
* nexthop group and set / clear the offload indication for them.
3388+
*/
3389+
list_for_each_entry(fib6_entry, &nh_grp->fib_list,
3390+
common.nexthop_group_node)
3391+
__mlxsw_sp_nexthop6_group_offload_refresh(nh_grp, fib6_entry);
3392+
}
3393+
3394+
static void
3395+
mlxsw_sp_nexthop_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
3396+
struct mlxsw_sp_nexthop_group *nh_grp)
3397+
{
3398+
switch (mlxsw_sp_nexthop_group_type(nh_grp)) {
3399+
case AF_INET:
3400+
mlxsw_sp_nexthop4_group_offload_refresh(mlxsw_sp, nh_grp);
3401+
break;
3402+
case AF_INET6:
3403+
mlxsw_sp_nexthop6_group_offload_refresh(mlxsw_sp, nh_grp);
3404+
break;
3405+
}
3406+
}
3407+
33553408
static void
33563409
mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
33573410
struct mlxsw_sp_nexthop_group *nh_grp)
@@ -3425,6 +3478,8 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
34253478
goto set_trap;
34263479
}
34273480

3481+
mlxsw_sp_nexthop_group_offload_refresh(mlxsw_sp, nh_grp);
3482+
34283483
if (!old_adj_index_valid) {
34293484
/* The trap was set for fib entries, so we have to call
34303485
* fib entry update to unset it and use adjacency index.
@@ -3446,9 +3501,6 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
34463501
goto set_trap;
34473502
}
34483503

3449-
/* Offload state within the group changed, so update the flags. */
3450-
mlxsw_sp_nexthop_fib_entries_refresh(nh_grp);
3451-
34523504
return;
34533505

34543506
set_trap:
@@ -3461,6 +3513,7 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
34613513
err = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp);
34623514
if (err)
34633515
dev_warn(mlxsw_sp->bus_info->dev, "Failed to set traps for fib entries.\n");
3516+
mlxsw_sp_nexthop_group_offload_refresh(mlxsw_sp, nh_grp);
34643517
if (old_adj_index_valid)
34653518
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
34663519
nh_grp->ecmp_size, nh_grp->adj_index);
@@ -5113,6 +5166,11 @@ static int mlxsw_sp_nexthop6_group_get(struct mlxsw_sp *mlxsw_sp,
51135166
&nh_grp->fib_list);
51145167
fib6_entry->common.nh_group = nh_grp;
51155168

5169+
/* The route and the nexthop are described by the same struct, so we
5170+
* need to the update the nexthop offload indication for the new route.
5171+
*/
5172+
__mlxsw_sp_nexthop6_group_offload_refresh(nh_grp, fib6_entry);
5173+
51165174
return 0;
51175175
}
51185176

0 commit comments

Comments
 (0)