]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
mlxsw: Add specific trap for packets routed via invalid nexthops
authorAmit Cohen <amitc@mellanox.com>
Thu, 7 Nov 2019 16:42:16 +0000 (18:42 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Nov 2019 03:51:40 +0000 (19:51 -0800)
Currently, mlxsw does not differentiate between these two cases of
routes with invalid nexthops:

1. Nexthops whose nexthop device is a mlxsw upper (has a RIF), but whose
neighbour could not be resolved

2. Nexthops whose nexthop device is not a mlxsw upper (e.g., management
interface)

Up until now this did not matter and mlxsw trapped packets for both
cases using the same trap ID. However, packets that should have been
routed in hardware (case 1), but incurred a problem are considered
exceptions and should be reported to the user. The two cases should
therefore be split between two different trap IDs.

Allocate a new adjacency entry during initialization and upon the
insertion of the first route with an invalid mlxsw nexthop, program this
entry to discard packets. Packets hitting this entry will be reported
using new trap ID - "DISCARD_ROUTER3".

In the future, the entry could be written during initialization, but
currently firmware requires a valid RIF, which is not available at this
stage.

Signed-off-by: Amit Cohen <amitc@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/trap.h

index f7b29872db6c0b51f46d2ec3f7b96adc50976c88..d9bcb3b8d032cce3b0c0b60e2fef1359d624b6b0 100644 (file)
@@ -4528,6 +4528,8 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
        MLXSW_SP_RXL_MARK(IPV6_OSPF, TRAP_TO_CPU, OSPF, false),
        MLXSW_SP_RXL_MARK(IPV6_DHCP, TRAP_TO_CPU, DHCP, false),
        MLXSW_SP_RXL_MARK(RTR_INGRESS0, TRAP_TO_CPU, REMOTE_ROUTE, false),
+       MLXSW_SP_RXL_MARK(DISCARD_ROUTER3, TRAP_EXCEPTION_TO_CPU, REMOTE_ROUTE,
+                         false),
        MLXSW_SP_RXL_MARK(IPV4_BGP, TRAP_TO_CPU, BGP, false),
        MLXSW_SP_RXL_MARK(IPV6_BGP, TRAP_TO_CPU, BGP, false),
        MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_SOLICITATION, TRAP_TO_CPU, IPV6_ND,
index 39c573b39faf0105985a9fa3ebe03adbedaefcc9..1aa436054490041c8e65eb5df9b4d53343b85006 100644 (file)
@@ -77,6 +77,7 @@ struct mlxsw_sp_router {
        struct notifier_block inet6addr_nb;
        const struct mlxsw_sp_rif_ops **rif_ops_arr;
        const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
+       u32 adj_discard_index;
 };
 
 struct mlxsw_sp_rif {
@@ -4197,15 +4198,31 @@ mlxsw_sp_fib_entry_ralue_pack(char *ralue_pl,
        }
 }
 
+static int mlxsw_sp_adj_discard_write(struct mlxsw_sp *mlxsw_sp, u16 rif_index)
+{
+       u32 adj_discard_index = mlxsw_sp->router->adj_discard_index;
+       enum mlxsw_reg_ratr_trap_action trap_action;
+       char ratr_pl[MLXSW_REG_RATR_LEN];
+
+       trap_action = MLXSW_REG_RATR_TRAP_ACTION_DISCARD_ERRORS;
+       mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, true,
+                           MLXSW_REG_RATR_TYPE_ETHERNET, adj_discard_index,
+                           rif_index);
+       mlxsw_reg_ratr_trap_action_set(ratr_pl, trap_action);
+       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
+}
+
 static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
                                        struct mlxsw_sp_fib_entry *fib_entry,
                                        enum mlxsw_reg_ralue_op op)
 {
+       struct mlxsw_sp_nexthop_group *nh_group = fib_entry->nh_group;
        char ralue_pl[MLXSW_REG_RALUE_LEN];
        enum mlxsw_reg_ralue_trap_action trap_action;
        u16 trap_id = 0;
        u32 adjacency_index = 0;
        u16 ecmp_size = 0;
+       int err;
 
        /* In case the nexthop group adjacency index is valid, use it
         * with provided ECMP size. Otherwise, setup trap and pass
@@ -4215,6 +4232,15 @@ static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
                adjacency_index = fib_entry->nh_group->adj_index;
                ecmp_size = fib_entry->nh_group->ecmp_size;
+       } else if (!nh_group->adj_index_valid && nh_group->count &&
+                  nh_group->nh_rif) {
+               err = mlxsw_sp_adj_discard_write(mlxsw_sp,
+                                                nh_group->nh_rif->rif_index);
+               if (err)
+                       return err;
+               trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
+               adjacency_index = mlxsw_sp->router->adj_discard_index;
+               ecmp_size = 1;
        } else {
                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
                trap_id = MLXSW_TRAP_ID_RTR_INGRESS0;
@@ -8144,6 +8170,11 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
        if (err)
                goto err_neigh_init;
 
+       err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
+                                 &router->adj_discard_index);
+       if (err)
+               goto err_adj_discard_index_alloc;
+
        mlxsw_sp->router->netevent_nb.notifier_call =
                mlxsw_sp_router_netevent_event;
        err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb);
@@ -8172,6 +8203,9 @@ err_dscp_init:
 err_mp_hash_init:
        unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
 err_register_netevent_notifier:
+       mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
+                          router->adj_discard_index);
+err_adj_discard_index_alloc:
        mlxsw_sp_neigh_fini(mlxsw_sp);
 err_neigh_init:
        mlxsw_sp_vrs_fini(mlxsw_sp);
@@ -8203,6 +8237,8 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
        unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp),
                                &mlxsw_sp->router->fib_nb);
        unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
+       mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
+                          mlxsw_sp->router->adj_discard_index);
        mlxsw_sp_neigh_fini(mlxsw_sp);
        mlxsw_sp_vrs_fini(mlxsw_sp);
        mlxsw_sp_mr_fini(mlxsw_sp);
index b7d83c67491fbd5f32d7102f3d2f9280a028e28e..b84b7f07dce20819be3c64f58fa1dd917b9f2f6b 100644 (file)
@@ -68,6 +68,7 @@ enum {
        MLXSW_TRAP_ID_ROUTER_ALERT_IPV4 = 0xD6,
        MLXSW_TRAP_ID_ROUTER_ALERT_IPV6 = 0xD7,
        MLXSW_TRAP_ID_DISCARD_ROUTER2 = 0x130,
+       MLXSW_TRAP_ID_DISCARD_ROUTER3 = 0x131,
        MLXSW_TRAP_ID_DISCARD_ING_PACKET_SMAC_MC = 0x140,
        MLXSW_TRAP_ID_DISCARD_ING_SWITCH_VTAG_ALLOW = 0x148,
        MLXSW_TRAP_ID_DISCARD_ING_SWITCH_VLAN = 0x149,