dev.dpdk.org archive mirror
 help / color / mirror / Atom feed
From: Xiaoyu Min <jackmin@mellanox.com>
To: rasland@mellanox.com, viacheslavo@mellanox.com,
	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
Subject: [dpdk-dev] [PATCH v4] net/mlx5: support IP-in-IP tunnel
Date: Wed, 10 Jul 2019 22:59:45 +0800	[thread overview]
Message-ID: <ef05b06fb050ca48fd7fd7ce8ddd876632f7b7a1.1562770515.git.jackmin@mellanox.com> (raw)
In-Reply-To: <20190528020426.18638-1-jackmin@mellanox.com>

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

The example testpmd commands would be:

- Match on IPv4 over IPv4 packets and do inner RSS:

  testpmd> flow create 0 ingress pattern eth / ipv4 proto is 0x04 /
           ipv4 / udp / end actions rss level 2 queues 0 1 2 3 end / end

- Match on IPv6 over IPv4 packets and do inner RSS:

  testpmd> flow create 0 ingress pattern eth / ipv4 proto is 0x29 /
           ipv6 / udp / end actions rss level 2 queues 0 1 2 3 end / end

Signed-off-by: Xiaoyu Min <jackmin@mellanox.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
v2:
  * updated release note
v3:
  * rebased on 19.08-rc1
v4:
  * add example testpmd commands in commit log
---
 doc/guides/nics/mlx5.rst               | 15 ++++++++++-
 doc/guides/rel_notes/release_19_08.rst |  1 +
 drivers/net/mlx5/mlx5_flow.c           | 35 ++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_flow.h           |  6 ++++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 37 ++++++++++++++++++++++++++
 5 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 20cbba7ace..16aa390380 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`.
@@ -540,6 +540,19 @@ Firmware configuration
      mlxconfig -d <mst device> query | grep FLEX_PARSER_PROFILE_ENABLE
      FLEX_PARSER_PROFILE_ENABLE         2
 
+- 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/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 27d5915bed..a9ec6adb69 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -112,6 +112,7 @@ New Features
   * Updated the packet header modification feature. Added support of TCP header
     sequence number and acknowledgment number modification.
   * Added support for match on ICMP/ICMP6 code and type.
+  * Added support for IP-in-IP tunnel.
 
 * **Updated Solarflare network PMD.**
 
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 534cd9338e..005a1a69a7 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1282,6 +1282,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),
@@ -1296,7 +1297,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,
@@ -1346,6 +1364,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 =
@@ -1365,7 +1384,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 3d7fcf706e..ef430d6d44 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -54,6 +54,9 @@
 #define MLX5_FLOW_LAYER_ICMP (1u << 18)
 #define MLX5_FLOW_LAYER_ICMP6 (1u << 19)
 
+#define MLX5_FLOW_LAYER_IPIP (1u << 20)
+#define MLX5_FLOW_LAYER_IPV6_ENCAP (1u << 21)
+
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
 	(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
@@ -66,7 +69,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 9cc09e73c9..54c1b9f2e1 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -141,6 +141,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
@@ -2355,6 +2388,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,
@@ -2376,6 +2410,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
@@ -4348,6 +4383,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,
@@ -4360,6 +4396,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


  parent reply	other threads:[~2019-07-10 14:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-28  2:04 [dpdk-dev] [PATCH] net/mlx5: support IP-in-IP tunnel Xiaoyu Min
2019-07-02  5:51 ` [dpdk-dev] [PATCH v2] " 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 ` Xiaoyu Min [this message]
2019-07-14 12:26   ` [dpdk-dev] [Suspected-Phishing][PATCH v4] " 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=ef05b06fb050ca48fd7fd7ce8ddd876632f7b7a1.1562770515.git.jackmin@mellanox.com \
    --to=jackmin@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=john.mcnamara@intel.com \
    --cc=marko.kovacevic@intel.com \
    --cc=rasland@mellanox.com \
    --cc=shahafs@mellanox.com \
    --cc=viacheslavo@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).