DPDK patches and discussions
 help / color / mirror / Atom feed
From: Leo Xu <yongquanx@nvidia.com>
To: <dev@dpdk.org>
Cc: Matan Azrad <matan@nvidia.com>,
	Shahaf Shuler <shahafs@nvidia.com>,
	Viacheslav Ovsiienko <viacheslavo@nvidia.com>
Subject: [PATCH 2/3] net/mlx5: add ICMPv6 id and sequence match support
Date: Mon, 12 Dec 2022 10:59:21 +0200	[thread overview]
Message-ID: <20221212085923.2314350-3-yongquanx@nvidia.com> (raw)
In-Reply-To: <20221212085923.2314350-1-yongquanx@nvidia.com>

This patch adds ICMPv6 id and sequence match support.
Since type and code of ICMPv6 echo is already specified by ITEM type:
  RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST
  RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY
mlx5 pmd will set appropriate type and code automatically:
  Echo request: type(128), code(0)
  Echo reply:   type(129), code(0)
type and code provided by application will be ignored.

Signed-off-by: Leo Xu <yongquanx@nvidia.com>
---
 doc/guides/nics/mlx5.rst        |  2 +-
 drivers/net/mlx5/mlx5_flow.c    | 61 ++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_flow.h    |  4 ++
 drivers/net/mlx5/mlx5_flow_dv.c | 76 +++++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c |  2 +
 5 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 328c728f13..d17bb1fe47 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -328,7 +328,7 @@ Limitations
   - The input buffer, providing the removal size, is not validated.
   - The buffer size must match the length of the headers to be removed.
 
-- ICMP(code/type/identifier/sequence number) / ICMP6(code/type) matching, IP-in-IP and MPLS flow matching are all
+- ICMP(code/type/identifier/sequence number) / ICMP6(code/type/identifier/sequence number) matching, IP-in-IP and MPLS flow matching are all
   mutually exclusive features which cannot be supported together
   (see :ref:`mlx5_firmware_config`).
 
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 114451b872..bf6a3010ca 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2442,6 +2442,67 @@ mlx5_flow_validate_item_icmp6(const struct rte_flow_item *item,
 	return 0;
 }
 
+/**
+ * Validate ICMP6 echo request/reply item.
+ *
+ * @param[in] item
+ *   Item specification.
+ * @param[in] item_flags
+ *   Bit-fields that holds the items detected until now.
+ * @param[in] ext_vlan_sup
+ *   Whether extended VLAN features are supported or not.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_flow_validate_item_icmp6_echo(const struct rte_flow_item *item,
+				   uint64_t item_flags,
+				   uint8_t target_protocol,
+				   struct rte_flow_error *error)
+{
+	const struct rte_flow_item_icmp6_echo *mask = item->mask;
+	const struct rte_flow_item_icmp6_echo nic_mask = {
+		.echo.hdr.type = 0xff,
+		.echo.hdr.code = 0xff,
+		.echo.identifier = RTE_BE16(0xffff),
+		.echo.sequence = RTE_BE16(0xffff),
+	};
+	const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
+	const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 :
+				      MLX5_FLOW_LAYER_OUTER_L3_IPV6;
+	const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
+				      MLX5_FLOW_LAYER_OUTER_L4;
+	int ret;
+
+	if (target_protocol != 0xFF && target_protocol != IPPROTO_ICMPV6)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "protocol filtering not compatible"
+					  " with ICMP6 layer");
+	if (!(item_flags & l3m))
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "IPv6 is mandatory to filter on"
+					  " ICMP6");
+	if (item_flags & l4m)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ITEM, item,
+					  "multiple L4 layers not supported");
+	if (!mask)
+		mask = &nic_mask;
+	ret = mlx5_flow_item_acceptable
+		(item, (const uint8_t *)mask,
+		 (const uint8_t *)&nic_mask,
+		 sizeof(struct rte_flow_item_icmp6_echo),
+		 MLX5_ITEM_RANGE_NOT_ACCEPTED, error);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
 /**
  * Validate ICMP item.
  *
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 322ffc5651..e9d763cd4c 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -2333,6 +2333,10 @@ int mlx5_flow_validate_item_icmp6(const struct rte_flow_item *item,
 				   uint64_t item_flags,
 				   uint8_t target_protocol,
 				   struct rte_flow_error *error);
+int mlx5_flow_validate_item_icmp6_echo(const struct rte_flow_item *item,
+				       uint64_t item_flags,
+				       uint8_t target_protocol,
+				       struct rte_flow_error *error);
 int mlx5_flow_validate_item_nvgre(const struct rte_flow_item *item,
 				  uint64_t item_flags,
 				  uint8_t target_protocol,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 49425087d6..1ecfd13d67 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -6194,6 +6194,17 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 			item_ipv6_proto = IPPROTO_ICMPV6;
 			last_item = MLX5_FLOW_LAYER_ICMP6;
 			break;
+		case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST:
+		case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY:
+			ret = mlx5_flow_validate_item_icmp6_echo(items,
+								 item_flags,
+								 next_protocol,
+								 error);
+			if (ret < 0)
+				return ret;
+			item_ipv6_proto = IPPROTO_ICMPV6;
+			last_item = MLX5_FLOW_LAYER_ICMP6;
+			break;
 		case RTE_FLOW_ITEM_TYPE_TAG:
 			ret = flow_dv_validate_item_tag(dev, items,
 							attr, error);
@@ -9165,6 +9176,65 @@ flow_dv_translate_item_icmp6(void *key, const struct rte_flow_item *item,
 		 icmp6_v->code & icmp6_m->code);
 }
 
+/**
+ * Add ICMP6 echo request/reply item to the value.
+ *
+ * @param[in, out] key
+ *   Flow matcher value.
+ * @param[in] item
+ *   Flow pattern to translate.
+ * @param[in] inner
+ *   Item is inner pattern.
+ * @param[in] key_type
+ *   Set flow matcher mask or value.
+ */
+static void
+flow_dv_translate_item_icmp6_echo(void *key, const struct rte_flow_item *item,
+				  int inner, uint32_t key_type)
+{
+	const struct rte_flow_item_icmp6_echo *icmp6_m;
+	const struct rte_flow_item_icmp6_echo *icmp6_v;
+	uint32_t icmp6_header_data_m = 0;
+	uint32_t icmp6_header_data_v = 0;
+	void *headers_v;
+	void *misc3_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_3);
+	uint8_t icmp6_type = 0;
+	struct rte_flow_item_icmp6_echo zero_mask;
+
+	memset(&zero_mask, 0, sizeof(zero_mask));
+	headers_v = inner ? MLX5_ADDR_OF(fte_match_param, key, inner_headers) :
+		MLX5_ADDR_OF(fte_match_param, key, outer_headers);
+	if (key_type & MLX5_SET_MATCHER_M)
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, 0xFF);
+	else
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
+			 IPPROTO_ICMPV6);
+	MLX5_ITEM_UPDATE(item, key_type, icmp6_v, icmp6_m, &zero_mask);
+	/* Set fixed type and code for icmpv6 echo request or reply */
+	icmp6_type = (item->type == RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST ?
+		      RTE_ICMP6_ECHO_REQUEST : RTE_ICMP6_ECHO_REPLY);
+	if (key_type & MLX5_SET_MATCHER_M) {
+		MLX5_SET(fte_match_set_misc3, misc3_v, icmpv6_type, 0xFF);
+		MLX5_SET(fte_match_set_misc3, misc3_v, icmpv6_code, 0xFF);
+	} else {
+		MLX5_SET(fte_match_set_misc3, misc3_v, icmpv6_type, icmp6_type);
+		MLX5_SET(fte_match_set_misc3, misc3_v, icmpv6_code, 0);
+	}
+	if (icmp6_v == NULL)
+		return;
+	/* Set icmp6 header data (identifier & sequence) accordingly */
+	icmp6_header_data_m =
+		(rte_be_to_cpu_16(icmp6_m->echo.identifier) << 16) |
+		rte_be_to_cpu_16(icmp6_m->echo.sequence);
+	if (icmp6_header_data_m) {
+		icmp6_header_data_v =
+			(rte_be_to_cpu_16(icmp6_v->echo.identifier) << 16) |
+			rte_be_to_cpu_16(icmp6_v->echo.sequence);
+		MLX5_SET(fte_match_set_misc3, misc3_v, icmpv6_header_data,
+			 icmp6_header_data_v & icmp6_header_data_m);
+	}
+}
+
 /**
  * Add ICMP item to the value.
  *
@@ -12804,6 +12874,12 @@ flow_dv_translate_items(struct rte_eth_dev *dev,
 		wks->priority = MLX5_PRIORITY_MAP_L4;
 		last_item = MLX5_FLOW_LAYER_ICMP6;
 		break;
+	case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST:
+	case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY:
+		flow_dv_translate_item_icmp6_echo(key, items, tunnel, key_type);
+		wks->priority = MLX5_PRIORITY_MAP_L4;
+		last_item = MLX5_FLOW_LAYER_ICMP6;
+		break;
 	case RTE_FLOW_ITEM_TYPE_TAG:
 		flow_dv_translate_item_tag(dev, key, items, key_type);
 		last_item = MLX5_FLOW_ITEM_TAG;
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 8d59e73581..f9ad862707 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -4765,6 +4765,8 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
 		case RTE_FLOW_ITEM_TYPE_GRE_OPTION:
 		case RTE_FLOW_ITEM_TYPE_ICMP:
 		case RTE_FLOW_ITEM_TYPE_ICMP6:
+		case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST:
+		case RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY:
 		case RTE_FLOW_ITEM_TYPE_CONNTRACK:
 		case RTE_FLOW_ITEM_TYPE_QUOTA:
 			break;
-- 
2.27.0


  parent reply	other threads:[~2022-12-12  9:01 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-12  8:59 [PATCH 0/3] support match icmpv6 id and sequence Leo Xu
2022-12-12  8:59 ` [PATCH 1/3] ethdev: add ICMPv6 " Leo Xu
2022-12-12  8:59 ` Leo Xu [this message]
2022-12-12  8:59 ` [PATCH 3/3] net/mlx5/hws: add ICMPv6 id and sequence match support Leo Xu
2022-12-20  7:44 ` [PATCH v2 0/3] support match icmpv6 ID and sequence Leo Xu
2022-12-20  7:44   ` [PATCH v2 1/3] ethdev: add ICMPv6 " Leo Xu
2023-01-03  8:17     ` Ori Kam
2023-01-18  9:30     ` Thomas Monjalon
2023-01-31  6:53       ` Leo Xu (Networking SW)
2023-02-01  9:56         ` Thomas Monjalon
2023-02-02 18:33           ` Leo Xu (Networking SW)
2023-02-02 21:23             ` Thomas Monjalon
2023-02-03  2:56               ` Leo Xu (Networking SW)
2023-01-26 10:45     ` Ferruh Yigit
2023-01-31  3:58       ` Leo Xu (Networking SW)
2022-12-20  7:44   ` [PATCH v2 2/3] net/mlx5: add ICMPv6 ID and sequence match support Leo Xu
2023-01-18  8:55     ` Thomas Monjalon
2023-01-31  6:57       ` Leo Xu (Networking SW)
2022-12-20  7:44   ` [PATCH v2 3/3] net/mlx5/hws: " Leo Xu
2023-01-18  8:58     ` Thomas Monjalon
2023-01-31  6:56       ` Leo Xu (Networking SW)
2023-01-26 10:47   ` [PATCH v2 0/3] support match icmpv6 ID and sequence Ferruh Yigit
2023-01-31  3:54     ` Leo Xu (Networking SW)
2023-02-05 13:41   ` [PATCH v3 " Leo Xu
2023-02-05 13:41     ` [PATCH v3 1/3] ethdev: add ICMPv6 " Leo Xu
2023-02-05 13:41     ` [PATCH v3 2/3] net/mlx5: add ICMPv6 ID and sequence match support Leo Xu
2023-02-07 13:48       ` Slava Ovsiienko
2023-02-05 13:41     ` [PATCH v3 3/3] net/mlx5/hws: " Leo Xu
2023-02-07 13:05       ` Alex Vesker
2023-02-07 13:49       ` Slava Ovsiienko
2023-02-09 13:04     ` [PATCH v3 0/3] support match icmpv6 ID and sequence Ferruh Yigit

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=20221212085923.2314350-3-yongquanx@nvidia.com \
    --to=yongquanx@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=matan@nvidia.com \
    --cc=shahafs@nvidia.com \
    --cc=viacheslavo@nvidia.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).