From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C464FA00C4; Sat, 9 Apr 2022 01:20:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 663B740041; Sat, 9 Apr 2022 01:20:23 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 858F04003F for ; Sat, 9 Apr 2022 01:20:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649460021; x=1680996021; h=from:to:cc:subject:date:message-id; bh=gNQSNqOFk9bjwCGdl5riT4b1rTP/6uMSZjdjD432npg=; b=C4EZLzpWGB1pnaSXQP8D+BXJe6upETWW3wpAjpYgYgppBOlav6cKnThQ 5UneSxJ6BC0EsM29qzkdqu9EiS/gwaFzSHOCsceZbGh2a3NoEv019Ib0+ 2kxndX4mCIC0m0/s5J5LFWBiBffD73YSWIRSyilUty7cTIFvyuZavwKsT eIYGLjsrQCbTjkSaibIkFYG/OqOwKXrpyJuJrwBGo+fJ72j2FD0BWMPBS F4alZbqvJ1DvKbg4gSxAkQLjdUBYXoFlOt2NhUguJ756MJOT8XwQkIdaH xAhAQvrQphheUVHKX+SVBlAtCvig36UqRRDY2LbTfhUXdcspp/H2f1wJp g==; X-IronPort-AV: E=McAfee;i="6400,9594,10311"; a="286717497" X-IronPort-AV: E=Sophos;i="5.90,246,1643702400"; d="scan'208";a="286717497" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2022 16:20:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,246,1643702400"; d="scan'208";a="621838348" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by fmsmga004.fm.intel.com with ESMTP; 08 Apr 2022 16:20:19 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Yogesh Jangra Subject: [PATCH] pipeline: support default action arguments Date: Sat, 9 Apr 2022 00:20:18 +0100 Message-Id: <20220408232018.83284-1-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for default action arguments. Up to now, only default actions with no arguments were accepted. Signed-off-by: Cristian Dumitrescu Signed-off-by: Yogesh Jangra --- 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