DPDK patches and discussions
 help / color / mirror / Atom feed
From: Dekel Peled <dekelp@mellanox.com>
To: yskoh@mellanox.com, shahafs@mellanox.com
Cc: dev@dpdk.org, orika@mellanox.com, dekelp@mellanox.com
Subject: [dpdk-dev] [PATCH v3 1/3] net/mlx5: add MPLS to Direct Verbs flow engine
Date: Thu, 15 Nov 2018 17:17:12 +0200	[thread overview]
Message-ID: <1542295034-16098-2-git-send-email-dekelp@mellanox.com> (raw)
In-Reply-To: <1542102705-55243-1-git-send-email-dekelp@mellanox.com>

From: Shahaf Shuler <shahafs@mellanox.com>

The support in MPLS on this flow engine was overlooked. It's absence is
critical because there are required actions for MPLS which can be done
only with the DV engine.

To set correctly the MPLS filter, we need to reason about the flow item
before the MPLS (UDP, GRE or other).
To do that, a new variable last_item was added and updated after each
translation. the full item flags are updated after each item iteration.

Signed-off-by: Shahaf Shuler <shahafs@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow.h    |   3 +
 drivers/net/mlx5/mlx5_flow_dv.c | 145 ++++++++++++++++++++++++++++++++++------
 2 files changed, 129 insertions(+), 19 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 51ab47f..3022090 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -114,6 +114,9 @@
 #define IPPROTO_MPLS 137
 #endif
 
+/* UDP port number for MPLS */
+#define MLX5_UDP_PORT_MPLS 6635
+
 /* UDP port numbers for VxLAN. */
 #define MLX5_UDP_PORT_VXLAN 4789
 #define MLX5_UDP_PORT_VXLAN_GPE 4790
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index a2edd16..e8cd253 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -890,6 +890,14 @@
 				return ret;
 			item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE;
 			break;
+		case RTE_FLOW_ITEM_TYPE_MPLS:
+			ret = mlx5_flow_validate_item_mpls(items, item_flags,
+							   next_protocol,
+							   error);
+			if (ret < 0)
+				return ret;
+			item_flags |= MLX5_FLOW_LAYER_MPLS;
+			break;
 		case RTE_FLOW_ITEM_TYPE_META:
 			ret = flow_dv_validate_item_meta(dev, items, attr,
 							 error);
@@ -1609,6 +1617,98 @@
 }
 
 /**
+ * Add MPLS item to matcher and to the value.
+ *
+ * @param[in, out] matcher
+ *   Flow matcher.
+ * @param[in, out] key
+ *   Flow matcher value.
+ * @param[in] item
+ *   Flow pattern to translate.
+ * @param[in] prev_layer
+ *   The protocol layer indicated in previous item.
+ * @param[in] inner
+ *   Item is inner pattern.
+ */
+static void
+flow_dv_translate_item_mpls(void *matcher, void *key,
+			    const struct rte_flow_item *item,
+			    uint64_t prev_layer,
+			    int inner)
+{
+#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
+	const uint32_t *in_mpls_m = item->mask;
+	const uint32_t *in_mpls_v = item->spec;
+	uint32_t *out_mpls_m = 0;
+	uint32_t *out_mpls_v = 0;
+	void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters);
+	void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
+	void *misc2_m = MLX5_ADDR_OF(fte_match_param, matcher,
+				     misc_parameters_2);
+	void *misc2_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_2);
+	void *headers_m = MLX5_ADDR_OF(fte_match_param, matcher, outer_headers);
+	void *headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers);
+
+	switch (prev_layer) {
+	case MLX5_FLOW_LAYER_OUTER_L4_UDP:
+		MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, 0xffff);
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
+			 MLX5_UDP_PORT_MPLS);
+		break;
+	case MLX5_FLOW_LAYER_GRE:
+		MLX5_SET(fte_match_set_misc, misc_m, gre_protocol, 0xffff);
+		MLX5_SET(fte_match_set_misc, misc_v, gre_protocol,
+			 ETHER_TYPE_MPLS);
+		break;
+	default:
+		MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_protocol, 0xff);
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
+			 IPPROTO_MPLS);
+		break;
+	}
+	if (!in_mpls_v)
+		return;
+	if (!in_mpls_m)
+		in_mpls_m = (const uint32_t *)&rte_flow_item_mpls_mask;
+	switch (prev_layer) {
+	case MLX5_FLOW_LAYER_OUTER_L4_UDP:
+		out_mpls_m =
+			(uint32_t *)MLX5_ADDR_OF(fte_match_set_misc2, misc2_m,
+						 outer_first_mpls_over_udp);
+		out_mpls_v =
+			(uint32_t *)MLX5_ADDR_OF(fte_match_set_misc2, misc2_v,
+						 outer_first_mpls_over_udp);
+		break;
+	case MLX5_FLOW_LAYER_GRE:
+		out_mpls_m =
+			(uint32_t *)MLX5_ADDR_OF(fte_match_set_misc2, misc2_m,
+						 outer_first_mpls_over_gre);
+		out_mpls_v =
+			(uint32_t *)MLX5_ADDR_OF(fte_match_set_misc2, misc2_v,
+						 outer_first_mpls_over_gre);
+		break;
+	default:
+		/* Inner MPLS not over GRE is not supported. */
+		if (!inner) {
+			out_mpls_m =
+				(uint32_t *)MLX5_ADDR_OF(fte_match_set_misc2,
+							 misc2_m,
+							 outer_first_mpls);
+			out_mpls_v =
+				(uint32_t *)MLX5_ADDR_OF(fte_match_set_misc2,
+							 misc2_v,
+							 outer_first_mpls);
+		}
+		break;
+	}
+	if (out_mpls_m && out_mpls_v) {
+		*out_mpls_m = *in_mpls_m;
+		*out_mpls_v = *in_mpls_v & *in_mpls_m;
+	}
+#endif
+}
+
+/**
  * Add META item to matcher
  *
  * @param[in, out] matcher
@@ -1786,6 +1886,7 @@
 	struct priv *priv = dev->data->dev_private;
 	struct rte_flow *flow = dev_flow->flow;
 	uint64_t item_flags = 0;
+	uint64_t last_item = 0;
 	uint64_t action_flags = 0;
 	uint64_t priority = attr->priority;
 	struct mlx5_flow_dv_matcher matcher = {
@@ -1940,17 +2041,17 @@
 			flow_dv_translate_item_eth(match_mask, match_value,
 						   items, tunnel);
 			matcher.priority = MLX5_PRIORITY_MAP_L2;
-			item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 :
-					       MLX5_FLOW_LAYER_OUTER_L2;
+			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L2 :
+					     MLX5_FLOW_LAYER_OUTER_L2;
 			break;
 		case RTE_FLOW_ITEM_TYPE_VLAN:
 			flow_dv_translate_item_vlan(match_mask, match_value,
 						    items, tunnel);
 			matcher.priority = MLX5_PRIORITY_MAP_L2;
-			item_flags |= tunnel ? (MLX5_FLOW_LAYER_INNER_L2 |
-						MLX5_FLOW_LAYER_INNER_VLAN) :
-					       (MLX5_FLOW_LAYER_OUTER_L2 |
-						MLX5_FLOW_LAYER_OUTER_VLAN);
+			last_item = tunnel ? (MLX5_FLOW_LAYER_INNER_L2 |
+					      MLX5_FLOW_LAYER_INNER_VLAN) :
+					     (MLX5_FLOW_LAYER_OUTER_L2 |
+					      MLX5_FLOW_LAYER_OUTER_VLAN);
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV4:
 			flow_dv_translate_item_ipv4(match_mask, match_value,
@@ -1961,8 +2062,8 @@
 					(dev_flow, tunnel,
 					 MLX5_IPV4_LAYER_TYPES,
 					 MLX5_IPV4_IBV_RX_HASH);
-			item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 :
-					       MLX5_FLOW_LAYER_OUTER_L3_IPV4;
+			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 :
+					     MLX5_FLOW_LAYER_OUTER_L3_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
 			flow_dv_translate_item_ipv6(match_mask, match_value,
@@ -1973,8 +2074,8 @@
 					(dev_flow, tunnel,
 					 MLX5_IPV6_LAYER_TYPES,
 					 MLX5_IPV6_IBV_RX_HASH);
-			item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 :
-					       MLX5_FLOW_LAYER_OUTER_L3_IPV6;
+			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 :
+					     MLX5_FLOW_LAYER_OUTER_L3_IPV6;
 			break;
 		case RTE_FLOW_ITEM_TYPE_TCP:
 			flow_dv_translate_item_tcp(match_mask, match_value,
@@ -1985,8 +2086,8 @@
 					(dev_flow, tunnel, ETH_RSS_TCP,
 					 IBV_RX_HASH_SRC_PORT_TCP |
 					 IBV_RX_HASH_DST_PORT_TCP);
-			item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP :
-					       MLX5_FLOW_LAYER_OUTER_L4_TCP;
+			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP :
+					     MLX5_FLOW_LAYER_OUTER_L4_TCP;
 			break;
 		case RTE_FLOW_ITEM_TYPE_UDP:
 			flow_dv_translate_item_udp(match_mask, match_value,
@@ -1997,37 +2098,43 @@
 					(dev_flow, tunnel, ETH_RSS_UDP,
 					 IBV_RX_HASH_SRC_PORT_UDP |
 					 IBV_RX_HASH_DST_PORT_UDP);
-			item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP :
-					       MLX5_FLOW_LAYER_OUTER_L4_UDP;
+			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP :
+					     MLX5_FLOW_LAYER_OUTER_L4_UDP;
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			flow_dv_translate_item_gre(match_mask, match_value,
 						   items, tunnel);
-			item_flags |= MLX5_FLOW_LAYER_GRE;
+			last_item = MLX5_FLOW_LAYER_GRE;
 			break;
 		case RTE_FLOW_ITEM_TYPE_NVGRE:
 			flow_dv_translate_item_nvgre(match_mask, match_value,
 						     items, tunnel);
-			item_flags |= MLX5_FLOW_LAYER_GRE;
+			last_item = MLX5_FLOW_LAYER_GRE;
 			break;
 		case RTE_FLOW_ITEM_TYPE_VXLAN:
 			flow_dv_translate_item_vxlan(match_mask, match_value,
 						     items, tunnel);
-			item_flags |= MLX5_FLOW_LAYER_VXLAN;
+			last_item = MLX5_FLOW_LAYER_VXLAN;
 			break;
 		case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
 			flow_dv_translate_item_vxlan(match_mask, match_value,
 						     items, tunnel);
-			item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE;
+			last_item = MLX5_FLOW_LAYER_VXLAN_GPE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_MPLS:
+			flow_dv_translate_item_mpls(match_mask, match_value,
+						    items, last_item, tunnel);
+			last_item = MLX5_FLOW_LAYER_MPLS;
 			break;
 		case RTE_FLOW_ITEM_TYPE_META:
 			flow_dv_translate_item_meta(match_mask, match_value,
 						    items);
-			item_flags |= MLX5_FLOW_ITEM_METADATA;
+			last_item = MLX5_FLOW_ITEM_METADATA;
 			break;
 		default:
 			break;
 		}
+		item_flags |= last_item;
 	}
 	assert(!flow_dv_check_valid_spec(matcher.mask.buf,
 					 dev_flow->dv.value.buf));
-- 
1.8.3.1

  parent reply	other threads:[~2018-11-15 15:18 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-12  9:20 [dpdk-dev] [PATCH] net/mlx5: fix MPLS item validation Dekel Peled
2018-11-12  9:52 ` Ori Kam
2018-11-13  9:51 ` [dpdk-dev] [PATCH v2 0/2] net/mlx5: update MPLS item support Dekel Peled
2018-11-15 15:17   ` [dpdk-dev] [PATCH v3 0/3] " Dekel Peled
2018-11-15 20:44     ` Shahaf Shuler
2018-11-15 15:17   ` Dekel Peled [this message]
2018-11-15 15:17   ` [dpdk-dev] [PATCH v3 2/3] net/mlx5: fix MPLS item validation Dekel Peled
2018-11-15 15:17   ` [dpdk-dev] [PATCH v3 3/3] net/mlx5: fix tunnel ptype of MPLS in UDP Dekel Peled
2018-11-13  9:51 ` [dpdk-dev] [PATCH v2 1/2] net/mlx5: add MPLS to Direct Verbs flow engine Dekel Peled
2018-11-13  9:51 ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: fix MPLS item validation Dekel Peled

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1542295034-16098-2-git-send-email-dekelp@mellanox.com \
    --to=dekelp@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=orika@mellanox.com \
    --cc=shahafs@mellanox.com \
    --cc=yskoh@mellanox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).