|
|
@@ -2052,6 +2052,8 @@ struct mlxsw_sp_nexthop {
|
|
|
struct mlxsw_sp_neigh_entry *neigh_entry;
|
|
|
struct mlxsw_sp_ipip_entry *ipip_entry;
|
|
|
};
|
|
|
+ unsigned int counter_index;
|
|
|
+ bool counter_valid;
|
|
|
};
|
|
|
|
|
|
struct mlxsw_sp_nexthop_group {
|
|
|
@@ -2068,6 +2070,41 @@ struct mlxsw_sp_nexthop_group {
|
|
|
#define nh_rif nexthops[0].rif
|
|
|
};
|
|
|
|
|
|
+static void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp,
|
|
|
+ struct mlxsw_sp_nexthop *nh)
|
|
|
+{
|
|
|
+ struct devlink *devlink;
|
|
|
+
|
|
|
+ devlink = priv_to_devlink(mlxsw_sp->core);
|
|
|
+ if (!devlink_dpipe_table_counter_enabled(devlink,
|
|
|
+ MLXSW_SP_DPIPE_TABLE_NAME_ADJ))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (mlxsw_sp_flow_counter_alloc(mlxsw_sp, &nh->counter_index))
|
|
|
+ return;
|
|
|
+
|
|
|
+ nh->counter_valid = true;
|
|
|
+}
|
|
|
+
|
|
|
+static void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
|
|
|
+ struct mlxsw_sp_nexthop *nh)
|
|
|
+{
|
|
|
+ if (!nh->counter_valid)
|
|
|
+ return;
|
|
|
+ mlxsw_sp_flow_counter_free(mlxsw_sp, nh->counter_index);
|
|
|
+ nh->counter_valid = false;
|
|
|
+}
|
|
|
+
|
|
|
+int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
|
|
|
+ struct mlxsw_sp_nexthop *nh, u64 *p_counter)
|
|
|
+{
|
|
|
+ if (!nh->counter_valid)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return mlxsw_sp_flow_counter_get(mlxsw_sp, nh->counter_index,
|
|
|
+ p_counter, NULL);
|
|
|
+}
|
|
|
+
|
|
|
struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
|
|
|
struct mlxsw_sp_nexthop *nh)
|
|
|
{
|
|
|
@@ -2396,8 +2433,8 @@ static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
|
|
|
- struct mlxsw_sp_nexthop *nh)
|
|
|
+static int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
|
|
|
+ struct mlxsw_sp_nexthop *nh)
|
|
|
{
|
|
|
struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
|
|
|
char ratr_pl[MLXSW_REG_RATR_LEN];
|
|
|
@@ -2406,6 +2443,11 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
|
|
|
true, MLXSW_REG_RATR_TYPE_ETHERNET,
|
|
|
adj_index, neigh_entry->rif);
|
|
|
mlxsw_reg_ratr_eth_entry_pack(ratr_pl, neigh_entry->ha);
|
|
|
+ if (nh->counter_valid)
|
|
|
+ mlxsw_reg_ratr_counter_pack(ratr_pl, nh->counter_index, true);
|
|
|
+ else
|
|
|
+ mlxsw_reg_ratr_counter_pack(ratr_pl, 0, false);
|
|
|
+
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
|
|
|
}
|
|
|
|
|
|
@@ -2440,7 +2482,7 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
|
|
|
if (nh->update || reallocate) {
|
|
|
switch (nh->type) {
|
|
|
case MLXSW_SP_NEXTHOP_TYPE_ETH:
|
|
|
- err = mlxsw_sp_nexthop_mac_update
|
|
|
+ err = mlxsw_sp_nexthop_update
|
|
|
(mlxsw_sp, adj_index, nh);
|
|
|
break;
|
|
|
case MLXSW_SP_NEXTHOP_TYPE_IPIP:
|
|
|
@@ -2857,6 +2899,7 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
+ mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);
|
|
|
list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list);
|
|
|
|
|
|
if (!dev)
|
|
|
@@ -2883,6 +2926,7 @@ static void mlxsw_sp_nexthop4_fini(struct mlxsw_sp *mlxsw_sp,
|
|
|
{
|
|
|
mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh);
|
|
|
list_del(&nh->router_list_node);
|
|
|
+ mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh);
|
|
|
mlxsw_sp_nexthop_remove(mlxsw_sp, nh);
|
|
|
}
|
|
|
|
|
|
@@ -4120,6 +4164,7 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
|
nh->nh_grp = nh_grp;
|
|
|
memcpy(&nh->gw_addr, &rt->rt6i_gateway, sizeof(nh->gw_addr));
|
|
|
+ mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);
|
|
|
|
|
|
list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list);
|
|
|
|
|
|
@@ -4135,6 +4180,7 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,
|
|
|
{
|
|
|
mlxsw_sp_nexthop6_type_fini(mlxsw_sp, nh);
|
|
|
list_del(&nh->router_list_node);
|
|
|
+ mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh);
|
|
|
}
|
|
|
|
|
|
static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
|