From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
To: dev@dpdk.org
Cc: Venkata Suresh Kumar P <venkata.suresh.kumar.p@intel.com>,
Churchill Khangar <churchill.khangar@intel.com>
Subject: [dpdk-dev] [PATCH 2/5] pipeline: improve table entry parsing
Date: Mon, 15 Feb 2021 16:21:48 +0000 [thread overview]
Message-ID: <20210215162151.5655-2-cristian.dumitrescu@intel.com> (raw)
In-Reply-To: <20210215162151.5655-1-cristian.dumitrescu@intel.com>
Improve the table entry parsing: better code structure, enable parsing
for the key field masks, allow comments and empty lines in the table
entry files.
Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Venkata Suresh Kumar P <venkata.suresh.kumar.p@intel.com>
Signed-off-by: Churchill Khangar <churchill.khangar@intel.com>
---
examples/pipeline/cli.c | 21 +++-
lib/librte_pipeline/rte_swx_ctl.c | 172 ++++++++++++++++++++----------
lib/librte_pipeline/rte_swx_ctl.h | 7 +-
3 files changed, 141 insertions(+), 59 deletions(-)
diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c
index e97e12060..30c2dd34d 100644
--- a/examples/pipeline/cli.c
+++ b/examples/pipeline/cli.c
@@ -881,14 +881,19 @@ cmd_pipeline_table_update(char **tokens,
if (file_add)
for (line_id = 1; ; line_id++) {
struct rte_swx_table_entry *entry;
+ int is_blank_or_comment;
if (fgets(line, 2048, file_add) == NULL)
break;
entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
table_name,
- line);
+ line,
+ &is_blank_or_comment);
if (!entry) {
+ if (is_blank_or_comment)
+ continue;
+
snprintf(out, out_size, MSG_FILE_ERR,
file_name_add, line_id);
goto error;
@@ -911,14 +916,19 @@ cmd_pipeline_table_update(char **tokens,
if (file_delete)
for (line_id = 1; ; line_id++) {
struct rte_swx_table_entry *entry;
+ int is_blank_or_comment;
if (fgets(line, 2048, file_delete) == NULL)
break;
entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
table_name,
- line);
+ line,
+ &is_blank_or_comment);
if (!entry) {
+ if (is_blank_or_comment)
+ continue;
+
snprintf(out, out_size, MSG_FILE_ERR,
file_name_delete, line_id);
goto error;
@@ -940,14 +950,19 @@ cmd_pipeline_table_update(char **tokens,
if (file_default)
for (line_id = 1; ; line_id++) {
struct rte_swx_table_entry *entry;
+ int is_blank_or_comment;
if (fgets(line, 2048, file_default) == NULL)
break;
entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
table_name,
- line);
+ line,
+ &is_blank_or_comment);
if (!entry) {
+ if (is_blank_or_comment)
+ continue;
+
snprintf(out, out_size, MSG_FILE_ERR,
file_name_default, line_id);
goto error;
diff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c
index 3dfbc4aec..480e34238 100644
--- a/lib/librte_pipeline/rte_swx_ctl.c
+++ b/lib/librte_pipeline/rte_swx_ctl.c
@@ -1333,19 +1333,32 @@ rte_swx_ctl_pipeline_abort(struct rte_swx_ctl_pipeline *ctl)
table_abort(ctl, i);
}
+static int
+token_is_comment(const char *token)
+{
+ if ((token[0] == '#') ||
+ (token[0] == ';') ||
+ ((token[0] == '/') && (token[1] == '/')))
+ return 1; /* TRUE. */
+
+ return 0; /* FALSE. */
+}
+
#define RTE_SWX_CTL_ENTRY_TOKENS_MAX 256
struct rte_swx_table_entry *
rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
const char *table_name,
- const char *string)
+ const char *string,
+ int *is_blank_or_comment)
{
- char *tokens[RTE_SWX_CTL_ENTRY_TOKENS_MAX];
+ char *token_array[RTE_SWX_CTL_ENTRY_TOKENS_MAX], **tokens;
struct table *table;
struct action *action;
struct rte_swx_table_entry *entry = NULL;
char *s0 = NULL, *s;
uint32_t n_tokens = 0, arg_offset = 0, i;
+ int blank_or_comment = 0;
/* Check input arguments. */
if (!ctl)
@@ -1375,37 +1388,66 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
char *token;
token = strtok_r(s, " \f\n\r\t\v", &s);
- if (!token)
+ if (!token || token_is_comment(token))
break;
if (n_tokens >= RTE_SWX_CTL_ENTRY_TOKENS_MAX)
goto error;
- tokens[n_tokens] = token;
+ token_array[n_tokens] = token;
n_tokens++;
}
- if ((n_tokens < 3 + table->info.n_match_fields) ||
- strcmp(tokens[0], "match") ||
- strcmp(tokens[1 + table->info.n_match_fields], "action"))
- goto error;
-
- action = action_find(ctl, tokens[2 + table->info.n_match_fields]);
- if (!action)
+ if (!n_tokens) {
+ blank_or_comment = 1;
goto error;
+ }
- if (n_tokens != 3 + table->info.n_match_fields +
- action->info.n_args * 2)
- goto error;
+ tokens = token_array;
/*
* Match.
*/
+ if (n_tokens && strcmp(tokens[0], "match"))
+ goto action;
+
+ if (n_tokens < 1 + table->info.n_match_fields)
+ goto error;
+
for (i = 0; i < table->info.n_match_fields; i++) {
struct rte_swx_ctl_table_match_field_info *mf = &table->mf[i];
- char *mf_val = tokens[1 + i];
- uint64_t val;
+ char *mf_val = tokens[1 + i], *mf_mask = NULL;
+ uint64_t val, mask = UINT64_MAX;
+ uint32_t offset = (mf->offset - table->mf[0].offset) / 8;
+
+ /*
+ * Mask.
+ */
+ mf_mask = strchr(mf_val, '/');
+ if (mf_mask) {
+ *mf_mask = 0;
+ mf_mask++;
+
+ /* Parse. */
+ mask = strtoull(mf_mask, &mf_mask, 0);
+ if (mf_mask[0])
+ goto error;
+
+ /* Endianness conversion. */
+ if (mf->is_header)
+ mask = field_hton(mask, mf->n_bits);
+ }
+
+ /* Copy to entry. */
+ if (entry->key_mask)
+ memcpy(&entry->key_mask[offset],
+ (uint8_t *)&mask,
+ mf->n_bits / 8);
+ /*
+ * Value.
+ */
+ /* Parse. */
val = strtoull(mf_val, &mf_val, 0);
if (mf_val[0])
goto error;
@@ -1414,17 +1456,32 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
if (mf->is_header)
val = field_hton(val, mf->n_bits);
- /* Copy key and key_mask to entry. */
- memcpy(&entry->key[(mf->offset - table->mf[0].offset) / 8],
+ /* Copy to entry. */
+ memcpy(&entry->key[offset],
(uint8_t *)&val,
mf->n_bits / 8);
-
- /* TBD Set entry->key_mask for wildcard and LPM tables. */
}
+ tokens += 1 + table->info.n_match_fields;
+ n_tokens -= 1 + table->info.n_match_fields;
+
/*
* Action.
*/
+action:
+ if (n_tokens && strcmp(tokens[0], "action"))
+ goto other;
+
+ if (n_tokens < 2)
+ goto error;
+
+ action = action_find(ctl, tokens[1]);
+ if (!action)
+ goto error;
+
+ if (n_tokens < 2 + action->info.n_args * 2)
+ goto error;
+
/* action_id. */
entry->action_id = action - ctl->actions;
@@ -1435,8 +1492,8 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
uint64_t val;
int is_nbo = 0;
- arg_name = tokens[3 + table->info.n_match_fields + i * 2];
- arg_val = tokens[3 + table->info.n_match_fields + i * 2 + 1];
+ arg_name = tokens[2 + i * 2];
+ arg_val = tokens[2 + i * 2 + 1];
if (strcmp(arg_name, arg->name) ||
(strlen(arg_val) < 4) ||
@@ -1467,15 +1524,50 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
arg_offset += arg->n_bits / 8;
}
+ tokens += 2 + action->info.n_args * 2;
+ n_tokens -= 2 + action->info.n_args * 2;
+
+other:
+ if (n_tokens)
+ goto error;
+
free(s0);
return entry;
error:
table_entry_free(entry);
free(s0);
+ if (is_blank_or_comment)
+ *is_blank_or_comment = blank_or_comment;
return NULL;
}
+static void
+table_entry_printf(FILE *f,
+ struct rte_swx_ctl_pipeline *ctl,
+ struct table *table,
+ struct rte_swx_table_entry *entry)
+{
+ struct action *action = &ctl->actions[entry->action_id];
+ uint32_t i;
+
+ fprintf(f, "match ");
+ for (i = 0; i < table->params.key_size; i++)
+ fprintf(f, "%02x", entry->key[i]);
+
+ if (entry->key_mask) {
+ fprintf(f, "/");
+ for (i = 0; i < table->params.key_size; i++)
+ fprintf(f, "%02x", entry->key_mask[i]);
+ }
+
+ fprintf(f, " action %s ", action->info.name);
+ for (i = 0; i < action->data_size; i++)
+ fprintf(f, "%02x", entry->action_data[i]);
+
+ fprintf(f, "\n");
+}
+
int
rte_swx_ctl_pipeline_table_fprintf(FILE *f,
struct rte_swx_ctl_pipeline *ctl,
@@ -1506,47 +1598,17 @@ rte_swx_ctl_pipeline_table_fprintf(FILE *f,
/* Table entries. */
TAILQ_FOREACH(entry, &table->entries, node) {
- struct action *action = &ctl->actions[entry->action_id];
-
- fprintf(f, "match ");
- for (i = 0; i < table->params.key_size; i++)
- fprintf(f, "%02x", entry->key[i]);
-
- fprintf(f, " action %s ", action->info.name);
- for (i = 0; i < action->data_size; i++)
- fprintf(f, "%02x", entry->action_data[i]);
-
- fprintf(f, "\n");
+ table_entry_printf(f, ctl, table, entry);
n_entries++;
}
TAILQ_FOREACH(entry, &table->pending_modify0, node) {
- struct action *action = &ctl->actions[entry->action_id];
-
- fprintf(f, "match ");
- for (i = 0; i < table->params.key_size; i++)
- fprintf(f, "%02x", entry->key[i]);
-
- fprintf(f, " action %s ", action->info.name);
- for (i = 0; i < action->data_size; i++)
- fprintf(f, "%02x", entry->action_data[i]);
-
- fprintf(f, "\n");
+ table_entry_printf(f, ctl, table, entry);
n_entries++;
}
TAILQ_FOREACH(entry, &table->pending_delete, node) {
- struct action *action = &ctl->actions[entry->action_id];
-
- fprintf(f, "match ");
- for (i = 0; i < table->params.key_size; i++)
- fprintf(f, "%02x", entry->key[i]);
-
- fprintf(f, " action %s ", action->info.name);
- for (i = 0; i < action->data_size; i++)
- fprintf(f, "%02x", entry->action_data[i]);
-
- fprintf(f, "\n");
+ table_entry_printf(f, ctl, table, entry);
n_entries++;
}
diff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h
index 32815b69e..530671db1 100644
--- a/lib/librte_pipeline/rte_swx_ctl.h
+++ b/lib/librte_pipeline/rte_swx_ctl.h
@@ -521,6 +521,10 @@ rte_swx_ctl_pipeline_abort(struct rte_swx_ctl_pipeline *ctl);
* Table name.
* @param[in] string
* String containing the table entry.
+ * @param[out] is_blank_or_comment
+ * On error, this argument provides an indication of whether *string* contains
+ * an invalid table entry (set to zero) or a blank or comment line that should
+ * typically be ignored (set to a non-zero value).
* @return
* 0 on success or the following error codes otherwise:
* -EINVAL: Invalid argument.
@@ -529,7 +533,8 @@ __rte_experimental
struct rte_swx_table_entry *
rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
const char *table_name,
- const char *string);
+ const char *string,
+ int *is_blank_or_comment);
/**
* Pipeline table print to file
--
2.17.1
next prev parent reply other threads:[~2021-02-15 16:22 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-15 16:21 [dpdk-dev] [PATCH 1/5] pipeline: improve table entry helpers Cristian Dumitrescu
2021-02-15 16:21 ` Cristian Dumitrescu [this message]
2021-02-15 16:21 ` [dpdk-dev] [PATCH 3/5] pipeline: support non-incremental table updates Cristian Dumitrescu
2021-02-15 16:21 ` [dpdk-dev] [PATCH 4/5] table: add table entry priority Cristian Dumitrescu
2021-02-15 16:21 ` [dpdk-dev] [PATCH 5/5] table: add wildcard match table type Cristian Dumitrescu
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=20210215162151.5655-2-cristian.dumitrescu@intel.com \
--to=cristian.dumitrescu@intel.com \
--cc=churchill.khangar@intel.com \
--cc=dev@dpdk.org \
--cc=venkata.suresh.kumar.p@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).