[v1,22/38] net/mvpp2: flow: add support for RAW type
diff mbox series

Message ID 20201202101212.4717-23-lironh@marvell.com
State Changes Requested
Delegated to: Jerin Jacob
Headers show
Series
  • net/mvpp2: misc updates
Related show

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Liron Himi Dec. 2, 2020, 10:11 a.m. UTC
From: Liron Himi <lironh@marvell.com>

add support for RAW type and connect it to MUSDK UDF

Signed-off-by: Liron Himi <lironh@marvell.com>
Reviewed-by: Liron Himi <lironh@marvell.com>
---
 drivers/net/mvpp2/mrvl_ethdev.h |   1 +
 drivers/net/mvpp2/mrvl_flow.c   | 141 ++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)

Comments

Michael Shamis Dec. 23, 2020, 9:28 a.m. UTC | #1
Reviewed-by: Michael Shamis <michaelsh@marvell.com>

-----Original Message-----
From: dev <dev-bounces@dpdk.org> On Behalf Of lironh@marvell.com
Sent: Wednesday, December 2, 2020 12:12 PM
To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
Cc: dev@dpdk.org; Liron Himi <lironh@marvell.com>
Subject: [dpdk-dev] [PATCH v1 22/38] net/mvpp2: flow: add support for RAW type

From: Liron Himi <lironh@marvell.com>

add support for RAW type and connect it to MUSDK UDF

Signed-off-by: Liron Himi <lironh@marvell.com>
Reviewed-by: Liron Himi <lironh@marvell.com>
---
 drivers/net/mvpp2/mrvl_ethdev.h |   1 +
 drivers/net/mvpp2/mrvl_flow.c   | 141 ++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)

diff --git a/drivers/net/mvpp2/mrvl_ethdev.h b/drivers/net/mvpp2/mrvl_ethdev.h index e7f75067f..be5e5a51b 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.h
+++ b/drivers/net/mvpp2/mrvl_ethdev.h
@@ -92,6 +92,7 @@ struct rte_flow {
 	struct pp2_cls_tbl_rule rule;
 	struct pp2_cls_cos_desc cos;
 	struct pp2_cls_tbl_action action;
+	uint8_t next_udf_id;
 };
 
 struct mrvl_mtr_profile {
diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c index ffa47a12e..3c8052f06 100644
--- a/drivers/net/mvpp2/mrvl_flow.c
+++ b/drivers/net/mvpp2/mrvl_flow.c
@@ -1196,6 +1196,146 @@ mrvl_parse_udp(const struct rte_flow_item *item,
 	return -rte_errno;
 }
 
+static int
+mrvl_string_to_hex_values(const uint8_t *input_string,
+			  uint8_t *hex_key,
+			  uint8_t *length)
+{
+	char tmp_arr[3], tmp_string[MRVL_CLS_STR_SIZE_MAX], *string_iter;
+	int i;
+
+	strcpy(tmp_string, (const char *)input_string);
+	string_iter = tmp_string;
+
+	string_iter += 2; /* skip the '0x' */
+	*length = ((*length - 2) + 1) / 2;
+
+	for (i = 0; i < *length; i++) {
+		strncpy(tmp_arr, string_iter, 2);
+		tmp_arr[2] = '\0';
+		if (get_val_securely8(tmp_arr, 16,
+				      &hex_key[*length - 1 - i]) < 0)
+			return -1;
+		string_iter += 2;
+	}
+
+	return 0;
+}
+
+/**
+ * Parse raw flow item.
+ *
+ * @param item Pointer to the flow item.
+ * @param flow Pointer to the flow.
+ * @param error Pointer to the flow error.
+ * @returns 0 on success, negative value otherwise.
+ */
+static int
+mrvl_parse_raw(const struct rte_flow_item *item,
+	       struct rte_flow *flow,
+	       struct rte_flow_error *error)
+{
+	const struct rte_flow_item_raw *spec = NULL, *mask = NULL;
+	struct pp2_cls_rule_key_field *key_field;
+	struct mv_net_udf *udf_params;
+	uint8_t length;
+	int ret;
+
+	ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
+			      &rte_flow_item_raw_mask,
+			      sizeof(struct rte_flow_item_raw), error);
+	if (ret)
+		return ret;
+
+	if (!spec->pattern) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "pattern pointer MUST be given\n");
+		return -rte_errno;
+	}
+
+	/* Only hex string is supported; so, it must start with '0x' */
+	if (strncmp((const char *)spec->pattern, "0x", 2) != 0)  {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'pattern' string must start with '0x'\n");
+		return -rte_errno;
+	}
+
+	if (mask->pattern &&
+	    strncmp((const char *)mask->pattern, "0x", 2) != 0)  {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'mask-pattern' string must start with '0x'\n");
+		return -rte_errno;
+	}
+
+	if (mask->search && spec->search) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'search' option must be '0'\n");
+		return -rte_errno;
+	}
+
+	if (mask->offset && spec->offset != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'offset' option must be '0'\n");
+		return -rte_errno;
+	}
+
+	if (!mask->relative || !spec->relative) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'relative' option must be given and enabled\n");
+		return -rte_errno;
+	}
+
+	length = spec->length & mask->length;
+	if (!length) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'length' option must be given bigger than '0'\n");
+		return -rte_errno;
+	}
+
+	key_field = &flow->rule.fields[flow->rule.num_fields];
+	mrvl_alloc_key_mask(key_field);
+
+	/* pattern and length refer to string bytes. we need to convert it to
+	 * values.
+	 */
+	key_field->size = length;
+	ret = mrvl_string_to_hex_values(spec->pattern, key_field->key,
+					&key_field->size);
+	if (ret) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL,
+				   "can't convert pattern from string to hex\n");
+		return -rte_errno;
+	}
+	if (mask->pattern) {
+		ret = mrvl_string_to_hex_values(mask->pattern, key_field->mask,
+						&length);
+		if (ret) {
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+					   NULL,
+					   "can't convert mask-pattern from string to hex\n");
+			return -rte_errno;
+		}
+	} else {
+		rte_free(key_field->mask);
+		key_field->mask = NULL;
+	}
+
+	flow->table_key.proto_field[flow->rule.num_fields].proto =
+		MV_NET_UDF;
+	udf_params =
+		&flow->table_key.proto_field[flow->rule.num_fields].field.udf;
+	udf_params->id = flow->next_udf_id++;
+	udf_params->size = key_field->size;
+	flow->table_key.key_size += key_field->size;
+
+	flow->rule.num_fields += 1;
+
+	return 0;
+}
+
 /**
  * Structure used to map specific flow pattern to the pattern parse callback
  * which will iterate over each pattern item and extract relevant data.
@@ -1212,6 +1352,7 @@ static const struct {
 	{ RTE_FLOW_ITEM_TYPE_IPV6, mrvl_parse_ip6 },
 	{ RTE_FLOW_ITEM_TYPE_TCP, mrvl_parse_tcp },
 	{ RTE_FLOW_ITEM_TYPE_UDP, mrvl_parse_udp },
+	{ RTE_FLOW_ITEM_TYPE_RAW, mrvl_parse_raw },
 	{ RTE_FLOW_ITEM_TYPE_END, NULL }
 };
 
--
2.28.0
Jerin Jacob Jan. 11, 2021, 4:18 p.m. UTC | #2
On Wed, Dec 23, 2020 at 2:58 PM Michael Shamis <michaelsh@marvell.com> wrote:
>
> Reviewed-by: Michael Shamis <michaelsh@marvell.com>
>
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of lironh@marvell.com
> Sent: Wednesday, December 2, 2020 12:12 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Cc: dev@dpdk.org; Liron Himi <lironh@marvell.com>
> Subject: [dpdk-dev] [PATCH v1 22/38] net/mvpp2: flow: add support for RAW type
>
> From: Liron Himi <lironh@marvell.com>
>
> add support for RAW type and connect it to MUSDK UDF
>
> Signed-off-by: Liron Himi <lironh@marvell.com>
> Reviewed-by: Liron Himi <lironh@marvell.com>
> ---
>  drivers/net/mvpp2/mrvl_ethdev.h |   1 +
>  drivers/net/mvpp2/mrvl_flow.c   | 141 ++++++++++++++++++++++++++++++++
>  2 files changed, 142 insertions(+)
>
> diff --git a/drivers/net/mvpp2/mrvl_ethdev.h b/drivers/net/mvpp2/mrvl_ethdev.h index e7f75067f..be5e5a51b 100644
> --- a/drivers/net/mvpp2/mrvl_ethdev.h
> +++ b/drivers/net/mvpp2/mrvl_ethdev.h
> @@ -92,6 +92,7 @@ struct rte_flow {
>         struct pp2_cls_tbl_rule rule;
>         struct pp2_cls_cos_desc cos;
>         struct pp2_cls_tbl_action action;
> +       uint8_t next_udf_id;
>  };
>
>  struct mrvl_mtr_profile {
> diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c index ffa47a12e..3c8052f06 100644
> --- a/drivers/net/mvpp2/mrvl_flow.c
> +++ b/drivers/net/mvpp2/mrvl_flow.c
> @@ -1196,6 +1196,146 @@ mrvl_parse_udp(const struct rte_flow_item *item,
>         return -rte_errno;
>  }
>
> +static int
> +mrvl_string_to_hex_values(const uint8_t *input_string,
> +                         uint8_t *hex_key,
> +                         uint8_t *length)
> +{
> +       char tmp_arr[3], tmp_string[MRVL_CLS_STR_SIZE_MAX], *string_iter;
> +       int i;
> +
> +       strcpy(tmp_string, (const char *)input_string);
> +       string_iter = tmp_string;
> +
> +       string_iter += 2; /* skip the '0x' */
> +       *length = ((*length - 2) + 1) / 2;
> +
> +       for (i = 0; i < *length; i++) {
> +               strncpy(tmp_arr, string_iter, 2);
> +               tmp_arr[2] = '\0';
> +               if (get_val_securely8(tmp_arr, 16,
> +                                     &hex_key[*length - 1 - i]) < 0)
> +                       return -1;
> +               string_iter += 2;
> +       }
> +
> +       return 0;
> +}

Is standard strtol()  not enough?
Liron Himi Jan. 19, 2021, 10:44 a.m. UTC | #3
-----Original Message-----
From: Jerin Jacob <jerinjacobk@gmail.com> 
Sent: Monday, 11 January 2021 18:18
To: Michael Shamis <michaelsh@marvell.com>
Cc: Liron Himi <lironh@marvell.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; dev@dpdk.org
Subject: [EXT] Re: [dpdk-dev] [PATCH v1 22/38] net/mvpp2: flow: add support for RAW type

External Email

----------------------------------------------------------------------
On Wed, Dec 23, 2020 at 2:58 PM Michael Shamis <michaelsh@marvell.com> wrote:
>
> Reviewed-by: Michael Shamis <michaelsh@marvell.com>
>
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of lironh@marvell.com
> Sent: Wednesday, December 2, 2020 12:12 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> Cc: dev@dpdk.org; Liron Himi <lironh@marvell.com>
> Subject: [dpdk-dev] [PATCH v1 22/38] net/mvpp2: flow: add support for 
> RAW type
>
> From: Liron Himi <lironh@marvell.com>
>
> add support for RAW type and connect it to MUSDK UDF
>
> Signed-off-by: Liron Himi <lironh@marvell.com>
> Reviewed-by: Liron Himi <lironh@marvell.com>
> ---
>  drivers/net/mvpp2/mrvl_ethdev.h |   1 +
>  drivers/net/mvpp2/mrvl_flow.c   | 141 ++++++++++++++++++++++++++++++++
>  2 files changed, 142 insertions(+)
>
> diff --git a/drivers/net/mvpp2/mrvl_ethdev.h 
> b/drivers/net/mvpp2/mrvl_ethdev.h index e7f75067f..be5e5a51b 100644
> --- a/drivers/net/mvpp2/mrvl_ethdev.h
> +++ b/drivers/net/mvpp2/mrvl_ethdev.h
> @@ -92,6 +92,7 @@ struct rte_flow {
>         struct pp2_cls_tbl_rule rule;
>         struct pp2_cls_cos_desc cos;
>         struct pp2_cls_tbl_action action;
> +       uint8_t next_udf_id;
>  };
>
>  struct mrvl_mtr_profile {
> diff --git a/drivers/net/mvpp2/mrvl_flow.c 
> b/drivers/net/mvpp2/mrvl_flow.c index ffa47a12e..3c8052f06 100644
> --- a/drivers/net/mvpp2/mrvl_flow.c
> +++ b/drivers/net/mvpp2/mrvl_flow.c
> @@ -1196,6 +1196,146 @@ mrvl_parse_udp(const struct rte_flow_item *item,
>         return -rte_errno;
>  }
>
> +static int
> +mrvl_string_to_hex_values(const uint8_t *input_string,
> +                         uint8_t *hex_key,
> +                         uint8_t *length) {
> +       char tmp_arr[3], tmp_string[MRVL_CLS_STR_SIZE_MAX], *string_iter;
> +       int i;
> +
> +       strcpy(tmp_string, (const char *)input_string);
> +       string_iter = tmp_string;
> +
> +       string_iter += 2; /* skip the '0x' */
> +       *length = ((*length - 2) + 1) / 2;
> +
> +       for (i = 0; i < *length; i++) {
> +               strncpy(tmp_arr, string_iter, 2);
> +               tmp_arr[2] = '\0';
> +               if (get_val_securely8(tmp_arr, 16,
> +                                     &hex_key[*length - 1 - i]) < 0)
> +                       return -1;
> +               string_iter += 2;
> +       }
> +
> +       return 0;
> +}

Is standard strtol()  not enough?
[L.H.] I have just checked it and strtol is working only when up to 64bit numbers.
i.e. if given string is "0xaabbccddaabbccdd" it is working, but not "0xaabbccddaabbccdd11".

Patch
diff mbox series

diff --git a/drivers/net/mvpp2/mrvl_ethdev.h b/drivers/net/mvpp2/mrvl_ethdev.h
index e7f75067f..be5e5a51b 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.h
+++ b/drivers/net/mvpp2/mrvl_ethdev.h
@@ -92,6 +92,7 @@  struct rte_flow {
 	struct pp2_cls_tbl_rule rule;
 	struct pp2_cls_cos_desc cos;
 	struct pp2_cls_tbl_action action;
+	uint8_t next_udf_id;
 };
 
 struct mrvl_mtr_profile {
diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
index ffa47a12e..3c8052f06 100644
--- a/drivers/net/mvpp2/mrvl_flow.c
+++ b/drivers/net/mvpp2/mrvl_flow.c
@@ -1196,6 +1196,146 @@  mrvl_parse_udp(const struct rte_flow_item *item,
 	return -rte_errno;
 }
 
+static int
+mrvl_string_to_hex_values(const uint8_t *input_string,
+			  uint8_t *hex_key,
+			  uint8_t *length)
+{
+	char tmp_arr[3], tmp_string[MRVL_CLS_STR_SIZE_MAX], *string_iter;
+	int i;
+
+	strcpy(tmp_string, (const char *)input_string);
+	string_iter = tmp_string;
+
+	string_iter += 2; /* skip the '0x' */
+	*length = ((*length - 2) + 1) / 2;
+
+	for (i = 0; i < *length; i++) {
+		strncpy(tmp_arr, string_iter, 2);
+		tmp_arr[2] = '\0';
+		if (get_val_securely8(tmp_arr, 16,
+				      &hex_key[*length - 1 - i]) < 0)
+			return -1;
+		string_iter += 2;
+	}
+
+	return 0;
+}
+
+/**
+ * Parse raw flow item.
+ *
+ * @param item Pointer to the flow item.
+ * @param flow Pointer to the flow.
+ * @param error Pointer to the flow error.
+ * @returns 0 on success, negative value otherwise.
+ */
+static int
+mrvl_parse_raw(const struct rte_flow_item *item,
+	       struct rte_flow *flow,
+	       struct rte_flow_error *error)
+{
+	const struct rte_flow_item_raw *spec = NULL, *mask = NULL;
+	struct pp2_cls_rule_key_field *key_field;
+	struct mv_net_udf *udf_params;
+	uint8_t length;
+	int ret;
+
+	ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
+			      &rte_flow_item_raw_mask,
+			      sizeof(struct rte_flow_item_raw), error);
+	if (ret)
+		return ret;
+
+	if (!spec->pattern) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "pattern pointer MUST be given\n");
+		return -rte_errno;
+	}
+
+	/* Only hex string is supported; so, it must start with '0x' */
+	if (strncmp((const char *)spec->pattern, "0x", 2) != 0)  {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'pattern' string must start with '0x'\n");
+		return -rte_errno;
+	}
+
+	if (mask->pattern &&
+	    strncmp((const char *)mask->pattern, "0x", 2) != 0)  {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'mask-pattern' string must start with '0x'\n");
+		return -rte_errno;
+	}
+
+	if (mask->search && spec->search) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'search' option must be '0'\n");
+		return -rte_errno;
+	}
+
+	if (mask->offset && spec->offset != 0) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'offset' option must be '0'\n");
+		return -rte_errno;
+	}
+
+	if (!mask->relative || !spec->relative) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'relative' option must be given and enabled\n");
+		return -rte_errno;
+	}
+
+	length = spec->length & mask->length;
+	if (!length) {
+		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL, "'length' option must be given bigger than '0'\n");
+		return -rte_errno;
+	}
+
+	key_field = &flow->rule.fields[flow->rule.num_fields];
+	mrvl_alloc_key_mask(key_field);
+
+	/* pattern and length refer to string bytes. we need to convert it to
+	 * values.
+	 */
+	key_field->size = length;
+	ret = mrvl_string_to_hex_values(spec->pattern, key_field->key,
+					&key_field->size);
+	if (ret) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+				   NULL,
+				   "can't convert pattern from string to hex\n");
+		return -rte_errno;
+	}
+	if (mask->pattern) {
+		ret = mrvl_string_to_hex_values(mask->pattern, key_field->mask,
+						&length);
+		if (ret) {
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+					   NULL,
+					   "can't convert mask-pattern from string to hex\n");
+			return -rte_errno;
+		}
+	} else {
+		rte_free(key_field->mask);
+		key_field->mask = NULL;
+	}
+
+	flow->table_key.proto_field[flow->rule.num_fields].proto =
+		MV_NET_UDF;
+	udf_params =
+		&flow->table_key.proto_field[flow->rule.num_fields].field.udf;
+	udf_params->id = flow->next_udf_id++;
+	udf_params->size = key_field->size;
+	flow->table_key.key_size += key_field->size;
+
+	flow->rule.num_fields += 1;
+
+	return 0;
+}
+
 /**
  * Structure used to map specific flow pattern to the pattern parse callback
  * which will iterate over each pattern item and extract relevant data.
@@ -1212,6 +1352,7 @@  static const struct {
 	{ RTE_FLOW_ITEM_TYPE_IPV6, mrvl_parse_ip6 },
 	{ RTE_FLOW_ITEM_TYPE_TCP, mrvl_parse_tcp },
 	{ RTE_FLOW_ITEM_TYPE_UDP, mrvl_parse_udp },
+	{ RTE_FLOW_ITEM_TYPE_RAW, mrvl_parse_raw },
 	{ RTE_FLOW_ITEM_TYPE_END, NULL }
 };