X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=examples%2Fpipeline%2Fcli.c;h=edae63dae686893ff2031c6b12ef7f77deb23dbf;hb=a4c1146c754b4b8cceb1c615df2a20138c09d25a;hp=5ee9567bb0d51d7d7141f4cbcefcf1d4d474b06b;hpb=c2c4f87b12590d96f549c4ef04a04d29d3b8fb97;p=dpdk.git diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 5ee9567bb0..edae63dae6 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -385,9 +385,7 @@ print_link_info(struct link *link, char *out, size_t out_size) link->name, eth_link.link_status == 0 ? "DOWN" : "UP", mtu, - mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], - mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], - mac_addr.addr_bytes[4], mac_addr.addr_bytes[5], + RTE_ETHER_ADDR_BYTES(&mac_addr), link->n_rxq, link->n_txq, link->port_id, @@ -557,7 +555,7 @@ static const char cmd_pipeline_port_in_help[] = "pipeline port in \n" " link rxq bsz \n" " ring bsz \n" -" | source \n" +" | source loop \n" " | tap mempool mtu bsz \n"; static void @@ -684,7 +682,7 @@ cmd_pipeline_port_in(char **tokens, struct rte_swx_port_source_params params; struct mempool *mp; - if (n_tokens < t0 + 3) { + if (n_tokens < t0 + 5) { snprintf(out, out_size, MSG_ARG_MISMATCH, "pipeline port in source"); return; @@ -700,7 +698,18 @@ cmd_pipeline_port_in(char **tokens, params.file_name = tokens[t0 + 2]; - t0 += 3; + if (strcmp(tokens[t0 + 3], "loop") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "loop"); + return; + } + + if (parser_read_uint64(¶ms.n_loops, tokens[t0 + 4])) { + snprintf(out, out_size, MSG_ARG_INVALID, + "n_loops"); + return; + } + + t0 += 5; status = rte_swx_pipeline_port_in_config(p->p, port_id, @@ -1337,7 +1346,7 @@ cmd_pipeline_table_default(char **tokens, } static const char cmd_pipeline_table_show_help[] = -"pipeline table show\n"; +"pipeline table show [filename]\n"; static void cmd_pipeline_table_show(char **tokens, @@ -1348,9 +1357,10 @@ cmd_pipeline_table_show(char **tokens, { struct pipeline *p; char *pipeline_name, *table_name; + FILE *file = NULL; int status; - if (n_tokens != 5) { + if (n_tokens != 5 && n_tokens != 6) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -1363,9 +1373,18 @@ cmd_pipeline_table_show(char **tokens, } table_name = tokens[3]; - status = rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name); + file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout; + if (!file) { + snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]); + return; + } + + status = rte_swx_ctl_pipeline_table_fprintf(file, p->ctl, table_name); if (status) snprintf(out, out_size, MSG_ARG_INVALID, "table_name"); + + if (file) + fclose(file); } static const char cmd_pipeline_selector_group_add_help[] = @@ -1797,7 +1816,7 @@ cmd_pipeline_selector_group_member_delete(char **tokens, } static const char cmd_pipeline_selector_show_help[] = -"pipeline selector show\n"; +"pipeline selector show [filename]\n"; static void cmd_pipeline_selector_show(char **tokens, @@ -1808,9 +1827,10 @@ cmd_pipeline_selector_show(char **tokens, { struct pipeline *p; char *pipeline_name, *selector_name; + FILE *file = NULL; int status; - if (n_tokens != 5) { + if (n_tokens != 5 && n_tokens != 6) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -1823,10 +1843,117 @@ cmd_pipeline_selector_show(char **tokens, } selector_name = tokens[3]; - status = rte_swx_ctl_pipeline_selector_fprintf(stdout, - p->ctl, selector_name); + + file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout; + if (!file) { + snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]); + return; + } + + status = rte_swx_ctl_pipeline_selector_fprintf(file, p->ctl, selector_name); if (status) snprintf(out, out_size, MSG_ARG_INVALID, "selector_name"); + + if (file) + fclose(file); +} + +static int +pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p, + const char *learner_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_learner_default_entry_read(p, + learner_name, + line, + &is_blank_or_comment); + if (!entry) { + if (is_blank_or_comment) + continue; + + status = -EINVAL; + goto error; + } + + status = rte_swx_ctl_pipeline_learner_default_entry_add(p, + learner_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_learner_default_help[] = +"pipeline learner default \n"; + +static void +cmd_pipeline_learner_default(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj) +{ + struct pipeline *p; + char *pipeline_name, *learner_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; + } + + learner_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_learner_default_entry_add(p->ctl, + learner_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 const char cmd_pipeline_commit_help[] = @@ -2444,10 +2571,17 @@ cmd_pipeline_stats(char **tokens, rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats); - snprintf(out, out_size, "\tPort %u:" - " packets %" PRIu64 - " bytes %" PRIu64 "\n", - i, stats.n_pkts, stats.n_bytes); + if (i != info.n_ports_out - 1) + snprintf(out, out_size, "\tPort %u:" + " packets %" PRIu64 + " bytes %" PRIu64 "\n", + i, stats.n_pkts, stats.n_bytes); + else + snprintf(out, out_size, "\tDROP:" + " packets %" PRIu64 + " bytes %" PRIu64 "\n", + stats.n_pkts, stats.n_bytes); + out_size -= strlen(out); out += strlen(out); } @@ -2503,6 +2637,64 @@ cmd_pipeline_stats(char **tokens, out += strlen(out); } } + + snprintf(out, out_size, "\nLearner tables:\n"); + out_size -= strlen(out); + out += strlen(out); + + for (i = 0; i < info.n_learners; i++) { + struct rte_swx_ctl_learner_info learner_info; + uint64_t n_pkts_action[info.n_actions]; + struct rte_swx_learner_stats stats = { + .n_pkts_hit = 0, + .n_pkts_miss = 0, + .n_pkts_action = n_pkts_action, + }; + uint32_t j; + + status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info); + if (status) { + snprintf(out, out_size, "Learner table info get error."); + return; + } + + status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats); + if (status) { + snprintf(out, out_size, "Learner table stats read error."); + return; + } + + snprintf(out, out_size, "\tLearner table %s:\n" + "\t\tHit (packets): %" PRIu64 "\n" + "\t\tMiss (packets): %" PRIu64 "\n" + "\t\tLearn OK (packets): %" PRIu64 "\n" + "\t\tLearn error (packets): %" PRIu64 "\n" + "\t\tForget (packets): %" PRIu64 "\n", + learner_info.name, + stats.n_pkts_hit, + stats.n_pkts_miss, + stats.n_pkts_learn_ok, + stats.n_pkts_learn_err, + stats.n_pkts_forget); + out_size -= strlen(out); + out += strlen(out); + + for (j = 0; j < info.n_actions; j++) { + struct rte_swx_ctl_action_info action_info; + + status = rte_swx_ctl_action_info_get(p->p, j, &action_info); + if (status) { + snprintf(out, out_size, "Action info get error."); + return; + } + + snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n", + action_info.name, + stats.n_pkts_action[j]); + out_size -= strlen(out); + out += strlen(out); + } + } } static const char cmd_thread_pipeline_enable_help[] = @@ -2634,6 +2826,7 @@ cmd_help(char **tokens, "\tpipeline selector group member add\n" "\tpipeline selector group member delete\n" "\tpipeline selector show\n" + "\tpipeline learner default\n" "\tpipeline commit\n" "\tpipeline abort\n" "\tpipeline regrd\n" @@ -2783,6 +2976,15 @@ cmd_help(char **tokens, return; } + if ((strcmp(tokens[0], "pipeline") == 0) && + (n_tokens == 3) && + (strcmp(tokens[1], "learner") == 0) && + (strcmp(tokens[2], "default") == 0)) { + snprintf(out, out_size, "\n%s\n", + cmd_pipeline_learner_default_help); + return; + } + if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 2) && (strcmp(tokens[1], "commit") == 0)) { @@ -3031,6 +3233,14 @@ cli_process(char *in, char *out, size_t out_size, void *obj) return; } + if ((n_tokens >= 5) && + (strcmp(tokens[2], "learner") == 0) && + (strcmp(tokens[4], "default") == 0)) { + cmd_pipeline_learner_default(tokens, n_tokens, out, + out_size, obj); + return; + } + if ((n_tokens >= 3) && (strcmp(tokens[2], "commit") == 0)) { cmd_pipeline_commit(tokens, n_tokens, out,