mlxsw: spectrum_router: Make abort mechanism VR-aware
authorIdo Schimmel <idosch@mellanox.com>
Fri, 10 Mar 2017 07:53:43 +0000 (08:53 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 10 Mar 2017 17:36:06 +0000 (09:36 -0800)
When the abort mechanism is invoked it binds the first virtual router
(VR) to an LPM tree and inserts a default route to direct packets to the
CPU.

With VRFs, we can have router interfaces (RIFs) bound to multiple VRs,
so we need to make sure packets are trapped from all VRs and not just
the first one.

Upon abort invocation, bind all active VRs to the same LPM tree and
insert a default route in each.

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

index 22a4d689ea13862b1fd4e034fad01b2ba619f974..80345a1ddf173feff51822825e29ef79c376e74d 100644 (file)
@@ -2392,9 +2392,7 @@ static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp)
 {
        char ralta_pl[MLXSW_REG_RALTA_LEN];
        char ralst_pl[MLXSW_REG_RALST_LEN];
-       char raltb_pl[MLXSW_REG_RALTB_LEN];
-       char ralue_pl[MLXSW_REG_RALUE_LEN];
-       int err;
+       int i, err;
 
        mlxsw_reg_ralta_pack(ralta_pl, true, MLXSW_REG_RALXX_PROTOCOL_IPV4,
                             MLXSW_SP_LPM_TREE_MIN);
@@ -2407,16 +2405,33 @@ static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp)
        if (err)
                return err;
 
-       mlxsw_reg_raltb_pack(raltb_pl, 0, MLXSW_REG_RALXX_PROTOCOL_IPV4,
-                            MLXSW_SP_LPM_TREE_MIN);
-       err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb), raltb_pl);
-       if (err)
-               return err;
+       for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
+               struct mlxsw_sp_vr *vr = &mlxsw_sp->router.vrs[i];
+               char raltb_pl[MLXSW_REG_RALTB_LEN];
+               char ralue_pl[MLXSW_REG_RALUE_LEN];
 
-       mlxsw_reg_ralue_pack4(ralue_pl, MLXSW_SP_L3_PROTO_IPV4,
-                             MLXSW_REG_RALUE_OP_WRITE_WRITE, 0, 0, 0);
-       mlxsw_reg_ralue_act_ip2me_pack(ralue_pl);
-       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
+               if (!mlxsw_sp_vr_is_used(vr))
+                       continue;
+
+               mlxsw_reg_raltb_pack(raltb_pl, vr->id,
+                                    MLXSW_REG_RALXX_PROTOCOL_IPV4,
+                                    MLXSW_SP_LPM_TREE_MIN);
+               err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb),
+                                     raltb_pl);
+               if (err)
+                       return err;
+
+               mlxsw_reg_ralue_pack4(ralue_pl, MLXSW_SP_L3_PROTO_IPV4,
+                                     MLXSW_REG_RALUE_OP_WRITE_WRITE, vr->id, 0,
+                                     0);
+               mlxsw_reg_ralue_act_ip2me_pack(ralue_pl);
+               err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue),
+                                     ralue_pl);
+               if (err)
+                       return err;
+       }
+
+       return 0;
 }
 
 static void mlxsw_sp_fib4_node_flush(struct mlxsw_sp *mlxsw_sp,