mlxsw: spectrum: mr: Support trap-and-forward routes
authorYotam Gigi <yotamg@mellanox.com>
Tue, 3 Oct 2017 07:58:12 +0000 (09:58 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 3 Oct 2017 17:06:30 +0000 (10:06 -0700)
Add the support of trap-and-forward route action in the multicast routing
offloading logic. A route will be set to trap-and-forward action if one (or
more) of its output interfaces is not offload-able, i.e. does not have a
valid Spectrum RIF.

This way, a route with mixed output VIFs list, which contains both
offload-able and un-offload-able devices can go through partial offloading
in hardware, and the rest will be done in the kernel ipmr module.

Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Reviewed-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_mr.c

index 4aaf6ca1be7ccf0ccda1c9d52cb2bbd35ce1c246..1f84bb8e91352c02414cc2d7319e1a5cea28451b 100644 (file)
@@ -114,9 +114,9 @@ static bool mlxsw_sp_mr_vif_valid(const struct mlxsw_sp_mr_vif *vif)
        return mlxsw_sp_mr_vif_regular(vif) && vif->dev && vif->rif;
 }
 
-static bool mlxsw_sp_mr_vif_rif_invalid(const struct mlxsw_sp_mr_vif *vif)
+static bool mlxsw_sp_mr_vif_exists(const struct mlxsw_sp_mr_vif *vif)
 {
-       return mlxsw_sp_mr_vif_regular(vif) && vif->dev && !vif->rif;
+       return vif->dev;
 }
 
 static bool
@@ -182,14 +182,13 @@ mlxsw_sp_mr_route_action(const struct mlxsw_sp_mr_route *mr_route)
        if (!mlxsw_sp_mr_route_valid_evifs_num(mr_route))
                return MLXSW_SP_MR_ROUTE_ACTION_TRAP;
 
-       /* If either one of the eVIFs is not regular (VIF of type pimreg or
-        * tunnel) or one of the VIFs has no matching RIF, trap the packet.
+       /* If one of the eVIFs has no RIF, trap-and-forward the route as there
+        * is some more routing to do in software too.
         */
-       list_for_each_entry(rve, &mr_route->evif_list, route_node) {
-               if (!mlxsw_sp_mr_vif_regular(rve->mr_vif) ||
-                   mlxsw_sp_mr_vif_rif_invalid(rve->mr_vif))
-                       return MLXSW_SP_MR_ROUTE_ACTION_TRAP;
-       }
+       list_for_each_entry(rve, &mr_route->evif_list, route_node)
+               if (mlxsw_sp_mr_vif_exists(rve->mr_vif) && !rve->mr_vif->rif)
+                       return MLXSW_SP_MR_ROUTE_ACTION_TRAP_AND_FORWARD;
+
        return MLXSW_SP_MR_ROUTE_ACTION_FORWARD;
 }