From 75129ceb1e8b21369db2fcb4426790b8a9e0b9e6 Mon Sep 17 00:00:00 2001 From: Churchill Khangar Date: Fri, 2 Jul 2021 23:46:04 +0100 Subject: [PATCH] examples/pipeline: improve table update commands For more flexibility, 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 215dd8e851..30754e319a 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 7bf4a57575..a3bde6a9f9 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 1636ba080e..3cc9a94afe 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 -- 2.20.1