mlxsw: Add new FIB entry type for reject routes
authorAmit Cohen <amitc@mellanox.com>
Thu, 7 Nov 2019 16:42:15 +0000 (18:42 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Nov 2019 03:51:40 +0000 (19:51 -0800)
Currently, packets that cannot be routed in hardware (e.g., nexthop
device is not upper of mlxsw), are trapped to the kernel for forwarding.
Such packets are trapped using "RTR_INGRESS0" trap. This trap also traps
packets that hit reject routes (e.g., "unreachable") so that the kernel
will generate the appropriate ICMP error message for them.

Subsequent patch will need to only report to devlink packets that hit a
reject route, which is impossible as long as "RTR_INGRESS0" is
overloaded like that.

Solve this by using "RTR_INGRESS1" trap for packets that hit reject
routes.

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 838c014f6ed1889c088b683ab465c1660e29e2d1..f7b29872db6c0b51f46d2ec3f7b96adc50976c88 100644 (file)
@@ -4515,6 +4515,7 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
        MLXSW_SP_RXL_MARK(MTUERROR, TRAP_TO_CPU, ROUTER_EXP, false),
        MLXSW_SP_RXL_MARK(TTLERROR, TRAP_TO_CPU, ROUTER_EXP, false),
        MLXSW_SP_RXL_L3_MARK(LBERROR, MIRROR_TO_CPU, LBERROR, false),
+       MLXSW_SP_RXL_MARK(RTR_INGRESS1, TRAP_TO_CPU, REMOTE_ROUTE, false),
        MLXSW_SP_RXL_MARK(IP2ME, TRAP_TO_CPU, IP2ME, false),
        MLXSW_SP_RXL_MARK(IPV6_UNSPECIFIED_ADDRESS, TRAP_TO_CPU, ROUTER_EXP,
                          false),
index 0e99b64450ca2f029a7cac0c3ce1b26a27b0df26..39c573b39faf0105985a9fa3ebe03adbedaefcc9 100644 (file)
@@ -367,6 +367,7 @@ enum mlxsw_sp_fib_entry_type {
        MLXSW_SP_FIB_ENTRY_TYPE_LOCAL,
        MLXSW_SP_FIB_ENTRY_TYPE_TRAP,
        MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE,
+       MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE,
 
        /* This is a special case of local delivery, where a packet should be
         * decapsulated on reception. Note that there is no corresponding ENCAP,
@@ -4273,6 +4274,23 @@ static int mlxsw_sp_fib_entry_op_blackhole(struct mlxsw_sp *mlxsw_sp,
        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
 }
 
+static int
+mlxsw_sp_fib_entry_op_unreachable(struct mlxsw_sp *mlxsw_sp,
+                                 struct mlxsw_sp_fib_entry *fib_entry,
+                                 enum mlxsw_reg_ralue_op op)
+{
+       enum mlxsw_reg_ralue_trap_action trap_action;
+       char ralue_pl[MLXSW_REG_RALUE_LEN];
+       u16 trap_id;
+
+       trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
+       trap_id = MLXSW_TRAP_ID_RTR_INGRESS1;
+
+       mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
+       mlxsw_reg_ralue_act_local_pack(ralue_pl, trap_action, trap_id, 0);
+       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
+}
+
 static int
 mlxsw_sp_fib_entry_op_ipip_decap(struct mlxsw_sp *mlxsw_sp,
                                 struct mlxsw_sp_fib_entry *fib_entry,
@@ -4314,6 +4332,9 @@ static int __mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
                return mlxsw_sp_fib_entry_op_trap(mlxsw_sp, fib_entry, op);
        case MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE:
                return mlxsw_sp_fib_entry_op_blackhole(mlxsw_sp, fib_entry, op);
+       case MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE:
+               return mlxsw_sp_fib_entry_op_unreachable(mlxsw_sp, fib_entry,
+                                                        op);
        case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP:
                return mlxsw_sp_fib_entry_op_ipip_decap(mlxsw_sp,
                                                        fib_entry, op);
@@ -4391,7 +4412,7 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
                 * can do so with a lower priority than packets directed
                 * at the host, so use action type local instead of trap.
                 */
-               fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
+               fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE;
                return 0;
        case RTN_UNICAST:
                if (mlxsw_sp_fi_is_gateway(mlxsw_sp, fi))
@@ -5351,7 +5372,7 @@ static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,
        else if (rt->fib6_type == RTN_BLACKHOLE)
                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE;
        else if (rt->fib6_flags & RTF_REJECT)
-               fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
+               fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE;
        else if (mlxsw_sp_rt6_is_gateway(mlxsw_sp, rt))
                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
        else
index a4969982fce18617d159059897c77d3e92af5de4..b7d83c67491fbd5f32d7102f3d2f9280a028e28e 100644 (file)
@@ -49,6 +49,7 @@ enum {
        MLXSW_TRAP_ID_IPV6_DHCP = 0x69,
        MLXSW_TRAP_ID_IPV6_ALL_ROUTERS_LINK = 0x6F,
        MLXSW_TRAP_ID_RTR_INGRESS0 = 0x70,
+       MLXSW_TRAP_ID_RTR_INGRESS1 = 0x71,
        MLXSW_TRAP_ID_IPV6_PIM = 0x79,
        MLXSW_TRAP_ID_IPV6_VRRP = 0x7A,
        MLXSW_TRAP_ID_IPV4_BGP = 0x88,