mlxsw: spectrum_router: Offload ethernet nexthops when RIF is made
authorPetr Machata <petrm@nvidia.com>
Wed, 19 Jul 2023 11:01:27 +0000 (13:01 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 21 Jul 2023 07:54:05 +0000 (08:54 +0100)
As RIF is created, refresh each netxhop group tracked at the CRIF for which
the RIF was created.

Note that nothing needs to be done for IPIP nexthops. The RIF for these is
either available from the get-go, or will never be available, so no after
the fact offloading needs to be done.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

index ae2d5e760f1b531f40214ab33f7b2c63a8264481..fe1855cc2c76ab59892e02e62298cb361ecaf624 100644 (file)
@@ -4404,6 +4404,19 @@ err_neigh_init:
        return err;
 }
 
+static int mlxsw_sp_nexthop_type_rif_made(struct mlxsw_sp *mlxsw_sp,
+                                         struct mlxsw_sp_nexthop *nh)
+{
+       switch (nh->type) {
+       case MLXSW_SP_NEXTHOP_TYPE_ETH:
+               return mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
+       case MLXSW_SP_NEXTHOP_TYPE_IPIP:
+               break;
+       }
+
+       return 0;
+}
+
 static void mlxsw_sp_nexthop_type_rif_gone(struct mlxsw_sp *mlxsw_sp,
                                           struct mlxsw_sp_nexthop *nh)
 {
@@ -4532,6 +4545,35 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
        }
 }
 
+static int mlxsw_sp_nexthop_rif_made_sync(struct mlxsw_sp *mlxsw_sp,
+                                         struct mlxsw_sp_rif *rif)
+{
+       struct mlxsw_sp_nexthop *nh, *tmp;
+       unsigned int n = 0;
+       int err;
+
+       list_for_each_entry_safe(nh, tmp, &rif->crif->nexthop_list,
+                                crif_list_node) {
+               err = mlxsw_sp_nexthop_type_rif_made(mlxsw_sp, nh);
+               if (err)
+                       goto err_nexthop_type_rif;
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+               n++;
+       }
+
+       return 0;
+
+err_nexthop_type_rif:
+       list_for_each_entry_safe(nh, tmp, &rif->crif->nexthop_list,
+                                crif_list_node) {
+               if (!n--)
+                       break;
+               mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh);
+               mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
+       }
+       return err;
+}
+
 static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
                                           struct mlxsw_sp_rif *rif)
 {
@@ -7892,6 +7934,12 @@ static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif)
        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
 }
 
+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);
+}
+
 static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
                                          struct mlxsw_sp_rif *rif)
 {
@@ -8329,6 +8377,10 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
                        goto err_mr_rif_add;
        }
 
+       err = mlxsw_sp_router_rif_made_sync(mlxsw_sp, rif);
+       if (err)
+               goto err_rif_made_sync;
+
        if (netdev_offload_xstats_enabled(params->dev,
                                          NETDEV_OFFLOAD_XSTATS_TYPE_L3)) {
                err = mlxsw_sp_router_port_l3_stats_enable(rif);
@@ -8343,6 +8395,8 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
        return rif;
 
 err_stats_enable:
+       mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif);
+err_rif_made_sync:
 err_mr_rif_add:
        for (i--; i >= 0; i--)
                mlxsw_sp_mr_rif_del(vr->mr_table[i], rif);