net/mlx5: E-switch, Change flow rule destination checking
authorJianbo Liu <jianbol@nvidia.com>
Thu, 11 Jan 2024 01:27:47 +0000 (01:27 +0000)
committerSaeed Mahameed <saeedm@nvidia.com>
Sat, 2 Mar 2024 07:02:26 +0000 (23:02 -0800)
The checking in the cited commit is not accurate. In the common case,
VF destination is internal, and uplink destination is external.
However, uplink destination with packet reformat is considered as
internal because firmware uses LB+hairpin to support it. Update the
checking so header rewrite rules with both internal and external
destinations are not allowed.

Fixes: e0e22d59b47a ("net/mlx5: E-switch, Add checking for flow rule destinations")
Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

index 14b3bd3c5e2f718f2e59b7e0dc7cb21411830104..baaae628b0a0f6510e2c350cbab0b6309b32da52 100644 (file)
@@ -535,21 +535,26 @@ esw_src_port_rewrite_supported(struct mlx5_eswitch *esw)
 }
 
 static bool
-esw_dests_to_vf_pf_vports(struct mlx5_flow_destination *dests, int max_dest)
+esw_dests_to_int_external(struct mlx5_flow_destination *dests, int max_dest)
 {
-       bool vf_dest = false, pf_dest = false;
+       bool internal_dest = false, external_dest = false;
        int i;
 
        for (i = 0; i < max_dest; i++) {
-               if (dests[i].type != MLX5_FLOW_DESTINATION_TYPE_VPORT)
+               if (dests[i].type != MLX5_FLOW_DESTINATION_TYPE_VPORT &&
+                   dests[i].type != MLX5_FLOW_DESTINATION_TYPE_UPLINK)
                        continue;
 
-               if (dests[i].vport.num == MLX5_VPORT_UPLINK)
-                       pf_dest = true;
+               /* Uplink dest is external, but considered as internal
+                * if there is reformat because firmware uses LB+hairpin to support it.
+                */
+               if (dests[i].vport.num == MLX5_VPORT_UPLINK &&
+                   !(dests[i].vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID))
+                       external_dest = true;
                else
-                       vf_dest = true;
+                       internal_dest = true;
 
-               if (vf_dest && pf_dest)
+               if (internal_dest && external_dest)
                        return true;
        }
 
@@ -695,9 +700,9 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 
                /* Header rewrite with combined wire+loopback in FDB is not allowed */
                if ((flow_act.action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) &&
-                   esw_dests_to_vf_pf_vports(dest, i)) {
+                   esw_dests_to_int_external(dest, i)) {
                        esw_warn(esw->dev,
-                                "FDB: Header rewrite with forwarding to both PF and VF is not allowed\n");
+                                "FDB: Header rewrite with forwarding to both internal and external dests is not allowed\n");
                        rule = ERR_PTR(-EINVAL);
                        goto err_esw_get;
                }