if (strcmp(file_name_add, "none")) {
file_add = fopen(file_name_add, "r");
if (!file_add) {
- snprintf(out, out_size, "Cannot open file %s",
+ snprintf(out, out_size, "Cannot open file %s.\n",
file_name_add);
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",
+ snprintf(out, out_size, "Cannot open file %s.\n",
file_name_delete);
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",
+ snprintf(out, out_size, "Cannot open file %s.\n",
file_name_default);
goto error;
}
}
}
+static const char cmd_pipeline_meter_profile_add_help[] =
+"pipeline <pipeline_name> meter profile <profile_name> add "
+ "cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
+
+static void
+cmd_pipeline_meter_profile_add(char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size,
+ void *obj)
+{
+ struct rte_meter_trtcm_params params;
+ struct pipeline *p;
+ const char *profile_name;
+ int status;
+
+ if (n_tokens != 14) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ p = pipeline_find(obj, tokens[1]);
+ if (!p || !p->ctl) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
+
+ if (strcmp(tokens[2], "meter")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
+ return;
+ }
+
+ if (strcmp(tokens[3], "profile")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
+ return;
+ }
+
+ profile_name = tokens[4];
+
+ if (strcmp(tokens[5], "add")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
+ return;
+ }
+
+ if (strcmp(tokens[6], "cir")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
+ return;
+ }
+
+ if (parser_read_uint64(¶ms.cir, tokens[7])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "cir");
+ return;
+ }
+
+ if (strcmp(tokens[8], "pir")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
+ return;
+ }
+
+ if (parser_read_uint64(¶ms.pir, tokens[9])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pir");
+ return;
+ }
+
+ if (strcmp(tokens[10], "cbs")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
+ return;
+ }
+
+ if (parser_read_uint64(¶ms.cbs, tokens[11])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
+ return;
+ }
+
+ if (strcmp(tokens[12], "pbs")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
+ return;
+ }
+
+ if (parser_read_uint64(¶ms.pbs, tokens[13])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
+ return;
+ }
+
+ status = rte_swx_ctl_meter_profile_add(p->p, profile_name, ¶ms);
+ if (status) {
+ snprintf(out, out_size, "Command failed.\n");
+ return;
+ }
+}
+
+static const char cmd_pipeline_meter_profile_delete_help[] =
+"pipeline <pipeline_name> meter profile <profile_name> delete\n";
+
+static void
+cmd_pipeline_meter_profile_delete(char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size,
+ void *obj)
+{
+ struct pipeline *p;
+ const char *profile_name;
+ int status;
+
+ if (n_tokens != 6) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ p = pipeline_find(obj, tokens[1]);
+ if (!p || !p->ctl) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
+
+ if (strcmp(tokens[2], "meter")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
+ return;
+ }
+
+ if (strcmp(tokens[3], "profile")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
+ return;
+ }
+
+ profile_name = tokens[4];
+
+ if (strcmp(tokens[5], "delete")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
+ return;
+ }
+
+ status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
+ if (status) {
+ snprintf(out, out_size, "Command failed.\n");
+ return;
+ }
+}
+
+static const char cmd_pipeline_meter_reset_help[] =
+"pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
+ "reset\n";
+
+static void
+cmd_pipeline_meter_reset(char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size,
+ void *obj)
+{
+ struct pipeline *p;
+ const char *name;
+ uint32_t idx0, idx1;
+
+ if (n_tokens != 9) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ p = pipeline_find(obj, tokens[1]);
+ if (!p || !p->ctl) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
+
+ if (strcmp(tokens[2], "meter")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
+ return;
+ }
+
+ name = tokens[3];
+
+ if (strcmp(tokens[4], "from")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
+ return;
+ }
+
+ if (parser_read_uint32(&idx0, tokens[5])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "index0");
+ return;
+ }
+
+ if (strcmp(tokens[6], "to")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
+ return;
+ }
+
+ if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "index1");
+ return;
+ }
+
+ if (strcmp(tokens[8], "reset")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
+ return;
+ }
+
+ for ( ; idx0 <= idx1; idx0++) {
+ int status;
+
+ status = rte_swx_ctl_meter_reset(p->p, name, idx0);
+ if (status) {
+ snprintf(out, out_size, "Command failed for index %u.\n", idx0);
+ return;
+ }
+ }
+}
+
+static const char cmd_pipeline_meter_set_help[] =
+"pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
+ "set profile <profile_name>\n";
+
+static void
+cmd_pipeline_meter_set(char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size,
+ void *obj)
+{
+ struct pipeline *p;
+ const char *name, *profile_name;
+ uint32_t idx0, idx1;
+
+ if (n_tokens != 11) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ p = pipeline_find(obj, tokens[1]);
+ if (!p || !p->ctl) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
+
+ if (strcmp(tokens[2], "meter")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
+ return;
+ }
+
+ name = tokens[3];
+
+ if (strcmp(tokens[4], "from")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
+ return;
+ }
+
+ if (parser_read_uint32(&idx0, tokens[5])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "index0");
+ return;
+ }
+
+ if (strcmp(tokens[6], "to")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
+ return;
+ }
+
+ if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "index1");
+ return;
+ }
+
+ if (strcmp(tokens[8], "set")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
+ return;
+ }
+
+ if (strcmp(tokens[9], "profile")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
+ return;
+ }
+
+ profile_name = tokens[10];
+
+ for ( ; idx0 <= idx1; idx0++) {
+ int status;
+
+ status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
+ if (status) {
+ snprintf(out, out_size, "Command failed for index %u.\n", idx0);
+ return;
+ }
+ }
+}
+
+static const char cmd_pipeline_meter_stats_help[] =
+"pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
+ "stats\n";
+
+static void
+cmd_pipeline_meter_stats(char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size,
+ void *obj)
+{
+ struct rte_swx_ctl_meter_stats stats;
+ struct pipeline *p;
+ const char *name;
+ uint32_t idx0, idx1;
+
+ if (n_tokens != 9) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ p = pipeline_find(obj, tokens[1]);
+ if (!p || !p->ctl) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
+
+ if (strcmp(tokens[2], "meter")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
+ return;
+ }
+
+ name = tokens[3];
+
+ if (strcmp(tokens[4], "from")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
+ return;
+ }
+
+ if (parser_read_uint32(&idx0, tokens[5])) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "index0");
+ return;
+ }
+
+ if (strcmp(tokens[6], "to")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
+ return;
+ }
+
+ if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "index1");
+ return;
+ }
+
+ if (strcmp(tokens[8], "stats")) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
+ return;
+ }
+
+ /* Table header. */
+ snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
+ "-------",
+ "----------------", "----------------", "----------------",
+ "----------------", "----------------", "----------------");
+ out_size -= strlen(out);
+ out += strlen(out);
+
+ snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
+ "METER #",
+ "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
+ "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
+ out_size -= strlen(out);
+ out += strlen(out);
+
+ snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
+ "-------",
+ "----------------", "----------------", "----------------",
+ "----------------", "----------------", "----------------");
+ out_size -= strlen(out);
+ out += strlen(out);
+
+ /* Table rows. */
+ for ( ; idx0 <= idx1; idx0++) {
+ int status;
+
+ status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
+ if (status) {
+ snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
+ out_size -= strlen(out);
+ out += strlen(out);
+ return;
+ }
+
+ snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
+ " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
+ idx0,
+ stats.n_pkts[RTE_COLOR_GREEN],
+ stats.n_pkts[RTE_COLOR_YELLOW],
+ stats.n_pkts[RTE_COLOR_RED],
+ stats.n_bytes[RTE_COLOR_GREEN],
+ stats.n_bytes[RTE_COLOR_YELLOW],
+ stats.n_bytes[RTE_COLOR_RED]);
+ out_size -= strlen(out);
+ out += strlen(out);
+ }
+}
+
static const char cmd_pipeline_stats_help[] =
"pipeline <pipeline_name> stats\n";
out += strlen(out);
}
- snprintf(out, out_size, "Output ports:\n");
+ snprintf(out, out_size, "\nOutput ports:\n");
out_size -= strlen(out);
out += strlen(out);
out_size -= strlen(out);
out += strlen(out);
}
+
+ snprintf(out, out_size, "\nTables:\n");
+ out_size -= strlen(out);
+ out += strlen(out);
+
+ for (i = 0; i < info.n_tables; i++) {
+ struct rte_swx_ctl_table_info table_info;
+ uint64_t n_pkts_action[info.n_actions];
+ struct rte_swx_table_stats stats = {
+ .n_pkts_hit = 0,
+ .n_pkts_miss = 0,
+ .n_pkts_action = n_pkts_action,
+ };
+ uint32_t j;
+
+ status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
+ if (status) {
+ snprintf(out, out_size, "Table info get error.");
+ return;
+ }
+
+ status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
+ if (status) {
+ snprintf(out, out_size, "Table stats read error.");
+ return;
+ }
+
+ snprintf(out, out_size, "\tTable %s:\n"
+ "\t\tHit (packets): %" PRIu64 "\n"
+ "\t\tMiss (packets): %" PRIu64 "\n",
+ table_info.name,
+ stats.n_pkts_hit,
+ stats.n_pkts_miss);
+ 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[] =
"\tpipeline table update\n"
"\tpipeline regrd\n"
"\tpipeline regwr\n"
+ "\tpipeline meter profile add\n"
+ "\tpipeline meter profile delete\n"
+ "\tpipeline meter reset\n"
+ "\tpipeline meter set\n"
+ "\tpipeline meter stats\n"
"\tpipeline stats\n"
"\tthread pipeline enable\n"
"\tthread pipeline disable\n\n");
return;
}
+ if (!strcmp(tokens[0], "pipeline") &&
+ (n_tokens == 4) && !strcmp(tokens[1], "meter")
+ && !strcmp(tokens[2], "profile")
+ && !strcmp(tokens[3], "add")) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
+ return;
+ }
+
+ if (!strcmp(tokens[0], "pipeline") &&
+ (n_tokens == 4) && !strcmp(tokens[1], "meter")
+ && !strcmp(tokens[2], "profile")
+ && !strcmp(tokens[3], "delete")) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
+ return;
+ }
+
+ if (!strcmp(tokens[0], "pipeline") &&
+ (n_tokens == 3) && !strcmp(tokens[1], "meter")
+ && !strcmp(tokens[2], "reset")) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
+ return;
+ }
+
+ if (!strcmp(tokens[0], "pipeline") &&
+ (n_tokens == 3) && !strcmp(tokens[1], "meter")
+ && !strcmp(tokens[2], "set")) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
+ return;
+ }
+
+ if (!strcmp(tokens[0], "pipeline") &&
+ (n_tokens == 3) && !strcmp(tokens[1], "meter")
+ && !strcmp(tokens[2], "stats")) {
+ snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
+ return;
+ }
+
if ((strcmp(tokens[0], "pipeline") == 0) &&
(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
return;
}
+ if ((n_tokens >= 6) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[3], "profile") == 0) &&
+ (strcmp(tokens[5], "add") == 0)) {
+ cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
+ return;
+ }
+
+ if ((n_tokens >= 6) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[3], "profile") == 0) &&
+ (strcmp(tokens[5], "delete") == 0)) {
+ cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
+ return;
+ }
+
+ if ((n_tokens >= 9) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[8], "reset") == 0)) {
+ cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
+ return;
+ }
+
+ if ((n_tokens >= 9) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[8], "set") == 0)) {
+ cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
+ return;
+ }
+
+ if ((n_tokens >= 9) &&
+ (strcmp(tokens[2], "meter") == 0) &&
+ (strcmp(tokens[8], "stats") == 0)) {
+ cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
+ return;
+ }
+
if ((n_tokens >= 3) &&
(strcmp(tokens[2], "stats") == 0)) {
cmd_pipeline_stats(tokens, n_tokens, out, out_size,