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
next 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).