DPDK patches and discussions
 help / color / mirror / Atom feed
From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
To: dev@dpdk.org
Cc: Yogesh Jangra <yogesh.jangra@intel.com>
Subject: [PATCH] pipeline: support default action arguments
Date: Sat,  9 Apr 2022 00:20:18 +0100	[thread overview]
Message-ID: <20220408232018.83284-1-cristian.dumitrescu@intel.com> (raw)

Add support for default action arguments. Up to now, only default
actions with no arguments were accepted.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Yogesh Jangra <yogesh.jangra@intel.com>
---
 lib/pipeline/rte_swx_pipeline.c      | 200 +++++++++++++++++++++------
 lib/pipeline/rte_swx_pipeline.h      |  18 +--
 lib/pipeline/rte_swx_pipeline_spec.c |  14 +-
 3 files changed, 176 insertions(+), 56 deletions(-)

diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c
index 17da11c015..e1aee68225 100644
--- a/lib/pipeline/rte_swx_pipeline.c
+++ b/lib/pipeline/rte_swx_pipeline.c
@@ -7337,6 +7337,91 @@ action_arg_src_mov_count(struct action *a,
 	return n_users;
 }
 
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define field_ntoh(val, n_bits) (ntoh64((val) << (64 - n_bits)))
+#define field_hton(val, n_bits) (hton64((val) << (64 - n_bits)))
+#else
+#define field_ntoh(val, n_bits) (val)
+#define field_hton(val, n_bits) (val)
+#endif
+
+#define ACTION_ARGS_TOKENS_MAX 256
+
+static int
+action_args_parse(struct action *a, const char *args, uint8_t *data)
+{
+	char *tokens[ACTION_ARGS_TOKENS_MAX], *s0 = NULL, *s;
+	uint32_t n_tokens = 0, offset = 0, i;
+	int status = 0;
+
+	/* Checks. */
+	if (!a->st || !args || !args[0]) {
+		status = -EINVAL;
+		goto error;
+	}
+
+	/* Memory allocation. */
+	s0 = strdup(args);
+	if (!s0) {
+		status = -ENOMEM;
+		goto error;
+	}
+
+	/* Parse the string into tokens. */
+	for (s = s0; ; ) {
+		char *token;
+
+		token = strtok_r(s, " \f\n\r\t\v", &s);
+		if (!token)
+			break;
+
+		if (n_tokens >= RTE_DIM(tokens)) {
+			status = -EINVAL;
+			goto error;
+		}
+
+		tokens[n_tokens] = token;
+		n_tokens++;
+	}
+
+	/* More checks. */
+	if (n_tokens != a->st->n_fields * 2) {
+		status = -EINVAL;
+		goto error;
+	}
+
+	/* Process the action arguments. */
+	for (i = 0; i < a->st->n_fields; i++) {
+		struct field *f = &a->st->fields[i];
+		char *arg_name = tokens[i * 2];
+		char *arg_val = tokens[i * 2 + 1];
+		uint64_t val;
+
+		if (strcmp(arg_name, f->name)) {
+			status = -EINVAL;
+			goto error;
+		}
+
+		val = strtoull(arg_val, &arg_val, 0);
+		if (arg_val[0]) {
+			status = -EINVAL;
+			goto error;
+		}
+
+		/* Endianness conversion. */
+		if (a->args_endianness[i])
+			val = field_hton(val, f->n_bits);
+
+		/* Copy to entry. */
+		memcpy(&data[offset], (uint8_t *)&val, f->n_bits / 8);
+		offset += f->n_bits / 8;
+	}
+
+error:
+	free(s0);
+	return status;
+}
+
 /*
  * Table.
  */
@@ -7609,8 +7694,8 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
 	      EINVAL);
 
 	default_action = action_find(p, params->default_action_name);
-	CHECK((default_action->st && params->default_action_data) ||
-	      !params->default_action_data, EINVAL);
+	CHECK((default_action->st && params->default_action_args) || !params->default_action_args,
+	      EINVAL);
 
 	/* Table type checks. */
 	if (recommended_table_type_name)
@@ -7631,30 +7716,42 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
 
 	/* Memory allocation. */
 	t = calloc(1, sizeof(struct table));
-	if (!t)
-		goto nomem;
+	if (!t) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	t->fields = calloc(params->n_fields, sizeof(struct match_field));
-	if (!t->fields)
-		goto nomem;
+	if (!t->fields) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	t->actions = calloc(params->n_actions, sizeof(struct action *));
-	if (!t->actions)
-		goto nomem;
+	if (!t->actions) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	if (action_data_size_max) {
 		t->default_action_data = calloc(1, action_data_size_max);
-		if (!t->default_action_data)
-			goto nomem;
+		if (!t->default_action_data) {
+			status = -ENOMEM;
+			goto error;
+		}
 	}
 
 	t->action_is_for_table_entries = calloc(params->n_actions, sizeof(int));
-	if (!t->action_is_for_table_entries)
-		goto nomem;
+	if (!t->action_is_for_table_entries) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	t->action_is_for_default_entry = calloc(params->n_actions, sizeof(int));
-	if (!t->action_is_for_default_entry)
-		goto nomem;
+	if (!t->action_is_for_default_entry) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	/* Node initialization. */
 	strcpy(t->name, name);
@@ -7687,10 +7784,14 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
 		t->action_is_for_default_entry[i] = action_is_for_default_entry;
 	}
 	t->default_action = default_action;
-	if (default_action->st)
-		memcpy(t->default_action_data,
-		       params->default_action_data,
-		       default_action->st->n_bits / 8);
+	if (default_action->st) {
+		status = action_args_parse(default_action,
+					   params->default_action_args,
+					   t->default_action_data);
+		if (status)
+			goto error;
+	}
+
 	t->n_actions = params->n_actions;
 	t->default_action_is_const = params->default_action_is_const;
 	t->action_data_size_max = action_data_size_max;
@@ -7704,9 +7805,9 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
 
 	return 0;
 
-nomem:
+error:
 	if (!t)
-		return -ENOMEM;
+		return status;
 
 	free(t->action_is_for_default_entry);
 	free(t->action_is_for_table_entries);
@@ -7715,7 +7816,7 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,
 	free(t->fields);
 	free(t);
 
-	return -ENOMEM;
+	return status;
 }
 
 static struct rte_swx_table_params *
@@ -8496,8 +8597,8 @@ rte_swx_pipeline_learner_config(struct rte_swx_pipeline *p,
 	      EINVAL);
 
 	default_action = action_find(p, params->default_action_name);
-	CHECK((default_action->st && params->default_action_data) ||
-	      !params->default_action_data, EINVAL);
+	CHECK((default_action->st && params->default_action_args) || !params->default_action_args,
+	      EINVAL);
 
 	/* Any other checks. */
 	CHECK(size, EINVAL);
@@ -8505,30 +8606,42 @@ rte_swx_pipeline_learner_config(struct rte_swx_pipeline *p,
 
 	/* Memory allocation. */
 	l = calloc(1, sizeof(struct learner));
-	if (!l)
-		goto nomem;
+	if (!l) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	l->fields = calloc(params->n_fields, sizeof(struct field *));
-	if (!l->fields)
-		goto nomem;
+	if (!l->fields) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	l->actions = calloc(params->n_actions, sizeof(struct action *));
-	if (!l->actions)
-		goto nomem;
+	if (!l->actions) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	if (action_data_size_max) {
 		l->default_action_data = calloc(1, action_data_size_max);
-		if (!l->default_action_data)
-			goto nomem;
+		if (!l->default_action_data) {
+			status = -ENOMEM;
+			goto error;
+		}
 	}
 
 	l->action_is_for_table_entries = calloc(params->n_actions, sizeof(int));
-	if (!l->action_is_for_table_entries)
-		goto nomem;
+	if (!l->action_is_for_table_entries) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	l->action_is_for_default_entry = calloc(params->n_actions, sizeof(int));
-	if (!l->action_is_for_default_entry)
-		goto nomem;
+	if (!l->action_is_for_default_entry) {
+		status = -ENOMEM;
+		goto error;
+	}
 
 	/* Node initialization. */
 	strcpy(l->name, name);
@@ -8560,10 +8673,13 @@ rte_swx_pipeline_learner_config(struct rte_swx_pipeline *p,
 
 	l->default_action = default_action;
 
-	if (default_action->st)
-		memcpy(l->default_action_data,
-		       params->default_action_data,
-		       default_action->st->n_bits / 8);
+	if (default_action->st) {
+		status = action_args_parse(default_action,
+					   params->default_action_args,
+					   l->default_action_data);
+		if (status)
+			goto error;
+	}
 
 	l->n_actions = params->n_actions;
 
@@ -8583,9 +8699,9 @@ rte_swx_pipeline_learner_config(struct rte_swx_pipeline *p,
 
 	return 0;
 
-nomem:
+error:
 	if (!l)
-		return -ENOMEM;
+		return status;
 
 	free(l->action_is_for_default_entry);
 	free(l->action_is_for_table_entries);
@@ -8594,7 +8710,7 @@ rte_swx_pipeline_learner_config(struct rte_swx_pipeline *p,
 	free(l->fields);
 	free(l);
 
-	return -ENOMEM;
+	return status;
 }
 
 static void
diff --git a/lib/pipeline/rte_swx_pipeline.h b/lib/pipeline/rte_swx_pipeline.h
index 1cfd1c542f..c95d0c7682 100644
--- a/lib/pipeline/rte_swx_pipeline.h
+++ b/lib/pipeline/rte_swx_pipeline.h
@@ -619,11 +619,12 @@ struct rte_swx_pipeline_table_params {
 	 */
 	const char *default_action_name;
 
-	/** Default action data. The size of this array is the action data size
-	 * of the default action. Must be NULL if the default action data size
-	 * is zero.
+	/** Default action arguments. Specified as a string with the format
+	 * "ARG0_NAME ARG0_VALUE ...". The number of arguments in this string
+	 * must match exactly the number of arguments of the default action.
+	 * Must be NULL if the default action does not have any arguments.
 	 */
-	uint8_t *default_action_data;
+	const char *default_action_args;
 
 	/** If non-zero (true), then the default action of the current table
 	 * cannot be changed. If zero (false), then the default action can be
@@ -758,11 +759,12 @@ struct rte_swx_pipeline_learner_params {
 	 */
 	const char *default_action_name;
 
-	/** Default action data. The size of this array is the action data size
-	 * of the default action. Must be NULL if the default action data size
-	 * is zero.
+	/** Default action arguments. Specified as a string with the format
+	 * "ARG0_NAME ARG0_VALUE ...". The number of arguments in this string
+	 * must match exactly the number of arguments of the default action.
+	 * Must be NULL if the default action does not have any arguments.
 	 */
-	uint8_t *default_action_data;
+	const char *default_action_args;
 
 	/** If non-zero (true), then the default action of the current table
 	 * cannot be changed. If zero (false), then the default action can be
diff --git a/lib/pipeline/rte_swx_pipeline_spec.c b/lib/pipeline/rte_swx_pipeline_spec.c
index 8165a046ea..3606a26b96 100644
--- a/lib/pipeline/rte_swx_pipeline_spec.c
+++ b/lib/pipeline/rte_swx_pipeline_spec.c
@@ -558,7 +558,7 @@ struct table_spec {
 static void
 table_spec_free(struct table_spec *s)
 {
-	uintptr_t default_action_name;
+	uintptr_t default_action_name, default_action_args;
 	uint32_t i;
 
 	if (!s)
@@ -593,8 +593,9 @@ table_spec_free(struct table_spec *s)
 	free((void *)default_action_name);
 	s->params.default_action_name = NULL;
 
-	free(s->params.default_action_data);
-	s->params.default_action_data = NULL;
+	default_action_args = (uintptr_t)s->params.default_action_args;
+	free((void *)default_action_args);
+	s->params.default_action_args = NULL;
 
 	free(s->params.action_is_for_table_entries);
 	s->params.action_is_for_table_entries = NULL;
@@ -1339,7 +1340,7 @@ struct learner_spec {
 static void
 learner_spec_free(struct learner_spec *s)
 {
-	uintptr_t default_action_name;
+	uintptr_t default_action_name, default_action_args;
 	uint32_t i;
 
 	if (!s)
@@ -1374,8 +1375,9 @@ learner_spec_free(struct learner_spec *s)
 	free((void *)default_action_name);
 	s->params.default_action_name = NULL;
 
-	free(s->params.default_action_data);
-	s->params.default_action_data = NULL;
+	default_action_args = (uintptr_t)s->params.default_action_args;
+	free((void *)default_action_args);
+	s->params.default_action_args = NULL;
 
 	free(s->params.action_is_for_table_entries);
 	s->params.action_is_for_table_entries = NULL;
-- 
2.17.1


             reply	other threads:[~2022-04-08 23:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-08 23:20 Cristian Dumitrescu [this message]
2022-04-09 11:21 ` [PATCH V2] " Cristian Dumitrescu
2022-04-09 12:19   ` [PATCH V3] " Cristian Dumitrescu
2022-04-11 18:21     ` [PATCH V4] " Cristian Dumitrescu
2022-06-01 12:01       ` Thomas Monjalon

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=20220408232018.83284-1-cristian.dumitrescu@intel.com \
    --to=cristian.dumitrescu@intel.com \
    --cc=dev@dpdk.org \
    --cc=yogesh.jangra@intel.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).