Skip to content

Commit

Permalink
mlxsw: spectrum_router: Replay neighbours when RIF is made
Browse files Browse the repository at this point in the history
As neighbours are created, mlxsw is involved through the netevent
notifications. When at the time there is no RIF for a given neighbour, the
notification is not acted upon. When the RIF is later created, these
outstanding neighbours are left unoffloaded and cause traffic to go through
the SW datapath.

In order to fix this issue, as a RIF is created, walk the ARP and ND tables
and find neighbours for the netdevice that represents the RIF. Then
schedule neighbour work for them, allowing them to be offloaded.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Petr Machata authored and David S. Miller committed Jul 21, 2023
1 parent 49c3a61 commit 8fdb09a
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -2983,6 +2983,52 @@ static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
}
}

struct mlxsw_sp_neigh_rif_made_sync {
struct mlxsw_sp *mlxsw_sp;
struct mlxsw_sp_rif *rif;
int err;
};

static void mlxsw_sp_neigh_rif_made_sync_each(struct neighbour *n, void *data)
{
struct mlxsw_sp_neigh_rif_made_sync *rms = data;
int rc;

if (rms->err)
return;
if (n->dev != mlxsw_sp_rif_dev(rms->rif))
return;
rc = mlxsw_sp_router_schedule_neigh_work(rms->mlxsw_sp->router, n);
if (rc != NOTIFY_DONE)
rms->err = -ENOMEM;
}

static int mlxsw_sp_neigh_rif_made_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{
struct mlxsw_sp_neigh_rif_made_sync rms = {
.mlxsw_sp = mlxsw_sp,
.rif = rif,
};

neigh_for_each(&arp_tbl, mlxsw_sp_neigh_rif_made_sync_each, &rms);
if (rms.err)
goto err_arp;

#if IS_ENABLED(CONFIG_IPV6)
neigh_for_each(&nd_tbl, mlxsw_sp_neigh_rif_made_sync_each, &rms);
#endif
if (rms.err)
goto err_nd;

return 0;

err_nd:
err_arp:
mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif);
return rms.err;
}

enum mlxsw_sp_nexthop_type {
MLXSW_SP_NEXTHOP_TYPE_ETH,
MLXSW_SP_NEXTHOP_TYPE_IPIP,
Expand Down Expand Up @@ -7937,7 +7983,21 @@ static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif)
static int mlxsw_sp_router_rif_made_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif)
{
return mlxsw_sp_nexthop_rif_made_sync(mlxsw_sp, rif);
int err;

err = mlxsw_sp_neigh_rif_made_sync(mlxsw_sp, rif);
if (err)
return err;

err = mlxsw_sp_nexthop_rif_made_sync(mlxsw_sp, rif);
if (err)
goto err_nexthop;

return 0;

err_nexthop:
mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif);
return err;
}

static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
Expand Down

0 comments on commit 8fdb09a

Please sign in to comment.