Commit 3b81bcba authored by Erez Shitrit's avatar Erez Shitrit Committed by Saeed Mahameed
Browse files

net/mlx5: DR, Handle multi destination action in the right order



Whenever we have few destinations from Flow-table type we need to put
the one that goes to the wire to be the last one.

We are using FW in order to get iterator, the FW uses RX for the first
destinations and TX for the last destination, if we want the packet to
be directed to the wire it should be done in the TX path and not in the
RX.
The code now checks if the FT is directed to the wire and if so puts it
as the last destination.

Signed-off-by: default avatarErez Shitrit <erezsh@nvidia.com>
Reviewed-by: default avatarMoshe Shemesh <moshe@nvidia.com>
Reviewed-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent f6f46e71
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -1169,13 +1169,16 @@ mlx5dr_action_create_mult_dest_tbl(struct mlx5dr_domain *dmn,
				   bool ignore_flow_level,
				   u32 flow_source)
{
	struct mlx5dr_cmd_flow_destination_hw_info tmp_hw_dest;
	struct mlx5dr_cmd_flow_destination_hw_info *hw_dests;
	struct mlx5dr_action **ref_actions;
	struct mlx5dr_action *action;
	bool reformat_req = false;
	bool is_ft_wire = false;
	u16 num_dst_ft = 0;
	u32 num_of_ref = 0;
	u32 ref_act_cnt;
	u16 last_dest;
	int ret;
	int i;

@@ -1224,10 +1227,15 @@ mlx5dr_action_create_mult_dest_tbl(struct mlx5dr_domain *dmn,
			}
			num_dst_ft++;
			hw_dests[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
			if (dest_action->dest_tbl->is_fw_tbl)
			if (dest_action->dest_tbl->is_fw_tbl) {
				hw_dests[i].ft_id = dest_action->dest_tbl->fw_tbl.id;
			else
			} else {
				hw_dests[i].ft_id = dest_action->dest_tbl->tbl->table_id;
				if (dest_action->dest_tbl->is_wire_ft) {
					is_ft_wire = true;
					last_dest = i;
				}
			}
			break;

		default:
@@ -1236,6 +1244,16 @@ mlx5dr_action_create_mult_dest_tbl(struct mlx5dr_domain *dmn,
		}
	}

	/* In multidest, the FW does the iterator in the RX except of the last
	 * one that done in the TX.
	 * So, if one of the ft target is wire, put it at the end of the dest list.
	 */
	if (is_ft_wire && num_dst_ft > 1) {
		tmp_hw_dest = hw_dests[last_dest];
		hw_dests[last_dest] = hw_dests[num_of_dests - 1];
		hw_dests[num_of_dests - 1] = tmp_hw_dest;
	}

	action = dr_action_create_generic(DR_ACTION_TYP_FT);
	if (!action)
		goto free_ref_actions;
+1 −0
Original line number Diff line number Diff line
@@ -1064,6 +1064,7 @@ struct mlx5dr_action_sampler {

struct mlx5dr_action_dest_tbl {
	u8 is_fw_tbl:1;
	u8 is_wire_ft:1;
	union {
		struct mlx5dr_table *tbl;
		struct {
+8 −1
Original line number Diff line number Diff line
@@ -209,10 +209,17 @@ static struct mlx5dr_action *create_ft_action(struct mlx5dr_domain *domain,
					      struct mlx5_flow_rule *dst)
{
	struct mlx5_flow_table *dest_ft = dst->dest_attr.ft;
	struct mlx5dr_action *tbl_action;

	if (mlx5dr_is_fw_table(dest_ft))
		return mlx5dr_action_create_dest_flow_fw_table(domain, dest_ft);
	return mlx5dr_action_create_dest_table(dest_ft->fs_dr_table.dr_table);

	tbl_action = mlx5dr_action_create_dest_table(dest_ft->fs_dr_table.dr_table);
	if (tbl_action)
		tbl_action->dest_tbl->is_wire_ft =
			dest_ft->flags & MLX5_FLOW_TABLE_UPLINK_VPORT ? 1 : 0;

	return tbl_action;
}

static struct mlx5dr_action *create_range_action(struct mlx5dr_domain *domain,