From: Jasvinder Singh Date: Mon, 20 Nov 2017 16:39:18 +0000 (+0000) Subject: app/testpmd: clean metering and policing commands X-Git-Tag: spdx-start~752 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=e63b50162aa38111410a2ab2381d672d42503f6e;p=dpdk.git app/testpmd: clean metering and policing commands This patch updates the metering and policing CLIs as follows: - change name of set port meter CLI to create port meter and add meter enable option, dscp table entries arguments, action mask, policer actions and previous meter color option as an input color - set the right metering algorithm in add meter profile CLIs related to srtcm(rfc2697) and trtcm(rfc2698,rfc4115) - change clear flag type from uint32_t to string in show meter stats CLI Signed-off-by: Jasvinder Singh Acked-by: Jingjing Wu --- diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 8990ebf6b6..fd735d8ef2 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -698,7 +698,7 @@ static void cmd_help_long_parsed(void *parsed_result, "set port (port_id) queue-region flush (on|off)\n" " flush all queue region related configuration\n\n" - "add port meter profile srtcm_rfc2697 (port_id) (profile_id) (cir) (cbs) (ebs) (color_aware)\n" + "add port meter profile srtcm_rfc2697 (port_id) (profile_id) (cir) (cbs) (ebs)\n" " meter profile add - srtcm rfc 2697\n\n" "add port meter profile trtcm_rfc2698 (port_id) (profile_id) (cir) (pir) (cbs) (pbs)\n" @@ -710,7 +710,10 @@ static void cmd_help_long_parsed(void *parsed_result, "del port meter profile (port_id) (profile_id)\n" " meter profile delete\n\n" - "set port meter (port_id) (mtr_id) (profile_id) (g_action) (y_action) (r_action) (stats_mask) (shared)\n" + "create port meter (port_id) (mtr_id) (profile_id) (meter_enable)\n" + "(g_action) (y_action) (r_action) (stats_mask) (shared)\n" + "(use_pre_meter_color) [(dscp_tbl_entry0) (dscp_tbl_entry1)...\n" + "(dscp_tbl_entry63)]\n" " meter create\n\n" "del port meter (port_id) (mtr_id)\n" @@ -719,7 +722,8 @@ static void cmd_help_long_parsed(void *parsed_result, "set port meter profile (port_id) (mtr_id) (profile_id)\n" " meter update meter profile\n\n" - "set port meter policer action (port_id) (mtr_id) (color) (action)\n" + "set port meter policer action (port_id) (mtr_id) (action_mask)\n" + "(action0) [(action1) (action2)]\n" " meter update policer action\n\n" "set port meter stats mask (port_id) (mtr_id) (stats_mask)\n" @@ -15688,7 +15692,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_add_port_meter_profile_srtcm, (cmdline_parse_inst_t *)&cmd_add_port_meter_profile_trtcm, (cmdline_parse_inst_t *)&cmd_del_port_meter_profile, - (cmdline_parse_inst_t *)&cmd_set_port_meter, + (cmdline_parse_inst_t *)&cmd_create_port_meter, (cmdline_parse_inst_t *)&cmd_del_port_meter, (cmdline_parse_inst_t *)&cmd_set_port_meter_profile, (cmdline_parse_inst_t *)&cmd_set_port_meter_policer_action, diff --git a/app/test-pmd/cmdline_mtr.c b/app/test-pmd/cmdline_mtr.c index 5eb91f13e1..ae742492d6 100644 --- a/app/test-pmd/cmdline_mtr.c +++ b/app/test-pmd/cmdline_mtr.c @@ -13,6 +13,9 @@ #include "testpmd.h" #include "cmdline_mtr.h" +#define PARSE_DELIMITER " \f\n\r\t\v" +#define MAX_DSCP_TABLE_ENTRIES 64 + /** Display Meter Error Message */ static void print_err_msg(struct rte_mtr_error *error) @@ -53,24 +56,138 @@ print_err_msg(struct rte_mtr_error *error) error->type); } +static int +parse_uint(uint64_t *value, const char *str) +{ + char *next = NULL; + uint64_t n; + + errno = 0; + /* Parse number string */ + n = strtol(str, &next, 10); + if (errno != 0 || str == next || *next != '\0') + return -1; + + *value = n; + + return 0; +} + +static int +parse_dscp_table_entries(char *str, enum rte_mtr_color *dscp_table) +{ + char *token; + int i = 0; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) + return 0; + + /* Allocate memory for dscp table */ + dscp_table = (enum rte_mtr_color *)malloc(MAX_DSCP_TABLE_ENTRIES * + sizeof(enum rte_mtr_color)); + + while (1) { + if (strcmp(token, "G") == 0 || + strcmp(token, "g") == 0) + dscp_table[i++] = RTE_MTR_GREEN; + else if (strcmp(token, "Y") == 0 || + strcmp(token, "y") == 0) + dscp_table[i++] = RTE_MTR_YELLOW; + else if (strcmp(token, "R") == 0 || + strcmp(token, "r") == 0) + dscp_table[i++] = RTE_MTR_RED; + else { + free(dscp_table); + return -1; + } + if (i == MAX_DSCP_TABLE_ENTRIES) + break; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) + return -1; + } + return 0; +} + +static int +parse_meter_color_str(char *c_str, uint32_t *use_prev_meter_color, + enum rte_mtr_color *dscp_table) +{ + char *token; + uint64_t previous_mtr_color = 0; + int ret; + + /* First token: use previous meter color */ + token = strtok_r(c_str, PARSE_DELIMITER, &c_str); + if (token == NULL) + return -1; + + ret = parse_uint(&previous_mtr_color, token); + if (ret != 0) + return -1; + + /* Check if previous meter color to be used */ + if (previous_mtr_color) { + *use_prev_meter_color = previous_mtr_color; + return 0; + } + + /* Parse dscp table entries */ + ret = parse_dscp_table_entries(c_str, dscp_table); + if (ret != 0) + return -1; + + return 0; +} + static int string_to_policer_action(char *s) { - if (strcmp(s, "G") == 0) + if ((strcmp(s, "G") == 0) || (strcmp(s, "g") == 0)) return MTR_POLICER_ACTION_COLOR_GREEN; - if (strcmp(s, "Y") == 0) + if ((strcmp(s, "Y") == 0) || (strcmp(s, "y") == 0)) return MTR_POLICER_ACTION_COLOR_YELLOW; - if (strcmp(s, "R") == 0) + if ((strcmp(s, "R") == 0) || (strcmp(s, "r") == 0)) return MTR_POLICER_ACTION_COLOR_RED; - if (strcmp(s, "D") == 0) + if ((strcmp(s, "D") == 0) || (strcmp(s, "d") == 0)) return MTR_POLICER_ACTION_DROP; return -1; } +static int +parse_policer_action_string(char *p_str, uint32_t action_mask, + enum rte_mtr_policer_action actions[]) +{ + char *token; + int count = __builtin_popcount(action_mask); + int g_color = 0, y_color = 0, action, i; + + for (i = 0; i < count; i++) { + token = strtok_r(p_str, PARSE_DELIMITER, &p_str); + if (token == NULL) + return -1; + + action = string_to_policer_action(token); + if (action == -1) + return -1; + + if (g_color == 0 && (action_mask & 0x1)) { + actions[RTE_MTR_GREEN] = action; + g_color = 1; + } else if (y_color == 0 && (action_mask & 0x2)) { + actions[RTE_MTR_YELLOW] = action; + y_color = 1; + } else + actions[RTE_MTR_RED] = action; + } + return 0; +} /* *** Add Port Meter Profile srtcm_rfc2697 *** */ struct cmd_add_port_meter_profile_srtcm_result { cmdline_fixed_string_t add; @@ -83,7 +200,6 @@ struct cmd_add_port_meter_profile_srtcm_result { uint64_t cir; uint64_t cbs; uint64_t ebs; - uint8_t color_aware; }; cmdline_parse_token_string_t cmd_add_port_meter_profile_srtcm_add = @@ -142,7 +258,7 @@ static void cmd_add_port_meter_profile_srtcm_parsed(void *parsed_result, /* Private shaper profile params */ memset(&mp, 0, sizeof(struct rte_mtr_meter_profile)); - mp.alg = 0; + mp.alg = RTE_MTR_SRTCM_RFC2697; mp.srtcm_rfc2697.cir = res->cir; mp.srtcm_rfc2697.cbs = res->cbs; mp.srtcm_rfc2697.ebs = res->ebs; @@ -248,7 +364,7 @@ static void cmd_add_port_meter_profile_trtcm_parsed(void *parsed_result, /* Private shaper profile params */ memset(&mp, 0, sizeof(struct rte_mtr_meter_profile)); - mp.alg = 0; + mp.alg = RTE_MTR_TRTCM_RFC2698; mp.trtcm_rfc2698.cir = res->cir; mp.trtcm_rfc2698.pir = res->pir; mp.trtcm_rfc2698.cbs = res->cbs; @@ -360,7 +476,7 @@ static void cmd_add_port_meter_profile_trtcm_rfc4115_parsed( /* Private shaper profile params */ memset(&mp, 0, sizeof(struct rte_mtr_meter_profile)); - mp.alg = 0; + mp.alg = RTE_MTR_TRTCM_RFC4115; mp.trtcm_rfc4115.cir = res->cir; mp.trtcm_rfc4115.eir = res->eir; mp.trtcm_rfc4115.cbs = res->cbs; @@ -464,65 +580,75 @@ cmdline_parse_inst_t cmd_del_port_meter_profile = { }; /* *** Create Port Meter Object *** */ -struct cmd_set_port_meter_result { - cmdline_fixed_string_t set; +struct cmd_create_port_meter_result { + cmdline_fixed_string_t create; cmdline_fixed_string_t port; cmdline_fixed_string_t meter; uint16_t port_id; uint32_t mtr_id; uint32_t profile_id; + cmdline_fixed_string_t meter_enable; cmdline_fixed_string_t g_action; cmdline_fixed_string_t y_action; cmdline_fixed_string_t r_action; uint64_t statistics_mask; uint32_t shared; + cmdline_multi_string_t meter_input_color; }; -cmdline_parse_token_string_t cmd_set_port_meter_set = +cmdline_parse_token_string_t cmd_create_port_meter_create = TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_result, set, "set"); -cmdline_parse_token_string_t cmd_set_port_meter_port = + struct cmd_create_port_meter_result, create, "create"); +cmdline_parse_token_string_t cmd_create_port_meter_port = TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_result, port, "port"); -cmdline_parse_token_string_t cmd_set_port_meter_meter = + struct cmd_create_port_meter_result, port, "port"); +cmdline_parse_token_string_t cmd_create_port_meter_meter = TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_result, meter, "meter"); -cmdline_parse_token_num_t cmd_set_port_meter_port_id = + struct cmd_create_port_meter_result, meter, "meter"); +cmdline_parse_token_num_t cmd_create_port_meter_port_id = TOKEN_NUM_INITIALIZER( - struct cmd_set_port_meter_result, port_id, UINT16); -cmdline_parse_token_num_t cmd_set_port_meter_mtr_id = + struct cmd_create_port_meter_result, port_id, UINT16); +cmdline_parse_token_num_t cmd_create_port_meter_mtr_id = TOKEN_NUM_INITIALIZER( - struct cmd_set_port_meter_result, mtr_id, UINT32); -cmdline_parse_token_num_t cmd_set_port_meter_profile_id = + struct cmd_create_port_meter_result, mtr_id, UINT32); +cmdline_parse_token_num_t cmd_create_port_meter_profile_id = TOKEN_NUM_INITIALIZER( - struct cmd_set_port_meter_result, profile_id, UINT32); -cmdline_parse_token_string_t cmd_set_port_meter_g_action = - TOKEN_STRING_INITIALIZER(struct cmd_set_port_meter_result, - g_action, "R#Y#G#D"); -cmdline_parse_token_string_t cmd_set_port_meter_y_action = - TOKEN_STRING_INITIALIZER(struct cmd_set_port_meter_result, - y_action, "R#Y#G#D"); -cmdline_parse_token_string_t cmd_set_port_meter_r_action = - TOKEN_STRING_INITIALIZER(struct cmd_set_port_meter_result, - r_action, "R#Y#G#D"); -cmdline_parse_token_num_t cmd_set_port_meter_statistics_mask = - TOKEN_NUM_INITIALIZER(struct cmd_set_port_meter_result, + struct cmd_create_port_meter_result, profile_id, UINT32); +cmdline_parse_token_string_t cmd_create_port_meter_meter_enable = + TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result, + meter_enable, "yes#no"); +cmdline_parse_token_string_t cmd_create_port_meter_g_action = + TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result, + g_action, "R#Y#G#D#r#y#g#d"); +cmdline_parse_token_string_t cmd_create_port_meter_y_action = + TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result, + y_action, "R#Y#G#D#r#y#g#d"); +cmdline_parse_token_string_t cmd_create_port_meter_r_action = + TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result, + r_action, "R#Y#G#D#r#y#g#d"); +cmdline_parse_token_num_t cmd_create_port_meter_statistics_mask = + TOKEN_NUM_INITIALIZER(struct cmd_create_port_meter_result, statistics_mask, UINT64); -cmdline_parse_token_num_t cmd_set_port_meter_shared = - TOKEN_NUM_INITIALIZER(struct cmd_set_port_meter_result, +cmdline_parse_token_num_t cmd_create_port_meter_shared = + TOKEN_NUM_INITIALIZER(struct cmd_create_port_meter_result, shared, UINT32); +cmdline_parse_token_string_t cmd_create_port_meter_input_color = + TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result, + meter_input_color, TOKEN_STRING_MULTI); -static void cmd_set_port_meter_parsed(void *parsed_result, +static void cmd_create_port_meter_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { - struct cmd_set_port_meter_result *res = parsed_result; + struct cmd_create_port_meter_result *res = parsed_result; struct rte_mtr_error error; struct rte_mtr_params params; uint32_t mtr_id = res->mtr_id; uint32_t shared = res->shared; + uint32_t use_prev_meter_color = 0; uint16_t port_id = res->port_id; - + enum rte_mtr_color *dscp_table = NULL; + char *c_str = res->meter_input_color; int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) @@ -531,9 +657,22 @@ static void cmd_set_port_meter_parsed(void *parsed_result, /* Meter params */ memset(¶ms, 0, sizeof(struct rte_mtr_params)); params.meter_profile_id = res->profile_id; - params.use_prev_mtr_color = 1; - params.dscp_table = NULL; - params.meter_enable = 1; + + /* Parse meter input color string params */ + ret = parse_meter_color_str(c_str, &use_prev_meter_color, dscp_table); + if (ret) { + printf(" Meter input color params string parse error\n"); + return; + } + + params.use_prev_mtr_color = use_prev_meter_color; + params.dscp_table = dscp_table; + + if (strcmp(res->meter_enable, "yes") == 0) + params.meter_enable = 1; + else + params.meter_enable = 0; + params.action[RTE_MTR_GREEN] = string_to_policer_action(res->g_action); params.action[RTE_MTR_YELLOW] = @@ -544,27 +683,30 @@ static void cmd_set_port_meter_parsed(void *parsed_result, ret = rte_mtr_create(port_id, mtr_id, ¶ms, shared, &error); if (ret != 0) { + free(dscp_table); print_err_msg(&error); return; } } -cmdline_parse_inst_t cmd_set_port_meter = { - .f = cmd_set_port_meter_parsed, +cmdline_parse_inst_t cmd_create_port_meter = { + .f = cmd_create_port_meter_parsed, .data = NULL, - .help_str = "Set port meter", + .help_str = "Create port meter", .tokens = { - (void *)&cmd_set_port_meter_set, - (void *)&cmd_set_port_meter_port, - (void *)&cmd_set_port_meter_meter, - (void *)&cmd_set_port_meter_port_id, - (void *)&cmd_set_port_meter_mtr_id, - (void *)&cmd_set_port_meter_profile_id, - (void *)&cmd_set_port_meter_g_action, - (void *)&cmd_set_port_meter_y_action, - (void *)&cmd_set_port_meter_r_action, - (void *)&cmd_set_port_meter_statistics_mask, - (void *)&cmd_set_port_meter_shared, + (void *)&cmd_create_port_meter_create, + (void *)&cmd_create_port_meter_port, + (void *)&cmd_create_port_meter_meter, + (void *)&cmd_create_port_meter_port_id, + (void *)&cmd_create_port_meter_mtr_id, + (void *)&cmd_create_port_meter_profile_id, + (void *)&cmd_create_port_meter_meter_enable, + (void *)&cmd_create_port_meter_g_action, + (void *)&cmd_create_port_meter_y_action, + (void *)&cmd_create_port_meter_r_action, + (void *)&cmd_create_port_meter_statistics_mask, + (void *)&cmd_create_port_meter_shared, + (void *)&cmd_create_port_meter_input_color, NULL, }, }; @@ -712,8 +854,8 @@ struct cmd_set_port_meter_policer_action_result { cmdline_fixed_string_t action; uint16_t port_id; uint32_t mtr_id; - cmdline_fixed_string_t color; - cmdline_fixed_string_t policer_action; + uint32_t action_mask; + cmdline_multi_string_t policer_action; }; cmdline_parse_token_string_t cmd_set_port_meter_policer_action_set = @@ -742,56 +884,60 @@ cmdline_parse_token_num_t cmd_set_port_meter_policer_action_mtr_id = TOKEN_NUM_INITIALIZER( struct cmd_set_port_meter_policer_action_result, mtr_id, UINT32); -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_color = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, color, - "G#Y#R"); +cmdline_parse_token_num_t cmd_set_port_meter_policer_action_action_mask = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_meter_policer_action_result, action_mask, + UINT32); cmdline_parse_token_string_t cmd_set_port_meter_policer_action_policer_action = TOKEN_STRING_INITIALIZER( struct cmd_set_port_meter_policer_action_result, - policer_action, "G#Y#R#D"); + policer_action, TOKEN_STRING_MULTI); static void cmd_set_port_meter_policer_action_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) { struct cmd_set_port_meter_policer_action_result *res = parsed_result; - enum rte_mtr_color color; - enum rte_mtr_policer_action action[RTE_MTR_COLORS]; + enum rte_mtr_policer_action *actions; struct rte_mtr_error error; uint32_t mtr_id = res->mtr_id; + uint32_t action_mask = res->action_mask; uint16_t port_id = res->port_id; - char *c = res->color; - char *a = res->policer_action; + char *p_str = res->policer_action; int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; - /* Color */ - if (strcmp(c, "G") == 0) - color = RTE_MTR_GREEN; - else if (strcmp(c, "Y") == 0) - color = RTE_MTR_YELLOW; - else - color = RTE_MTR_RED; - - /* Action */ - if (strcmp(a, "G") == 0) - action[color] = MTR_POLICER_ACTION_COLOR_GREEN; - else if (strcmp(a, "Y") == 0) - action[color] = MTR_POLICER_ACTION_COLOR_YELLOW; - else if (strcmp(a, "R") == 0) - action[color] = MTR_POLICER_ACTION_COLOR_RED; - else - action[color] = MTR_POLICER_ACTION_DROP; + /* Check: action mask */ + if (action_mask == 0 || (action_mask & (~0x7UL))) { + printf(" Policer action mask not correct (error)\n"); + return; + } + + /* Allocate memory for policer actions */ + actions = (enum rte_mtr_policer_action *)malloc(RTE_MTR_COLORS * + sizeof(enum rte_mtr_policer_action)); + if (actions == NULL) { + printf("Memory for policer actions not allocated (error)\n"); + return; + } + /* Parse policer action string */ + ret = parse_policer_action_string(p_str, action_mask, actions); + if (ret) { + printf(" Policer action string parse error\n"); + free(actions); + return; + } ret = rte_mtr_policer_actions_update(port_id, mtr_id, - 1 << color, action, &error); + action_mask, actions, &error); if (ret != 0) { print_err_msg(&error); return; } + + free(actions); } cmdline_parse_inst_t cmd_set_port_meter_policer_action = { @@ -806,7 +952,7 @@ cmdline_parse_inst_t cmd_set_port_meter_policer_action = { (void *)&cmd_set_port_meter_policer_action_action, (void *)&cmd_set_port_meter_policer_action_port_id, (void *)&cmd_set_port_meter_policer_action_mtr_id, - (void *)&cmd_set_port_meter_policer_action_color, + (void *)&cmd_set_port_meter_policer_action_action_mask, (void *)&cmd_set_port_meter_policer_action_policer_action, NULL, }, @@ -896,7 +1042,7 @@ struct cmd_show_port_meter_stats_result { cmdline_fixed_string_t stats; uint16_t port_id; uint32_t mtr_id; - uint32_t clear; + cmdline_fixed_string_t clear; }; cmdline_parse_token_string_t cmd_show_port_meter_stats_show = @@ -917,9 +1063,9 @@ cmdline_parse_token_num_t cmd_show_port_meter_stats_port_id = cmdline_parse_token_num_t cmd_show_port_meter_stats_mtr_id = TOKEN_NUM_INITIALIZER( struct cmd_show_port_meter_stats_result, mtr_id, UINT32); -cmdline_parse_token_num_t cmd_show_port_meter_stats_clear = - TOKEN_NUM_INITIALIZER( - struct cmd_show_port_meter_stats_result, clear, UINT32); +cmdline_parse_token_string_t cmd_show_port_meter_stats_clear = + TOKEN_STRING_INITIALIZER( + struct cmd_show_port_meter_stats_result, clear, "yes#no"); static void cmd_show_port_meter_stats_parsed(void *parsed_result, __attribute__((unused)) struct cmdline *cl, @@ -930,13 +1076,16 @@ static void cmd_show_port_meter_stats_parsed(void *parsed_result, uint64_t stats_mask = 0; struct rte_mtr_error error; uint32_t mtr_id = res->mtr_id; - uint32_t clear = res->clear; + uint32_t clear = 0; uint16_t port_id = res->port_id; int ret; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; + if (strcmp(res->clear, "yes") == 0) + clear = 1; + memset(&stats, 0, sizeof(struct rte_mtr_stats)); ret = rte_mtr_stats_read(port_id, mtr_id, &stats, &stats_mask, clear, &error); diff --git a/app/test-pmd/cmdline_mtr.h b/app/test-pmd/cmdline_mtr.h index 8701a79d82..e5ebf05557 100644 --- a/app/test-pmd/cmdline_mtr.h +++ b/app/test-pmd/cmdline_mtr.h @@ -10,7 +10,7 @@ extern cmdline_parse_inst_t cmd_add_port_meter_profile_srtcm; extern cmdline_parse_inst_t cmd_add_port_meter_profile_trtcm; extern cmdline_parse_inst_t cmd_add_port_meter_profile_trtcm_rfc4115; extern cmdline_parse_inst_t cmd_del_port_meter_profile; -extern cmdline_parse_inst_t cmd_set_port_meter; +extern cmdline_parse_inst_t cmd_create_port_meter; extern cmdline_parse_inst_t cmd_del_port_meter; extern cmdline_parse_inst_t cmd_set_port_meter_profile; extern cmdline_parse_inst_t cmd_set_port_meter_policer_action;