DPDK patches and discussions
 help / color / mirror / Atom feed
From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
To: dev@dpdk.org
Subject: [PATCH 6/7] examples/pipeline: add CLI commands for direct registers
Date: Fri, 26 Aug 2022 10:36:04 +0000	[thread overview]
Message-ID: <20220826103605.1579589-7-cristian.dumitrescu@intel.com> (raw)
In-Reply-To: <20220826103605.1579589-1-cristian.dumitrescu@intel.com>

Add the CLI command support for reading/writing direct registers.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/pipeline/cli.c | 228 +++++++++++++++++++++++++++++++++-------
 1 file changed, 192 insertions(+), 36 deletions(-)

diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c
index 2e69698031..72998f580b 100644
--- a/examples/pipeline/cli.c
+++ b/examples/pipeline/cli.c
@@ -142,6 +142,54 @@ is_comment(char *in)
 	return 0;
 }
 
+static void
+table_entry_free(struct rte_swx_table_entry *entry)
+{
+	if (!entry)
+		return;
+
+	free(entry->key);
+	free(entry->key_mask);
+	free(entry->action_data);
+	free(entry);
+}
+
+static struct rte_swx_table_entry *
+parse_table_entry(struct rte_swx_ctl_pipeline *p,
+		  char *table_name,
+		  char **tokens,
+		  uint32_t n_tokens)
+{
+	struct rte_swx_table_entry *entry;
+	char *line;
+	uint32_t i;
+
+	/* Buffer allocation. */
+	line = malloc(MAX_LINE_SIZE);
+	if (!line)
+		return NULL;
+
+	/* Copy tokens to buffer. Since the tokens were initially part of a buffer of size
+	 * MAX_LINE_LENGTH, it is guaranteed that putting back some of them into a buffer of the
+	 * same size separated by a single space will not result in buffer overrun.
+	 */
+	line[0] = 0;
+	for (i = 0; i < n_tokens; i++) {
+		if (i)
+			strcat(line, " ");
+
+		strcat(line, tokens[i]);
+	}
+
+	/* Read the table entry from the input buffer. */
+	entry = rte_swx_ctl_pipeline_table_entry_read(p, table_name, line, NULL);
+
+	/* Buffer free. */
+	free(line);
+
+	return entry;
+}
+
 static const char cmd_mempool_help[] =
 "mempool <mempool_name>\n"
 "   buffer <buffer_size>\n"
@@ -732,18 +780,6 @@ cmd_pipeline_build(char **tokens,
 		fclose(iospec_file);
 }
 
-static void
-table_entry_free(struct rte_swx_table_entry *entry)
-{
-	if (!entry)
-		return;
-
-	free(entry->key);
-	free(entry->key_mask);
-	free(entry->action_data);
-	free(entry);
-}
-
 static int
 pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
 			   const char *table_name,
@@ -1710,7 +1746,9 @@ cmd_pipeline_abort(char **tokens,
 }
 
 static const char cmd_pipeline_regrd_help[] =
-"pipeline <pipeline_name> regrd <register_array_name> <index>\n";
+"pipeline <pipeline_name> regrd <register_array_name>"
+	"index <index>"
+	" | table <table_name> match <field0> ...\n";
 
 static void
 cmd_pipeline_regrd(char **tokens,
@@ -1720,18 +1758,20 @@ cmd_pipeline_regrd(char **tokens,
 	void *obj __rte_unused)
 {
 	struct rte_swx_pipeline *p;
-	const char *name;
+	struct rte_swx_ctl_pipeline *ctl;
+	const char *pipeline_name, *name;
 	uint64_t value;
-	uint32_t idx;
 	int status;
 
-	if (n_tokens != 5) {
+	if (n_tokens < 5) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
 	}
 
-	p = rte_swx_pipeline_find(tokens[1]);
-	if (!p) {
+	pipeline_name = tokens[1];
+	p = rte_swx_pipeline_find(pipeline_name);
+	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
+	if (!p || !ctl) {
 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
 		return;
 	}
@@ -1743,22 +1783,77 @@ cmd_pipeline_regrd(char **tokens,
 
 	name = tokens[3];
 
-	if (parser_read_uint32(&idx, tokens[4])) {
-		snprintf(out, out_size, MSG_ARG_INVALID, "index");
+	/* index. */
+	if (!strcmp(tokens[4], "index")) {
+		uint32_t idx;
+
+		if (n_tokens != 6) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+			return;
+		}
+
+		if (parser_read_uint32(&idx, tokens[5])) {
+			snprintf(out, out_size, MSG_ARG_INVALID, "index");
+			return;
+		}
+
+		status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
+		if (status) {
+			snprintf(out, out_size, "Command failed.\n");
+			return;
+		}
+
+		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
 		return;
 	}
 
-	status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
-	if (status) {
-		snprintf(out, out_size, "Command failed.\n");
+	/* table. */
+	if (!strcmp(tokens[4], "table")) {
+		struct rte_swx_table_entry *entry;
+		char *table_name;
+
+		if (n_tokens < 8) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+			return;
+		}
+
+		table_name = tokens[5];
+
+		if (strcmp(tokens[6], "match")) {
+			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
+			return;
+		}
+
+		entry = parse_table_entry(ctl, table_name, &tokens[6], n_tokens - 6);
+		if (!entry) {
+			snprintf(out, out_size, "Invalid match tokens.\n");
+			return;
+		}
+
+		status = rte_swx_ctl_pipeline_regarray_read_with_key(p,
+								     name,
+								     table_name,
+								     entry->key,
+								     &value);
+		table_entry_free(entry);
+		if (status) {
+			snprintf(out, out_size, "Command failed.\n");
+			return;
+		}
+
+		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
 		return;
 	}
 
-	snprintf(out, out_size, "0x%" PRIx64 "\n", value);
+	/* anything else. */
+	snprintf(out, out_size, "Invalid token %s\n.", tokens[4]);
+	return;
 }
 
 static const char cmd_pipeline_regwr_help[] =
-"pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
+"pipeline <pipeline_name> regwr <register_array_name> value <value>"
+	"index <index>"
+	" | table <table_name> match <field0> ...\n";
 
 static void
 cmd_pipeline_regwr(char **tokens,
@@ -1768,18 +1863,20 @@ cmd_pipeline_regwr(char **tokens,
 	void *obj __rte_unused)
 {
 	struct rte_swx_pipeline *p;
-	const char *name;
-	uint64_t value;
-	uint32_t idx;
+	struct rte_swx_ctl_pipeline *ctl;
+	const char *pipeline_name, *name;
+	uint64_t value = 0;
 	int status;
 
-	if (n_tokens != 6) {
+	if (n_tokens < 7) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
 	}
 
-	p = rte_swx_pipeline_find(tokens[1]);
-	if (!p) {
+	pipeline_name = tokens[1];
+	p = rte_swx_pipeline_find(pipeline_name);
+	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
+	if (!p || !ctl) {
 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
 		return;
 	}
@@ -1791,8 +1888,8 @@ cmd_pipeline_regwr(char **tokens,
 
 	name = tokens[3];
 
-	if (parser_read_uint32(&idx, tokens[4])) {
-		snprintf(out, out_size, MSG_ARG_INVALID, "index");
+	if (strcmp(tokens[4], "value")) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "value");
 		return;
 	}
 
@@ -1801,11 +1898,70 @@ cmd_pipeline_regwr(char **tokens,
 		return;
 	}
 
-	status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
-	if (status) {
-		snprintf(out, out_size, "Command failed.\n");
+	/* index. */
+	if (!strcmp(tokens[6], "index")) {
+		uint32_t idx;
+
+		if (n_tokens != 8) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+			return;
+		}
+
+		if (parser_read_uint32(&idx, tokens[7])) {
+			snprintf(out, out_size, MSG_ARG_INVALID, "index");
+			return;
+		}
+
+		status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
+		if (status) {
+			snprintf(out, out_size, "Command failed.\n");
+			return;
+		}
+
+		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
 		return;
 	}
+
+	/* table. */
+	if (!strcmp(tokens[6], "table")) {
+		struct rte_swx_table_entry *entry;
+		char *table_name;
+
+		if (n_tokens < 10) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+			return;
+		}
+
+		table_name = tokens[7];
+
+		if (strcmp(tokens[8], "match")) {
+			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
+			return;
+		}
+
+		entry = parse_table_entry(ctl, table_name, &tokens[8], n_tokens - 8);
+		if (!entry) {
+			snprintf(out, out_size, "Invalid match tokens.\n");
+			return;
+		}
+
+		status = rte_swx_ctl_pipeline_regarray_write_with_key(p,
+								      name,
+								      table_name,
+								      entry->key,
+								      value);
+		table_entry_free(entry);
+		if (status) {
+			snprintf(out, out_size, "Command failed.\n");
+			return;
+		}
+
+		return;
+	}
+
+	/* anything else. */
+	snprintf(out, out_size, "Invalid token %s\n.", tokens[6]);
+	return;
 }
 
 static const char cmd_pipeline_meter_profile_add_help[] =
-- 
2.34.1


  parent reply	other threads:[~2022-08-26 10:36 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-26 10:35 [PATCH 0/7] pipeline: support direct registers and meters Cristian Dumitrescu
2022-08-26 10:35 ` [PATCH 1/7] table: add entry ID for regular tables Cristian Dumitrescu
2022-08-26 10:36 ` [PATCH 2/7] table: add entry ID for learner tables Cristian Dumitrescu
2022-08-26 10:36 ` [PATCH 3/7] pipeline: add table entry ID read instruction Cristian Dumitrescu
2022-08-26 10:36 ` [PATCH 4/7] pipeline: support direct registers on the control path Cristian Dumitrescu
2022-08-26 10:36 ` [PATCH 5/7] pipeline: support direct meters " Cristian Dumitrescu
2022-08-26 10:36 ` Cristian Dumitrescu [this message]
2022-08-26 10:36 ` [PATCH 7/7] examples/pipeline: add CLI commands for direct meters Cristian Dumitrescu
2022-08-26 11:21 ` [PATCH V2 0/7] pipeline: support direct registers and meters Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 1/7] table: add entry ID for regular tables Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 2/7] table: add entry ID for learner tables Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 3/7] pipeline: add table entry ID read instruction Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 4/7] pipeline: support direct registers on the control path Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 5/7] pipeline: support direct meters " Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 6/7] examples/pipeline: add CLI commands for direct registers Cristian Dumitrescu
2022-08-26 11:21   ` [PATCH V2 7/7] examples/pipeline: add CLI commands for direct meters Cristian Dumitrescu
2022-08-30 18:58 ` [PATCH V3 0/7] pipeline: support direct registers and meters Cristian Dumitrescu
2022-08-30 18:58   ` [PATCH V3 1/7] table: add entry ID for regular tables Cristian Dumitrescu
2022-08-30 18:58   ` [PATCH V3 2/7] table: add entry ID for learner tables Cristian Dumitrescu
2022-09-24  8:25     ` Thomas Monjalon
2022-09-26  9:19       ` Dumitrescu, Cristian
2022-09-26 13:45         ` Thomas Monjalon
2022-08-30 18:58   ` [PATCH V3 3/7] pipeline: add table entry ID read instruction Cristian Dumitrescu
2022-08-30 18:58   ` [PATCH V3 4/7] pipeline: support direct registers on the control path Cristian Dumitrescu
2022-08-30 18:58   ` [PATCH V3 5/7] pipeline: support direct meters " Cristian Dumitrescu
2022-08-30 18:58   ` [PATCH V3 6/7] examples/pipeline: add CLI commands for direct registers Cristian Dumitrescu
2022-08-30 18:58   ` [PATCH V3 7/7] examples/pipeline: add CLI commands for direct meters Cristian Dumitrescu
2022-09-24  9:34   ` [PATCH V3 0/7] pipeline: support direct registers and meters 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=20220826103605.1579589-7-cristian.dumitrescu@intel.com \
    --to=cristian.dumitrescu@intel.com \
    --cc=dev@dpdk.org \
    /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).