All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xiaoyu Min <jackmin@mellanox.com>
To: Shahaf Shuler <shahafs@mellanox.com>,
	Yongseok Koh <yskoh@mellanox.com>,
	John McNamara <john.mcnamara@intel.com>,
	Marko Kovacevic <marko.kovacevic@intel.com>
Cc: dev@dpdk.org, jackmin@mellanox.com
Subject: [dpdk-dev] [PATCH] net/mlx5: support IP-in-IP tunnel
Date: Tue, 28 May 2019 05:04:25 +0300	[thread overview]
Message-ID: <20190528020426.18638-1-jackmin@mellanox.com> (raw)

Enabled IP-in-IP tunnel type support on DV/DR flow engine.
This includes the following combination:
 - IPv4 over IPv4
 - IPv4 over IPv6
 - IPv6 over IPv4
 - IPv6 over IPv6

MLX5 NIC supports IP-in-IP tunnel via FLEX Parser so
need to make sure fw using FLEX Paser profile 0.

  mlxconfig -d <mst device> -y set FLEX_PARSER_PROFILE_ENABLE=0

Signed-off-by: Xiaoyu Min <jackmin@mellanox.com>
---
 doc/guides/nics/mlx5.rst        | 15 ++++++++++++-
 drivers/net/mlx5/mlx5_flow.c    | 35 +++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_flow.h    |  9 +++++---
 drivers/net/mlx5/mlx5_flow_dv.c | 37 +++++++++++++++++++++++++++++++++
 4 files changed, 92 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 5176aa845c..67377048ae 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -76,7 +76,7 @@ Features
 - RX interrupts.
 - Statistics query including Basic, Extended and per queue.
 - Rx HW timestamp.
-- Tunnel types: VXLAN, L3 VXLAN, VXLAN-GPE, GRE, MPLSoGRE, MPLSoUDP.
+- Tunnel types: VXLAN, L3 VXLAN, VXLAN-GPE, GRE, MPLSoGRE, MPLSoUDP, IP-in-IP.
 - Tunnel HW offloads: packet type, inner/outer RSS, IP and UDP checksum verification.
 - NIC HW offloads: encapsulation (vxlan, gre, mplsoudp, mplsogre), NAT, routing, TTL
   increment/decrement, count, drop, mark. For details please see :ref:`Supported hardware offloads using rte_flow API`.
@@ -518,6 +518,19 @@ Firmware configuration
      IP_OVER_VXLAN_EN                    True(1)
      IP_OVER_VXLAN_PORT                  <udp dport>
 
+- IP-in-IP tunnel enable
+
+   .. code-block:: console
+
+     mlxconfig -d <mst device> set FLEX_PARSER_PROFILE_ENABLE=0
+
+  Verify configurations are set:
+
+   .. code-block:: console
+
+     mlxconfig -d <mst device> query | grep FLEX_PARSER_PROFILE_ENABLE
+     FLEX_PARSER_PROFILE_ENABLE          0
+
 Prerequisites
 -------------
 
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 98870184d0..66f36f64bf 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1180,6 +1180,7 @@ mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item,
 			     struct rte_flow_error *error)
 {
 	const struct rte_flow_item_ipv4 *mask = item->mask;
+	const struct rte_flow_item_ipv4 *spec = item->spec;
 	const struct rte_flow_item_ipv4 nic_mask = {
 		.hdr = {
 			.src_addr = RTE_BE32(0xffffffff),
@@ -1194,7 +1195,24 @@ mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item,
 	const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
 				      MLX5_FLOW_LAYER_OUTER_L4;
 	int ret;
+	uint8_t next_proto = 0xFF;
 
+	if (item_flags & MLX5_FLOW_LAYER_IPIP) {
+		if (mask && spec)
+			next_proto = mask->hdr.next_proto_id &
+				     spec->hdr.next_proto_id;
+		if (next_proto == IPPROTO_IPIP || next_proto == IPPROTO_IPV6)
+			return rte_flow_error_set(error, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ITEM,
+						  item,
+						  "multiple tunnel "
+						  "not supported");
+	}
+	if (item_flags & MLX5_FLOW_LAYER_IPV6_ENCAP)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "wrong tunnel type - IPv6 specified "
+					  "but IPv4 item provided");
 	if (item_flags & l3m)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
@@ -1244,6 +1262,7 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item,
 			     struct rte_flow_error *error)
 {
 	const struct rte_flow_item_ipv6 *mask = item->mask;
+	const struct rte_flow_item_ipv6 *spec = item->spec;
 	const struct rte_flow_item_ipv6 nic_mask = {
 		.hdr = {
 			.src_addr =
@@ -1263,7 +1282,23 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item,
 	const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
 				      MLX5_FLOW_LAYER_OUTER_L4;
 	int ret;
+	uint8_t next_proto = 0xFF;
 
+	if (item_flags & MLX5_FLOW_LAYER_IPV6_ENCAP) {
+		if (mask && spec)
+			next_proto = mask->hdr.proto & spec->hdr.proto;
+		if (next_proto == IPPROTO_IPIP || next_proto == IPPROTO_IPV6)
+			return rte_flow_error_set(error, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ITEM,
+						  item,
+						  "multiple tunnel "
+						  "not supported");
+	}
+	if (item_flags & MLX5_FLOW_LAYER_IPIP)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "wrong tunnel type - IPv4 specified "
+					  "but IPv6 item provided");
 	if (item_flags & l3m)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index b6654200cb..6501accfe4 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -45,10 +45,12 @@
 #define MLX5_FLOW_LAYER_VXLAN_GPE (1u << 13)
 #define MLX5_FLOW_LAYER_GRE (1u << 14)
 #define MLX5_FLOW_LAYER_MPLS (1u << 15)
+#define MLX5_FLOW_LAYER_IPIP (1u << 16)
+#define MLX5_FLOW_LAYER_IPV6_ENCAP (1u << 17)
 
 /* General pattern items bits. */
-#define MLX5_FLOW_ITEM_METADATA (1u << 16)
-#define MLX5_FLOW_ITEM_PORT_ID (1u << 17)
+#define MLX5_FLOW_ITEM_METADATA (1u << 18)
+#define MLX5_FLOW_ITEM_PORT_ID (1u << 19)
 
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
@@ -62,7 +64,8 @@
 /* Tunnel Masks. */
 #define MLX5_FLOW_LAYER_TUNNEL \
 	(MLX5_FLOW_LAYER_VXLAN | MLX5_FLOW_LAYER_VXLAN_GPE | \
-	 MLX5_FLOW_LAYER_GRE | MLX5_FLOW_LAYER_MPLS)
+	 MLX5_FLOW_LAYER_GRE | MLX5_FLOW_LAYER_MPLS | \
+	 MLX5_FLOW_LAYER_IPIP | MLX5_FLOW_LAYER_IPV6_ENCAP)
 
 /* Inner Masks. */
 #define MLX5_FLOW_LAYER_INNER_L3 \
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index d096b02bba..1e9a497e7b 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -139,6 +139,39 @@ struct field_modify_info modify_tcp[] = {
 	{0, 0, 0},
 };
 
+static void
+mlx5_flow_tunnel_ip_check(const struct rte_flow_item *item, uint64_t *flags)
+{
+	uint8_t next_protocol = 0xFF;
+
+	if (item->mask != NULL) {
+		switch (item->type) {
+		case RTE_FLOW_ITEM_TYPE_IPV4:
+			next_protocol =
+				((const struct rte_flow_item_ipv4 *)
+				 (item->spec))->hdr.next_proto_id;
+			next_protocol &=
+				((const struct rte_flow_item_ipv4 *)
+				 (item->mask))->hdr.next_proto_id;
+			break;
+		case RTE_FLOW_ITEM_TYPE_IPV6:
+			next_protocol =
+				((const struct rte_flow_item_ipv6 *)
+				 (item->spec))->hdr.proto;
+			next_protocol &=
+				((const struct rte_flow_item_ipv6 *)
+				 (item->mask))->hdr.proto;
+			break;
+		default:
+			break;
+		}
+	}
+	if (next_protocol == IPPROTO_IPIP)
+		*flags |= MLX5_FLOW_LAYER_IPIP;
+	if (next_protocol == IPPROTO_IPV6)
+		*flags |= MLX5_FLOW_LAYER_IPV6_ENCAP;
+}
+
 /**
  * Acquire the synchronizing object to protect multithreaded access
  * to shared dv context. Lock occurs only if context is actually
@@ -2127,6 +2160,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 				/* Reset for inner layer. */
 				next_protocol = 0xff;
 			}
+			mlx5_flow_tunnel_ip_check(items, &last_item);
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
 			ret = mlx5_flow_validate_item_ipv6(items, item_flags,
@@ -2148,6 +2182,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 				/* Reset for inner layer. */
 				next_protocol = 0xff;
 			}
+			mlx5_flow_tunnel_ip_check(items, &last_item);
 			break;
 		case RTE_FLOW_ITEM_TYPE_TCP:
 			ret = mlx5_flow_validate_item_tcp
@@ -3953,6 +3988,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 					 MLX5_IPV4_IBV_RX_HASH);
 			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 :
 					     MLX5_FLOW_LAYER_OUTER_L3_IPV4;
+			mlx5_flow_tunnel_ip_check(items, &last_item);
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
 			flow_dv_translate_item_ipv6(match_mask, match_value,
@@ -3965,6 +4001,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 					 MLX5_IPV6_IBV_RX_HASH);
 			last_item = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 :
 					     MLX5_FLOW_LAYER_OUTER_L3_IPV6;
+			mlx5_flow_tunnel_ip_check(items, &last_item);
 			break;
 		case RTE_FLOW_ITEM_TYPE_TCP:
 			flow_dv_translate_item_tcp(match_mask, match_value,
-- 
2.21.0


             reply	other threads:[~2019-05-28  2:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-28  2:04 Xiaoyu Min [this message]
2019-07-02  5:51 ` [dpdk-dev] [PATCH v2] net/mlx5: support IP-in-IP tunnel Xiaoyu Min
2019-07-10 10:15 ` [dpdk-dev] [PATCH v3] " Xiaoyu Min
2019-07-10 14:19   ` [dpdk-dev] [Suspected-Phishing][PATCH " Slava Ovsiienko
2019-07-10 14:35     ` Slava Ovsiienko
2019-07-10 14:40       ` Jack Min
2019-07-10 14:59 ` [dpdk-dev] [PATCH v4] " Xiaoyu Min
2019-07-14 12:26   ` [dpdk-dev] [Suspected-Phishing][PATCH " Raslan Darawsheh

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=20190528020426.18638-1-jackmin@mellanox.com \
    --to=jackmin@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=john.mcnamara@intel.com \
    --cc=marko.kovacevic@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.