From patchwork Fri Jul 2 20:49:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Dumitrescu X-Patchwork-Id: 95221 Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C86FEA0C3F; Fri, 2 Jul 2021 22:49:59 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8B3C241363; Fri, 2 Jul 2021 22:49:59 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mails.dpdk.org (Postfix) with ESMTP id EA38941353 for ; Fri, 2 Jul 2021 22:49:56 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10033"; a="294428751" X-IronPort-AV: E=Sophos;i="5.83,320,1616482800"; d="scan'208";a="294428751" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2021 13:49:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,320,1616482800"; d="scan'208";a="494257766" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by fmsmga002.fm.intel.com with ESMTP; 02 Jul 2021 13:49:53 -0700 From: Cristian Dumitrescu To: dev@dpdk.org Cc: Churchill Khangar Date: Fri, 2 Jul 2021 21:49:52 +0100 Message-Id: <20210702204952.61445-1-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-dev] [PATCH 1/5] examples/pipeline: improve table update CLI commands 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 Sender: "dev" From: Churchill Khangar For more felxibility, the single monolithic table update command is split into table entry add, table entry delete, table default entry add, pipeline commit and pipeline abort. Signed-off-by: Churchill Khangar Signed-off-by: Cristian Dumitrescu --- examples/pipeline/cli.c | 589 ++++++++++++++++------ examples/pipeline/examples/vxlan.cli | 3 +- examples/pipeline/examples/vxlan_pcap.cli | 3 +- 3 files changed, 428 insertions(+), 167 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 215dd8e85..30754e319 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -1038,25 +1038,76 @@ table_entry_free(struct rte_swx_table_entry *entry) free(entry); } -static const char cmd_pipeline_table_update_help[] = -"pipeline table update " -" "; +#ifndef MAX_LINE_SIZE +#define MAX_LINE_SIZE 2048 +#endif + +static int +pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p, + const char *table_name, + FILE *file, + uint32_t *file_line_number) +{ + char *line = NULL; + uint32_t line_id = 0; + int status = 0; + + /* Buffer allocation. */ + line = malloc(MAX_LINE_SIZE); + if (!line) + return -ENOMEM; + + /* File read. */ + for (line_id = 1; ; line_id++) { + struct rte_swx_table_entry *entry; + int is_blank_or_comment; + + if (fgets(line, MAX_LINE_SIZE, file) == NULL) + break; + + entry = rte_swx_ctl_pipeline_table_entry_read(p, + table_name, + line, + &is_blank_or_comment); + if (!entry) { + if (is_blank_or_comment) + continue; + + status = -EINVAL; + goto error; + } + + status = rte_swx_ctl_pipeline_table_entry_add(p, + table_name, + entry); + table_entry_free(entry); + if (status) + goto error; + } + +error: + free(line); + *file_line_number = line_id; + return status; +} + +static const char cmd_pipeline_table_add_help[] = +"pipeline table add \n"; static void -cmd_pipeline_table_update(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj) +cmd_pipeline_table_add(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) { struct pipeline *p; - char *pipeline_name, *table_name, *line = NULL; - char *file_name_add, *file_name_delete, *file_name_default; - FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL; - uint32_t line_id; + char *pipeline_name, *table_name, *file_name; + FILE *file = NULL; + uint32_t file_line_number = 0; int status; - if (n_tokens != 8) { + if (n_tokens != 6) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -1068,192 +1119,313 @@ cmd_pipeline_table_update(char **tokens, return; } - if (strcmp(tokens[2], "table") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table"); + table_name = tokens[3]; + + file_name = tokens[5]; + file = fopen(file_name, "r"); + if (!file) { + snprintf(out, out_size, "Cannot open file %s.\n", file_name); + return; + } + + status = pipeline_table_entries_add(p->ctl, + table_name, + file, + &file_line_number); + if (status) + snprintf(out, out_size, "Invalid entry in file %s at line %u\n", + file_name, + file_line_number); + + fclose(file); +} + +static int +pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p, + const char *table_name, + FILE *file, + uint32_t *file_line_number) +{ + char *line = NULL; + uint32_t line_id = 0; + int status = 0; + + /* Buffer allocation. */ + line = malloc(MAX_LINE_SIZE); + if (!line) + return -ENOMEM; + + /* File read. */ + for (line_id = 1; ; line_id++) { + struct rte_swx_table_entry *entry; + int is_blank_or_comment; + + if (fgets(line, MAX_LINE_SIZE, file) == NULL) + break; + + entry = rte_swx_ctl_pipeline_table_entry_read(p, + table_name, + line, + &is_blank_or_comment); + if (!entry) { + if (is_blank_or_comment) + continue; + + status = -EINVAL; + goto error; + } + + status = rte_swx_ctl_pipeline_table_entry_delete(p, + table_name, + entry); + table_entry_free(entry); + if (status) + goto error; + } + +error: + *file_line_number = line_id; + free(line); + return status; +} + +static const char cmd_pipeline_table_delete_help[] = +"pipeline table delete \n"; + +static void +cmd_pipeline_table_delete(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) +{ + struct pipeline *p; + char *pipeline_name, *table_name, *file_name; + FILE *file = NULL; + uint32_t file_line_number = 0; + int status; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + pipeline_name = tokens[1]; + p = pipeline_find(obj, pipeline_name); + if (!p || !p->ctl) { + snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); return; } table_name = tokens[3]; - if (strcmp(tokens[4], "update") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update"); + file_name = tokens[5]; + file = fopen(file_name, "r"); + if (!file) { + snprintf(out, out_size, "Cannot open file %s.\n", file_name); return; } - file_name_add = tokens[5]; - file_name_delete = tokens[6]; - file_name_default = tokens[7]; + status = pipeline_table_entries_delete(p->ctl, + table_name, + file, + &file_line_number); + if (status) + snprintf(out, out_size, "Invalid entry in file %s at line %u\n", + file_name, + file_line_number); + + fclose(file); +} + +static int +pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p, + const char *table_name, + FILE *file, + uint32_t *file_line_number) +{ + char *line = NULL; + uint32_t line_id = 0; + int status = 0; + + /* Buffer allocation. */ + line = malloc(MAX_LINE_SIZE); + if (!line) + return -ENOMEM; + + /* File read. */ + for (line_id = 1; ; line_id++) { + struct rte_swx_table_entry *entry; + int is_blank_or_comment; - /* File open. */ - if (strcmp(file_name_add, "none")) { - file_add = fopen(file_name_add, "r"); - if (!file_add) { - snprintf(out, out_size, "Cannot open file %s.\n", - file_name_add); + if (fgets(line, MAX_LINE_SIZE, file) == NULL) + break; + + entry = rte_swx_ctl_pipeline_table_entry_read(p, + table_name, + line, + &is_blank_or_comment); + if (!entry) { + if (is_blank_or_comment) + continue; + + status = -EINVAL; goto error; } - } - if (strcmp(file_name_delete, "none")) { - file_delete = fopen(file_name_delete, "r"); - if (!file_delete) { - snprintf(out, out_size, "Cannot open file %s.\n", - file_name_delete); + status = rte_swx_ctl_pipeline_table_default_entry_add(p, + table_name, + entry); + table_entry_free(entry); + if (status) goto error; - } } - if (strcmp(file_name_default, "none")) { - file_default = fopen(file_name_default, "r"); - if (!file_default) { - snprintf(out, out_size, "Cannot open file %s.\n", - file_name_default); - goto error; - } +error: + *file_line_number = line_id; + free(line); + return status; +} + +static const char cmd_pipeline_table_default_help[] = +"pipeline table default \n"; + +static void +cmd_pipeline_table_default(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) +{ + struct pipeline *p; + char *pipeline_name, *table_name, *file_name; + FILE *file = NULL; + uint32_t file_line_number = 0; + int status; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; } - if (!file_add && !file_delete && !file_default) { - snprintf(out, out_size, "Nothing to be done."); + pipeline_name = tokens[1]; + p = pipeline_find(obj, pipeline_name); + if (!p || !p->ctl) { + snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); return; } - /* Buffer allocation. */ - line = malloc(2048); - if (!line) { - snprintf(out, out_size, MSG_OUT_OF_MEMORY); - goto error; - } - - /* Add. */ - 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, - &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; - } + table_name = tokens[3]; - status = rte_swx_ctl_pipeline_table_entry_add(p->ctl, - table_name, - entry); - table_entry_free(entry); - if (status) { - snprintf(out, out_size, - "Invalid entry in file %s at line %u", - file_name_add, line_id); - goto error; - } - } + file_name = tokens[5]; + file = fopen(file_name, "r"); + if (!file) { + snprintf(out, out_size, "Cannot open file %s.\n", file_name); + return; + } + status = pipeline_table_default_entry_add(p->ctl, + table_name, + file, + &file_line_number); + if (status) + snprintf(out, out_size, "Invalid entry in file %s at line %u\n", + file_name, + file_line_number); - /* Delete. */ - if (file_delete) - for (line_id = 1; ; line_id++) { - struct rte_swx_table_entry *entry; - int is_blank_or_comment; + fclose(file); +} - if (fgets(line, 2048, file_delete) == NULL) - break; +static const char cmd_pipeline_table_show_help[] = +"pipeline table show\n"; - entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, - table_name, - line, - &is_blank_or_comment); - if (!entry) { - if (is_blank_or_comment) - continue; +static void +cmd_pipeline_table_show(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) +{ + struct pipeline *p; + char *pipeline_name, *table_name; + int status; - snprintf(out, out_size, MSG_FILE_ERR, - file_name_delete, line_id); - goto error; - } + if (n_tokens != 5) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } - status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl, - table_name, - entry); - table_entry_free(entry); - if (status) { - snprintf(out, out_size, - "Invalid entry in file %s at line %u", - file_name_delete, line_id); - goto error; - } - } + pipeline_name = tokens[1]; + p = pipeline_find(obj, pipeline_name); + if (!p || !p->ctl) { + snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); + return; + } - /* Default. */ - if (file_default) - for (line_id = 1; ; line_id++) { - struct rte_swx_table_entry *entry; - int is_blank_or_comment; + table_name = tokens[3]; + status = rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name); + if (status) + snprintf(out, out_size, MSG_ARG_INVALID, "table_name"); +} - if (fgets(line, 2048, file_default) == NULL) - break; +static const char cmd_pipeline_commit_help[] = +"pipeline commit\n"; - entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl, - table_name, - line, - &is_blank_or_comment); - if (!entry) { - if (is_blank_or_comment) - continue; +static void +cmd_pipeline_commit(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) +{ + struct pipeline *p; + char *pipeline_name; + int status; - snprintf(out, out_size, MSG_FILE_ERR, - file_name_default, line_id); - goto error; - } + if (n_tokens != 3) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } - status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl, - table_name, - entry); - table_entry_free(entry); - if (status) { - snprintf(out, out_size, - "Invalid entry in file %s at line %u", - file_name_default, line_id); - goto error; - } - } + pipeline_name = tokens[1]; + p = pipeline_find(obj, pipeline_name); + if (!p || !p->ctl) { + snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); + return; + } status = rte_swx_ctl_pipeline_commit(p->ctl, 1); - if (status) { - snprintf(out, out_size, "Commit failed."); - goto error; - } + if (status) + snprintf(out, out_size, "Commit failed. " + "Use \"commit\" to retry or \"abort\" to discard the pending work.\n"); +} +static const char cmd_pipeline_abort_help[] = +"pipeline abort\n"; - rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name); +static void +cmd_pipeline_abort(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) +{ + struct pipeline *p; + char *pipeline_name; - free(line); - if (file_add) - fclose(file_add); - if (file_delete) - fclose(file_delete); - if (file_default) - fclose(file_default); - return; + if (n_tokens != 3) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + pipeline_name = tokens[1]; + p = pipeline_find(obj, pipeline_name); + if (!p || !p->ctl) { + snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); + return; + } -error: rte_swx_ctl_pipeline_abort(p->ctl); - free(line); - if (file_add) - fclose(file_add); - if (file_delete) - fclose(file_delete); - if (file_default) - fclose(file_default); } static const char cmd_pipeline_regrd_help[] = @@ -1992,7 +2164,12 @@ cmd_help(char **tokens, "\tpipeline port in\n" "\tpipeline port out\n" "\tpipeline build\n" - "\tpipeline table update\n" + "\tpipeline table add\n" + "\tpipeline table delete\n" + "\tpipeline table default\n" + "\tpipeline table show\n" + "\tpipeline commit\n" + "\tpipeline abort\n" "\tpipeline regrd\n" "\tpipeline regwr\n" "\tpipeline meter profile add\n" @@ -2056,9 +2233,52 @@ cmd_help(char **tokens, if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 3) && (strcmp(tokens[1], "table") == 0) && - (strcmp(tokens[2], "update") == 0)) { + (strcmp(tokens[2], "add") == 0)) { + snprintf(out, out_size, "\n%s\n", + cmd_pipeline_table_add_help); + return; + } + + if ((strcmp(tokens[0], "pipeline") == 0) && + (n_tokens == 3) && + (strcmp(tokens[1], "table") == 0) && + (strcmp(tokens[2], "delete") == 0)) { + snprintf(out, out_size, "\n%s\n", + cmd_pipeline_table_delete_help); + return; + } + + if ((strcmp(tokens[0], "pipeline") == 0) && + (n_tokens == 3) && + (strcmp(tokens[1], "table") == 0) && + (strcmp(tokens[2], "default") == 0)) { snprintf(out, out_size, "\n%s\n", - cmd_pipeline_table_update_help); + cmd_pipeline_table_default_help); + return; + } + + if ((strcmp(tokens[0], "pipeline") == 0) && + (n_tokens == 3) && + (strcmp(tokens[1], "table") == 0) && + (strcmp(tokens[2], "show") == 0)) { + snprintf(out, out_size, "\n%s\n", + cmd_pipeline_table_show_help); + return; + } + + if ((strcmp(tokens[0], "pipeline") == 0) && + (n_tokens == 2) && + (strcmp(tokens[1], "commit") == 0)) { + snprintf(out, out_size, "\n%s\n", + cmd_pipeline_commit_help); + return; + } + + if ((strcmp(tokens[0], "pipeline") == 0) && + (n_tokens == 2) && + (strcmp(tokens[1], "abort") == 0)) { + snprintf(out, out_size, "\n%s\n", + cmd_pipeline_abort_help); return; } @@ -2216,9 +2436,48 @@ cli_process(char *in, char *out, size_t out_size, void *obj) return; } + if ((n_tokens >= 5) && + (strcmp(tokens[2], "table") == 0) && + (strcmp(tokens[4], "add") == 0)) { + cmd_pipeline_table_add(tokens, n_tokens, out, + out_size, obj); + return; + } + + if ((n_tokens >= 5) && + (strcmp(tokens[2], "table") == 0) && + (strcmp(tokens[4], "delete") == 0)) { + cmd_pipeline_table_delete(tokens, n_tokens, out, + out_size, obj); + return; + } + + if ((n_tokens >= 5) && + (strcmp(tokens[2], "table") == 0) && + (strcmp(tokens[4], "default") == 0)) { + cmd_pipeline_table_default(tokens, n_tokens, out, + out_size, obj); + return; + } + + if ((n_tokens >= 5) && + (strcmp(tokens[2], "table") == 0) && + (strcmp(tokens[4], "show") == 0)) { + cmd_pipeline_table_show(tokens, n_tokens, out, + out_size, obj); + return; + } + + if ((n_tokens >= 3) && + (strcmp(tokens[2], "commit") == 0)) { + cmd_pipeline_commit(tokens, n_tokens, out, + out_size, obj); + return; + } + if ((n_tokens >= 3) && - (strcmp(tokens[2], "table") == 0)) { - cmd_pipeline_table_update(tokens, n_tokens, out, + (strcmp(tokens[2], "abort") == 0)) { + cmd_pipeline_abort(tokens, n_tokens, out, out_size, obj); return; } diff --git a/examples/pipeline/examples/vxlan.cli b/examples/pipeline/examples/vxlan.cli index 7bf4a5757..a3bde6a9f 100644 --- a/examples/pipeline/examples/vxlan.cli +++ b/examples/pipeline/examples/vxlan.cli @@ -22,6 +22,7 @@ pipeline PIPELINE0 port out 3 link LINK3 txq 0 bsz 32 pipeline PIPELINE0 port out 4 sink none pipeline PIPELINE0 build ./examples/pipeline/examples/vxlan.spec -pipeline PIPELINE0 table vxlan_table update ./examples/pipeline/examples/vxlan_table.txt none none +pipeline PIPELINE0 table vxlan_table add ./examples/pipeline/examples/vxlan_table.txt +pipeline PIPELINE0 commit thread 1 pipeline PIPELINE0 enable diff --git a/examples/pipeline/examples/vxlan_pcap.cli b/examples/pipeline/examples/vxlan_pcap.cli index 1636ba080..3cc9a94af 100644 --- a/examples/pipeline/examples/vxlan_pcap.cli +++ b/examples/pipeline/examples/vxlan_pcap.cli @@ -17,6 +17,7 @@ pipeline PIPELINE0 port out 3 sink none pipeline PIPELINE0 port out 4 sink none pipeline PIPELINE0 build ./examples/vxlan.spec -pipeline PIPELINE0 table vxlan_table update ./examples/vxlan_table.txt none none +pipeline PIPELINE0 table vxlan_table add ./examples/vxlan_table.txt +pipeline PIPELINE0 commit thread 1 pipeline PIPELINE0 enable