mlxsw: spectrum_router: Add ability to overwrite adjacency entry only when inactive
authorIdo Schimmel <idosch@nvidia.com>
Wed, 24 Mar 2021 20:14:16 +0000 (22:14 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Mar 2021 23:34:57 +0000 (16:34 -0700)
Allow the driver to instruct the device to only overwrite an adjacency
entry if its activity is cleared. Currently, adjacency entry is always
overwritten, regardless of activity.

This will be used by subsequent patches to prevent replacement of active
nexthop buckets.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h

index af2093f..9ff286b 100644 (file)
@@ -1196,7 +1196,8 @@ static int mlxsw_sp_dpipe_table_adj_counters_update(void *priv, bool enable)
                else
                        mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh);
                mlxsw_sp_nexthop_eth_update(mlxsw_sp,
-                                           adj_index + adj_hash_index, nh);
+                                           adj_index + adj_hash_index, nh,
+                                           true);
        }
        return 0;
 }
index 6ccca39..2389626 100644 (file)
@@ -127,14 +127,17 @@ bool mlxsw_sp_l3addr_is_zero(union mlxsw_sp_l3addr addr)
 
 static int
 mlxsw_sp_ipip_nexthop_update_gre4(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
-                                 struct mlxsw_sp_ipip_entry *ipip_entry)
+                                 struct mlxsw_sp_ipip_entry *ipip_entry,
+                                 bool force)
 {
        u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb);
        __be32 daddr4 = mlxsw_sp_ipip_netdev_daddr4(ipip_entry->ol_dev);
        char ratr_pl[MLXSW_REG_RATR_LEN];
+       enum mlxsw_reg_ratr_op op;
 
-       mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY,
-                           true, MLXSW_REG_RATR_TYPE_IPIP,
+       op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :
+                    MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;
+       mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_IPIP,
                            adj_index, rif_index);
        mlxsw_reg_ratr_ipip4_entry_pack(ratr_pl, be32_to_cpu(daddr4));
 
index 87bef98..af7dd19 100644 (file)
@@ -40,7 +40,8 @@ struct mlxsw_sp_ipip_ops {
        enum mlxsw_sp_l3proto ul_proto; /* Underlay. */
 
        int (*nexthop_update)(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
-                             struct mlxsw_sp_ipip_entry *ipip_entry);
+                             struct mlxsw_sp_ipip_entry *ipip_entry,
+                             bool force);
 
        bool (*can_offload)(const struct mlxsw_sp *mlxsw_sp,
                            const struct net_device *ol_dev);
index db859c2..63c2c7a 100644 (file)
@@ -3419,16 +3419,19 @@ err_mass_update_vr:
 
 static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp,
                                         u32 adj_index,
-                                        struct mlxsw_sp_nexthop *nh)
+                                        struct mlxsw_sp_nexthop *nh,
+                                        bool force)
 {
        struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
        char ratr_pl[MLXSW_REG_RATR_LEN];
+       enum mlxsw_reg_ratr_op op;
        u16 rif_index;
 
        rif_index = nh->rif ? nh->rif->rif_index :
                              mlxsw_sp->router->lb_rif_index;
-       mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY,
-                           true, MLXSW_REG_RATR_TYPE_ETHERNET,
+       op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :
+                    MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;
+       mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_ETHERNET,
                            adj_index, rif_index);
        switch (nh->action) {
        case MLXSW_SP_NEXTHOP_ACTION_FORWARD:
@@ -3456,7 +3459,7 @@ static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp,
 }
 
 int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
-                               struct mlxsw_sp_nexthop *nh)
+                               struct mlxsw_sp_nexthop *nh, bool force)
 {
        int i;
 
@@ -3464,7 +3467,7 @@ int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
                int err;
 
                err = __mlxsw_sp_nexthop_eth_update(mlxsw_sp, adj_index + i,
-                                                   nh);
+                                                   nh, force);
                if (err)
                        return err;
        }
@@ -3474,17 +3477,19 @@ int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
 
 static int __mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
                                          u32 adj_index,
-                                         struct mlxsw_sp_nexthop *nh)
+                                         struct mlxsw_sp_nexthop *nh,
+                                         bool force)
 {
        const struct mlxsw_sp_ipip_ops *ipip_ops;
 
        ipip_ops = mlxsw_sp->router->ipip_ops_arr[nh->ipip_entry->ipipt];
-       return ipip_ops->nexthop_update(mlxsw_sp, adj_index, nh->ipip_entry);
+       return ipip_ops->nexthop_update(mlxsw_sp, adj_index, nh->ipip_entry,
+                                       force);
 }
 
 static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
                                        u32 adj_index,
-                                       struct mlxsw_sp_nexthop *nh)
+                                       struct mlxsw_sp_nexthop *nh, bool force)
 {
        int i;
 
@@ -3492,7 +3497,7 @@ static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
                int err;
 
                err = __mlxsw_sp_nexthop_ipip_update(mlxsw_sp, adj_index + i,
-                                                    nh);
+                                                    nh, force);
                if (err)
                        return err;
        }
@@ -3501,7 +3506,7 @@ static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
-                                  struct mlxsw_sp_nexthop *nh)
+                                  struct mlxsw_sp_nexthop *nh, bool force)
 {
        /* When action is discard or trap, the nexthop must be
         * programmed as an Ethernet nexthop.
@@ -3509,9 +3514,11 @@ static int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
        if (nh->type == MLXSW_SP_NEXTHOP_TYPE_ETH ||
            nh->action == MLXSW_SP_NEXTHOP_ACTION_DISCARD ||
            nh->action == MLXSW_SP_NEXTHOP_ACTION_TRAP)
-               return mlxsw_sp_nexthop_eth_update(mlxsw_sp, adj_index, nh);
+               return mlxsw_sp_nexthop_eth_update(mlxsw_sp, adj_index, nh,
+                                                  force);
        else
-               return mlxsw_sp_nexthop_ipip_update(mlxsw_sp, adj_index, nh);
+               return mlxsw_sp_nexthop_ipip_update(mlxsw_sp, adj_index, nh,
+                                                   force);
 }
 
 static int
@@ -3534,7 +3541,8 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
                if (nh->update || reallocate) {
                        int err = 0;
 
-                       err = mlxsw_sp_nexthop_update(mlxsw_sp, adj_index, nh);
+                       err = mlxsw_sp_nexthop_update(mlxsw_sp, adj_index, nh,
+                                                     true);
                        if (err)
                                return err;
                        nh->update = 0;
index 01fd9a3..3bb2a06 100644 (file)
@@ -209,7 +209,7 @@ bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh);
 int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
                                 struct mlxsw_sp_nexthop *nh, u64 *p_counter);
 int mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
-                               struct mlxsw_sp_nexthop *nh);
+                               struct mlxsw_sp_nexthop *nh, bool force);
 void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp,
                                    struct mlxsw_sp_nexthop *nh);
 void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,