[v6,09/12] net/mlx5: update validation for mirroring flow

Message ID 1599634114-148013-10-git-send-email-jiaweiw@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series support the flow-based traffic sampling |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Jiawei Wang Sept. 9, 2020, 6:48 a.m. UTC
  Mirroring flow using sample action with ratio is 1, and it doesn't
support jump action with the same one flow.

Sample action must have destination actions like port or queue for
mirroring, and don't need split function as sampling flow.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 26 +++++++++++++++--
 drivers/net/mlx5/mlx5_flow_dv.c | 62 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 82 insertions(+), 6 deletions(-)
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index ce03210..61104a8 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3936,16 +3936,38 @@  struct mlx5_flow_tunnel_info {
  */
 static int
 flow_check_match_action(const struct rte_flow_action actions[],
-					enum rte_flow_action_type action)
+			const struct rte_flow_attr *attr,
+			enum rte_flow_action_type action)
 {
+	const struct rte_flow_action_sample *sample;
 	int actions_n = 0;
+	int jump_flag = 0;
 	int flag = 0;
+	uint32_t ratio = 0;
+	int sub_type = 0;
 
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
 		if (actions->type == action)
 			flag = 1;
+		if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP)
+			jump_flag = 1;
+		if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
+			sample = actions->conf;
+			ratio = sample->ratio;
+			sub_type = ((const struct rte_flow_action *)
+					(sample->actions))->type;
+		}
 		actions_n++;
 	}
+	if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
+		if (ratio == 1) {
+			/* JUMP Action not support for Mirroring;
+			 * Mirroring support multi-destination;
+			 */
+			if (!jump_flag && sub_type != RTE_FLOW_ACTION_TYPE_END)
+				flag = 0;
+		}
+	}
 	/* Count RTE_FLOW_ACTION_TYPE_END. */
 	return flag ? actions_n + 1 : 0;
 }
@@ -4460,7 +4482,7 @@  struct mlx5_flow_tunnel_info {
 	int ret = 0;
 
 	if (priv->sampler_en)
-		actions_n = flow_check_match_action(actions,
+		actions_n = flow_check_match_action(actions, attr,
 					RTE_FLOW_ACTION_TYPE_SAMPLE);
 	if (actions_n) {
 		/* The prefix actions must includes sample, tag, end. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 2241e36..19ad9fc 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -4024,6 +4024,7 @@  struct field_modify_info modify_tcp[] = {
 	const struct rte_flow_action_sample *sample = action->conf;
 	const struct rte_flow_action *act;
 	uint64_t sub_action_flags = 0;
+	uint16_t queue_index = 0xFFFF;
 	int actions_n = 0;
 	int ret;
 
@@ -4063,6 +4064,8 @@  struct field_modify_info modify_tcp[] = {
 							      attr, error);
 			if (ret < 0)
 				return ret;
+			queue_index = ((const struct rte_flow_action_queue *)
+							(act->conf))->index;
 			sub_action_flags |= MLX5_FLOW_ACTION_QUEUE;
 			++actions_n;
 			break;
@@ -4086,6 +4089,25 @@  struct field_modify_info modify_tcp[] = {
 			sub_action_flags |= MLX5_FLOW_ACTION_COUNT;
 			++actions_n;
 			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			ret = flow_dv_validate_action_port_id(dev,
+							      sub_action_flags,
+							      act,
+							      attr,
+							      error);
+			if (ret)
+				return ret;
+			sub_action_flags |= MLX5_FLOW_ACTION_PORT_ID;
+			++actions_n;
+			break;
+		case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
+			ret = flow_dv_validate_action_raw_encap_decap
+				(dev, NULL, act->conf, attr, &sub_action_flags,
+				 &actions_n, error);
+			if (ret < 0)
+				return ret;
+			++actions_n;
+			break;
 		default:
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -4108,10 +4130,42 @@  struct field_modify_info modify_tcp[] = {
 					  "Sample Only support Ingress "
 					  "or E-Switch");
 	} else if (sample->actions->type != RTE_FLOW_ACTION_TYPE_END) {
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "E-Switch doesn't support any "
-					  "optional action for sampling");
+		if (sample->ratio > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "E-Switch doesn't support "
+						  "any optional action "
+						  "for sampling");
+		if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "unsupported action QUEUE");
+		if (!(sub_action_flags & MLX5_FLOW_ACTION_PORT_ID))
+			return rte_flow_error_set(error, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "E-Switch must has a dest "
+						  "port for mirroring");
+	}
+	/* Continue validation for Xcap actions.*/
+	if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) &&
+	    (queue_index == 0xFFFF ||
+	     mlx5_rxq_get_type(dev, queue_index) != MLX5_RXQ_TYPE_HAIRPIN)) {
+		if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) ==
+		     MLX5_FLOW_XCAP_ACTIONS)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL, "encap and decap "
+						  "combination aren't "
+						  "supported");
+		if (!attr->transfer && attr->ingress && (sub_action_flags &
+							MLX5_FLOW_ACTION_ENCAP))
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL, "encap is not supported"
+						  " for ingress traffic");
 	}
 	return 0;
 }