From patchwork Thu Jun 23 12:57:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sunil Kumar Kori X-Patchwork-Id: 113342 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru 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 C2EB2A0093; Thu, 23 Jun 2022 14:57:16 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 673B740042; Thu, 23 Jun 2022 14:57:16 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 8C2A84003F for ; Thu, 23 Jun 2022 14:57:14 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25N9wYU5025936; Thu, 23 Jun 2022 05:57:13 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=QK4G56CdoVNx1lTBdqrFcOgfLuKYG9EYRaYMHoUM8go=; b=b3bp74t27MKt6LJ50oh9dWDk28rUiZRVcTklFqOCT2jBhmFZX6yYGffWZicg772iq2RC 9mngo2wTcCFbXVPTO29zwJv5JlZFGKLJifSImAMnRV+LRlpKnBDgXnP2EpB6w9hBCFh/ yv4IF8wuuo6NwFXknLu8jxGujlvPRlDk5L/Ok5FAv7XFYcjNmNkYE8aAs2ROeo+Ud4d8 XUUQZI5uznOu0tsEaPguIevxSTlMA8d6pcYpadNSLJl2KeZiEOEvQy+Q54Bop19zCo8b 9hY7vZf1ZX9992xj7RNuAEmiaB2fJEAuCXB1ZCsV8ozbD9vu/2lPdLAUBpwF01ePiQPV xw== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3gvp0urq2k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Thu, 23 Jun 2022 05:57:13 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Thu, 23 Jun 2022 05:57:11 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 23 Jun 2022 05:57:12 -0700 Received: from localhost.localdomain (unknown [10.28.34.25]) by maili.marvell.com (Postfix) with ESMTP id B7B065B6921; Thu, 23 Jun 2022 05:57:09 -0700 (PDT) From: To: Xiaoyun Li , Aman Singh , Yuying Zhang , Cristian Dumitrescu CC: , Sunil Kumar Kori Subject: [PATCH v5 1/1] app/testpmd: support different input color method Date: Thu, 23 Jun 2022 18:27:01 +0530 Message-ID: <20220623125701.1136065-1-skori@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220614100518.533931-1-skori@marvell.com> References: <20220614100518.533931-1-skori@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: 226zW5ey8AuJXZDlUI4D5uX_WjkMep84 X-Proofpoint-ORIG-GUID: 226zW5ey8AuJXZDlUI4D5uX_WjkMep84 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-06-23_05,2022-06-23_01,2022-06-22_01 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 From: Sunil Kumar Kori To enable input coloring, based on VLAN or DSCP, patch adds command line interface to configure the following: - configuring input coloring using VLAN or DSCP while creating meter i.e. during rte_mtr_create() - Update VLAN input coloring table at runtime. - configures protocol priorities. - retrieve protocol and priority information Depends-on: patch-22751 ("ethdev: mtr: support protocol based input color selection") Signed-off-by: Sunil Kumar Kori Acked-by: Cristian Dumitrescu --- v4..v5: - Update testpmd user guide. v3..v4: - Replace strcmp with strcasecmp whereever is needed. v2..v3: - Rebased to branch ToT dpdk-next-net/main - Fix static keyword for newly added token parsing symbols v1..v2: - Rebased to branch dpdk-next-net - add CLIs for input coloring mechanism app/test-pmd/cmdline.c | 4 + app/test-pmd/cmdline_mtr.c | 552 +++++++++++++++++++- app/test-pmd/cmdline_mtr.h | 4 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 35 +- 4 files changed, 587 insertions(+), 8 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 9a7fd5fc35..ded7dfe656 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -14345,6 +14345,10 @@ static cmdline_parse_ctx_t builtin_ctx[] = { (cmdline_parse_inst_t *)&cmd_del_port_meter_policy, (cmdline_parse_inst_t *)&cmd_set_port_meter_profile, (cmdline_parse_inst_t *)&cmd_set_port_meter_dscp_table, + (cmdline_parse_inst_t *)&cmd_set_port_meter_vlan_table, + (cmdline_parse_inst_t *)&cmd_set_port_meter_in_proto, + (cmdline_parse_inst_t *)&cmd_get_port_meter_in_proto, + (cmdline_parse_inst_t *)&cmd_get_port_meter_in_proto_prio, (cmdline_parse_inst_t *)&cmd_set_port_meter_stats_mask, (cmdline_parse_inst_t *)&cmd_show_port_meter_stats, (cmdline_parse_inst_t *)&cmd_mcast_addr, diff --git a/app/test-pmd/cmdline_mtr.c b/app/test-pmd/cmdline_mtr.c index 57050ec9af..b92e66cedb 100644 --- a/app/test-pmd/cmdline_mtr.c +++ b/app/test-pmd/cmdline_mtr.c @@ -14,6 +14,7 @@ #include "cmdline_mtr.h" #define PARSE_DELIMITER " \f\n\r\t\v" +#define MAX_VLAN_TABLE_ENTRIES 16 #define MAX_DSCP_TABLE_ENTRIES 64 /** Display Meter Error Message */ @@ -82,6 +83,122 @@ parse_uint(uint64_t *value, const char *str) return 0; } +static int +parse_input_color_table_entries(char *str, enum rte_color **dscp_table, + enum rte_color **vlan_table) +{ + enum rte_color *vlan, *dscp; + char *token; + int i = 0; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) + return 0; + + /* Allocate memory for dscp table */ + dscp = (enum rte_color *)malloc(MAX_DSCP_TABLE_ENTRIES * + sizeof(enum rte_color)); + if (dscp == NULL) + return -1; + + while (1) { + if (strcasecmp(token, "G") == 0) + dscp[i++] = RTE_COLOR_GREEN; + else if (strcasecmp(token, "Y") == 0) + dscp[i++] = RTE_COLOR_YELLOW; + else if (strcasecmp(token, "R") == 0) + dscp[i++] = RTE_COLOR_RED; + else { + free(dscp); + return -1; + } + if (i == MAX_DSCP_TABLE_ENTRIES) + break; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) { + free(dscp); + return -1; + } + } + + *dscp_table = dscp; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) + return 0; + + /* Allocate memory for vlan table */ + vlan = (enum rte_color *)malloc(MAX_VLAN_TABLE_ENTRIES * + sizeof(enum rte_color)); + if (vlan == NULL) + return -1; + + i = 0; + while (1) { + if (strcasecmp(token, "G") == 0) + vlan[i++] = RTE_COLOR_GREEN; + else if (strcasecmp(token, "Y") == 0) + vlan[i++] = RTE_COLOR_YELLOW; + else if (strcasecmp(token, "R") == 0) + vlan[i++] = RTE_COLOR_RED; + else { + free(vlan); + return -1; + } + if (i == MAX_VLAN_TABLE_ENTRIES) + break; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) { + free(vlan); + return -1; + } + } + + *vlan_table = vlan; + return 0; +} + +static int +parse_vlan_table_entries(char *str, enum rte_color **vlan_table) +{ + char *token; + int i = 0; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) + return 0; + + /* Allocate memory for vlan table */ + *vlan_table = (enum rte_color *)malloc(MAX_VLAN_TABLE_ENTRIES * + sizeof(enum rte_color)); + if (*vlan_table == NULL) + return -1; + + while (1) { + if (strcasecmp(token, "G") == 0) + (*vlan_table)[i++] = RTE_COLOR_GREEN; + else if (strcasecmp(token, "Y") == 0) + (*vlan_table)[i++] = RTE_COLOR_YELLOW; + else if (strcasecmp(token, "R") == 0) + (*vlan_table)[i++] = RTE_COLOR_RED; + else { + free(*vlan_table); + return -1; + } + if (i == MAX_VLAN_TABLE_ENTRIES) + break; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) { + free(*vlan_table); + return -1; + } + } + return 0; +} + static int parse_dscp_table_entries(char *str, enum rte_color **dscp_table) { @@ -124,9 +241,30 @@ parse_dscp_table_entries(char *str, enum rte_color **dscp_table) return 0; } +static int +parse_default_input_color_str(char *str, uint64_t *def_inp_color) +{ + char *token; + + token = strtok_r(str, PARSE_DELIMITER, &str); + if (token == NULL) + return 0; + + if (strcasecmp(token, "G") == 0) + *def_inp_color = RTE_COLOR_GREEN; + else if (strcasecmp(token, "Y") == 0) + *def_inp_color = RTE_COLOR_YELLOW; + else if (strcasecmp(token, "R") == 0) + *def_inp_color = RTE_COLOR_RED; + else + return -1; + + return 0; +} + static int parse_meter_color_str(char *c_str, uint32_t *use_prev_meter_color, - enum rte_color **dscp_table) + enum rte_color **vlan_table, enum rte_color **dscp_table) { char *token; uint64_t previous_mtr_color = 0; @@ -147,8 +285,7 @@ parse_meter_color_str(char *c_str, uint32_t *use_prev_meter_color, return 0; } - /* Parse dscp table entries */ - ret = parse_dscp_table_entries(c_str, dscp_table); + ret = parse_input_color_table_entries(c_str, dscp_table, vlan_table); if (ret != 0) return -1; @@ -192,6 +329,43 @@ parse_multi_token_string(char *t_str, uint16_t *port_id, return 0; } +static int +parse_multi_token_vlan_str(char *t_str, uint16_t *port_id, uint32_t *mtr_id, + enum rte_color **vlan_table) +{ + uint64_t val; + char *token; + int ret; + + /* First token: port id */ + token = strtok_r(t_str, PARSE_DELIMITER, &t_str); + if (token == NULL) + return -1; + + ret = parse_uint(&val, token); + if (ret != 0 || val > UINT16_MAX) + return -1; + + *port_id = val; + + /* Second token: meter id */ + token = strtok_r(t_str, PARSE_DELIMITER, &t_str); + if (token == NULL) + return 0; + + ret = parse_uint(&val, token); + if (ret != 0 || val > UINT32_MAX) + return -1; + + *mtr_id = val; + + ret = parse_vlan_table_entries(t_str, vlan_table); + if (ret != 0) + return -1; + + return 0; +} + /* *** Show Port Meter Capabilities *** */ struct cmd_show_port_meter_cap_result { cmdline_fixed_string_t show; @@ -277,6 +451,10 @@ static void cmd_show_port_meter_cap_parsed(void *parsed_result, printf("cap.trtcm_rfc4115_packet_mode_supported %" PRId32 "\n", cap.trtcm_rfc4115_packet_mode_supported); printf("cap.stats_mask %" PRIx64 "\n", cap.stats_mask); + printf("cap.input_color_proto_mask 0x%" PRIx64 "\n", + cap.input_color_proto_mask); + printf("cap.separate_input_color_table_per_port %" PRId32 "\n", + cap.separate_input_color_table_per_port); } cmdline_parse_inst_t cmd_show_port_meter_cap = { @@ -721,6 +899,7 @@ struct cmd_create_port_meter_result { cmdline_fixed_string_t r_action; uint64_t statistics_mask; uint32_t shared; + cmdline_fixed_string_t default_input_color; cmdline_multi_string_t meter_input_color; }; @@ -754,6 +933,9 @@ static cmdline_parse_token_num_t cmd_create_port_meter_statistics_mask = static cmdline_parse_token_num_t cmd_create_port_meter_shared = TOKEN_NUM_INITIALIZER(struct cmd_create_port_meter_result, shared, RTE_UINT32); +static cmdline_parse_token_string_t cmd_create_port_meter_default_input_color = + TOKEN_STRING_INITIALIZER(struct cmd_create_port_meter_result, + default_input_color, "R#Y#G#r#y#g"); static 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); @@ -769,7 +951,10 @@ static void cmd_create_port_meter_parsed(void *parsed_result, uint32_t shared = res->shared; uint32_t use_prev_meter_color = 0; uint16_t port_id = res->port_id; + uint64_t def_inp_color = 0; enum rte_color *dscp_table = NULL; + enum rte_color *vlan_table = NULL; + char *def_color_str = res->default_input_color; char *c_str = res->meter_input_color; int ret; @@ -780,8 +965,18 @@ static void cmd_create_port_meter_parsed(void *parsed_result, memset(¶ms, 0, sizeof(struct rte_mtr_params)); params.meter_profile_id = res->profile_id; params.meter_policy_id = res->policy_id; + + /* Parse meter default input color string params */ + ret = parse_default_input_color_str(def_color_str, &def_inp_color); + if (ret) { + fprintf(stderr, + " Meter default input color is invalid\n"); + return; + } + /* Parse meter input color string params */ - ret = parse_meter_color_str(c_str, &use_prev_meter_color, &dscp_table); + ret = parse_meter_color_str(c_str, &use_prev_meter_color, &vlan_table, + &dscp_table); if (ret) { fprintf(stderr, " Meter input color params string parse error\n"); @@ -789,16 +984,20 @@ static void cmd_create_port_meter_parsed(void *parsed_result, } params.use_prev_mtr_color = use_prev_meter_color; + params.vlan_table = vlan_table; params.dscp_table = dscp_table; + params.default_input_color = def_inp_color; if (strcmp(res->meter_enable, "yes") == 0) params.meter_enable = 1; else params.meter_enable = 0; + params.stats_mask = res->statistics_mask; ret = rte_mtr_create(port_id, mtr_id, ¶ms, shared, &error); if (ret != 0) { + free(vlan_table); free(dscp_table); print_err_msg(&error); return; @@ -809,8 +1008,10 @@ cmdline_parse_inst_t cmd_create_port_meter = { .f = cmd_create_port_meter_parsed, .data = NULL, .help_str = "create port meter " - "(yes|no) " - "[ ...]", + "(yes|no) " + "(g|y|r) " + "[ ...] " + "[ ... ]", .tokens = { (void *)&cmd_create_port_meter_create, (void *)&cmd_create_port_meter_port, @@ -822,6 +1023,7 @@ cmdline_parse_inst_t cmd_create_port_meter = { (void *)&cmd_create_port_meter_meter_enable, (void *)&cmd_create_port_meter_statistics_mask, (void *)&cmd_create_port_meter_shared, + (void *)&cmd_create_port_meter_default_input_color, (void *)&cmd_create_port_meter_input_color, NULL, }, @@ -1224,6 +1426,344 @@ cmdline_parse_inst_t cmd_set_port_meter_dscp_table = { }, }; +/* *** Set Port Meter VLAN Table *** */ +struct cmd_set_port_meter_vlan_table_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + cmdline_fixed_string_t meter; + cmdline_fixed_string_t vlan_table; + cmdline_multi_string_t token_string; +}; + +static cmdline_parse_token_string_t cmd_set_port_meter_vlan_table_set = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_vlan_table_result, set, "set"); +static cmdline_parse_token_string_t cmd_set_port_meter_vlan_table_port = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_vlan_table_result, port, "port"); +static cmdline_parse_token_string_t cmd_set_port_meter_vlan_table_meter = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_vlan_table_result, meter, "meter"); +static cmdline_parse_token_string_t cmd_set_port_meter_vlan_table_vlan_table = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_vlan_table_result, + vlan_table, "vlan table"); +static cmdline_parse_token_string_t cmd_set_port_meter_vlan_table_token_string = + TOKEN_STRING_INITIALIZER(struct cmd_set_port_meter_vlan_table_result, + token_string, TOKEN_STRING_MULTI); + +static void cmd_set_port_meter_vlan_table_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_set_port_meter_vlan_table_result *res = parsed_result; + struct rte_mtr_error error; + enum rte_color *vlan_table = NULL; + char *t_str = res->token_string; + uint32_t mtr_id = 0; + uint16_t port_id; + int ret; + + /* Parse string */ + ret = parse_multi_token_vlan_str(t_str, &port_id, &mtr_id, &vlan_table); + if (ret) { + fprintf(stderr, " Multi token string parse error\n"); + return; + } + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + goto free_table; + + /* Update Meter VLAN Table*/ + ret = rte_mtr_meter_vlan_table_update(port_id, mtr_id, + vlan_table, &error); + if (ret != 0) + print_err_msg(&error); + +free_table: + free(vlan_table); +} + +cmdline_parse_inst_t cmd_set_port_meter_vlan_table = { + .f = cmd_set_port_meter_vlan_table_parsed, + .data = NULL, + .help_str = "set port meter vlan table " + "[ ... ]", + .tokens = { + (void *)&cmd_set_port_meter_vlan_table_set, + (void *)&cmd_set_port_meter_vlan_table_port, + (void *)&cmd_set_port_meter_vlan_table_meter, + (void *)&cmd_set_port_meter_vlan_table_vlan_table, + (void *)&cmd_set_port_meter_vlan_table_token_string, + NULL, + }, +}; + +/* *** Set Port Meter input protocol *** */ +struct cmd_set_port_meter_in_proto_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + cmdline_fixed_string_t meter; + cmdline_fixed_string_t protocol; + cmdline_fixed_string_t proto; + uint32_t prio; + uint32_t mtr_id; + uint16_t port_id; +}; + +static cmdline_parse_token_string_t cmd_set_port_meter_in_proto_set = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, set, "set"); + +static cmdline_parse_token_string_t cmd_set_port_meter_in_proto_port = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, port, "port"); + +static cmdline_parse_token_string_t cmd_set_port_meter_in_proto_meter = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, meter, "meter"); + +static cmdline_parse_token_string_t cmd_set_port_meter_in_proto_protocol = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, protocol, "proto"); + +static cmdline_parse_token_string_t cmd_set_port_meter_in_proto_proto = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, proto, + "outer_vlan#inner_vlan#outer_ip#inner_ip"); + +static cmdline_parse_token_num_t cmd_set_port_meter_in_proto_prio = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, prio, RTE_UINT32); + +static cmdline_parse_token_num_t cmd_set_port_meter_in_proto_port_id = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, port_id, RTE_UINT16); + +static cmdline_parse_token_num_t cmd_set_port_meter_in_proto_mtr_id = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_meter_in_proto_result, mtr_id, RTE_UINT32); + +static void cmd_set_port_meter_in_proto_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_set_port_meter_in_proto_result *res = parsed_result; + enum rte_mtr_color_in_protocol proto; + struct rte_mtr_error error; + int ret; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + if (strcmp(res->proto, "outer_vlan") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN; + else if (strcmp(res->proto, "inner_vlan") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_INNER_VLAN; + else if (strcmp(res->proto, "outer_ip") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_OUTER_IP; + else if (strcmp(res->proto, "inner_ip") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_INNER_IP; + else { + printf("Invalid protocol\n"); + return; + } + + /* Update Meter input proto and priority */ + ret = rte_mtr_color_in_protocol_set(res->port_id, res->mtr_id, + proto, res->prio, &error); + if (ret != 0) + print_err_msg(&error); +} + +cmdline_parse_inst_t cmd_set_port_meter_in_proto = { + .f = cmd_set_port_meter_in_proto_parsed, + .data = NULL, + .help_str = "set port meter proto " + "", + .tokens = { + (void *)&cmd_set_port_meter_in_proto_set, + (void *)&cmd_set_port_meter_in_proto_port, + (void *)&cmd_set_port_meter_in_proto_meter, + (void *)&cmd_set_port_meter_in_proto_protocol, + (void *)&cmd_set_port_meter_in_proto_port_id, + (void *)&cmd_set_port_meter_in_proto_mtr_id, + (void *)&cmd_set_port_meter_in_proto_proto, + (void *)&cmd_set_port_meter_in_proto_prio, + NULL, + }, +}; + +/* *** Get Port Meter input protocol *** */ +struct cmd_get_port_meter_in_proto_result { + cmdline_fixed_string_t get; + cmdline_fixed_string_t port; + cmdline_fixed_string_t meter; + cmdline_fixed_string_t protocol; + uint32_t mtr_id; + uint16_t port_id; +}; + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_get = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_result, get, "get"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_port = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_result, port, "port"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_meter = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_result, meter, "meter"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_protocol = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_result, protocol, "proto"); + +static cmdline_parse_token_num_t cmd_get_port_meter_in_proto_port_id = + TOKEN_NUM_INITIALIZER( + struct cmd_get_port_meter_in_proto_result, port_id, RTE_UINT16); + +static cmdline_parse_token_num_t cmd_get_port_meter_in_proto_mtr_id = + TOKEN_NUM_INITIALIZER( + struct cmd_get_port_meter_in_proto_result, mtr_id, RTE_UINT32); + +static void cmd_get_port_meter_in_proto_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_set_port_meter_in_proto_result *res = parsed_result; + struct rte_mtr_error error; + uint64_t proto_mask = 0; + int ret; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + /* Update Meter input proto and priority */ + ret = rte_mtr_color_in_protocol_get(res->port_id, res->mtr_id, + &proto_mask, &error); + if (ret != 0) + print_err_msg(&error); + + printf("Enabled protocols:\n"); + if (proto_mask & RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN) + printf("\touter_vlan\n"); + if (proto_mask & RTE_MTR_COLOR_IN_PROTO_INNER_VLAN) + printf("\tinner_vlan\n"); + if (proto_mask & RTE_MTR_COLOR_IN_PROTO_OUTER_IP) + printf("\touter_ip\n"); + if (proto_mask & RTE_MTR_COLOR_IN_PROTO_INNER_IP) + printf("\tinner_ip\n"); +} + +cmdline_parse_inst_t cmd_get_port_meter_in_proto = { + .f = cmd_get_port_meter_in_proto_parsed, + .data = NULL, + .help_str = "get port meter proto ", + .tokens = { + (void *)&cmd_get_port_meter_in_proto_get, + (void *)&cmd_get_port_meter_in_proto_port, + (void *)&cmd_get_port_meter_in_proto_meter, + (void *)&cmd_get_port_meter_in_proto_protocol, + (void *)&cmd_get_port_meter_in_proto_port_id, + (void *)&cmd_get_port_meter_in_proto_mtr_id, + NULL, + }, +}; + +/* *** Get Port Meter input protocol priority *** */ +struct cmd_get_port_meter_in_proto_prio_result { + cmdline_fixed_string_t get; + cmdline_fixed_string_t port; + cmdline_fixed_string_t meter; + cmdline_fixed_string_t protocol; + cmdline_fixed_string_t proto; + uint32_t mtr_id; + uint16_t port_id; +}; + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_prio_get = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, get, "get"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_prio_port = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, port, "port"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_prio_meter = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, meter, "meter"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_prio_protocol = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, protocol, + "proto_prio"); + +static cmdline_parse_token_string_t cmd_get_port_meter_in_proto_prio_proto = + TOKEN_STRING_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, proto, + "outer_vlan#inner_vlan#outer_ip#inner_ip"); + +static cmdline_parse_token_num_t cmd_get_port_meter_in_proto_prio_port_id = + TOKEN_NUM_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, port_id, + RTE_UINT16); + +static cmdline_parse_token_num_t cmd_get_port_meter_in_proto_prio_mtr_id = + TOKEN_NUM_INITIALIZER( + struct cmd_get_port_meter_in_proto_prio_result, mtr_id, + RTE_UINT32); + +static void cmd_get_port_meter_in_proto_prio_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_get_port_meter_in_proto_prio_result *res = parsed_result; + enum rte_mtr_color_in_protocol proto; + struct rte_mtr_error error; + uint32_t prio = 0; + int ret; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + + if (strcmp(res->proto, "outer_vlan") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN; + else if (strcmp(res->proto, "inner_vlan") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_INNER_VLAN; + else if (strcmp(res->proto, "outer_ip") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_OUTER_IP; + else if (strcmp(res->proto, "inner_ip") == 0) + proto = RTE_MTR_COLOR_IN_PROTO_INNER_IP; + else { + printf("Invalid protocol\n"); + return; + } + + /* Get Meter input proto and priority */ + ret = rte_mtr_color_in_protocol_priority_get(res->port_id, res->mtr_id, + proto, &prio, &error); + if (ret != 0) + print_err_msg(&error); +} + +cmdline_parse_inst_t cmd_get_port_meter_in_proto_prio = { + .f = cmd_get_port_meter_in_proto_prio_parsed, + .data = NULL, + .help_str = "get port meter proto_prio ", + .tokens = { + (void *)&cmd_get_port_meter_in_proto_prio_get, + (void *)&cmd_get_port_meter_in_proto_prio_port, + (void *)&cmd_get_port_meter_in_proto_prio_meter, + (void *)&cmd_get_port_meter_in_proto_prio_protocol, + (void *)&cmd_get_port_meter_in_proto_prio_port_id, + (void *)&cmd_get_port_meter_in_proto_prio_mtr_id, + (void *)&cmd_get_port_meter_in_proto_prio_proto, + NULL, + }, +}; + /* *** Set Port Meter Stats Mask *** */ struct cmd_set_port_meter_stats_mask_result { cmdline_fixed_string_t set; diff --git a/app/test-pmd/cmdline_mtr.h b/app/test-pmd/cmdline_mtr.h index 2415fc16c3..23eaa5bc03 100644 --- a/app/test-pmd/cmdline_mtr.h +++ b/app/test-pmd/cmdline_mtr.h @@ -19,6 +19,10 @@ extern cmdline_parse_inst_t cmd_del_port_meter; extern cmdline_parse_inst_t cmd_del_port_meter_policy; extern cmdline_parse_inst_t cmd_set_port_meter_profile; extern cmdline_parse_inst_t cmd_set_port_meter_dscp_table; +extern cmdline_parse_inst_t cmd_set_port_meter_vlan_table; +extern cmdline_parse_inst_t cmd_set_port_meter_in_proto; +extern cmdline_parse_inst_t cmd_get_port_meter_in_proto; +extern cmdline_parse_inst_t cmd_get_port_meter_in_proto_prio; extern cmdline_parse_inst_t cmd_set_port_meter_stats_mask; extern cmdline_parse_inst_t cmd_show_port_meter_stats; void print_mtr_err_msg(struct rte_mtr_error *error); diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 0b7a53fdf1..4509a47ed4 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -2527,9 +2527,10 @@ create port meter Create new meter object for the ethernet device:: testpmd> create port meter (port_id) (mtr_id) (profile_id) \ - (policy_id) (meter_enable) (stats_mask) (shared) \ + (policy_id) (meter_enable) (stats_mask) (shared) (default_input_color) \ (use_pre_meter_color) [(dscp_tbl_entry0) (dscp_tbl_entry1)...\ - (dscp_tbl_entry63)] + (dscp_tbl_entry63)] [(vlan_tbl_entry0) (vlan_tbl_entry1) ... \ + (vlan_tbl_entry15)] where: @@ -2542,12 +2543,17 @@ where: meter object. * ``shared``: When this parameter has a non-zero value, the meter object is shared by multiple flows. Otherwise, meter object is used by single flow. +* ``default_input_color``: Default input color for incoming packets. + If incoming packet misses DSCP or VLAN input color table then it will be used + as input color. * ``use_pre_meter_color``: When this parameter has a non-zero value, the input color for the current meter object is determined by the latest meter object in the same flow. Otherwise, the current meter object uses the *dscp_table* to determine the input color. * ``dscp_tbl_entryx``: DSCP table entry x providing meter providing input color, 0 <= x <= 63. +* ``vlan_tbl_entryx``: VLAN table entry x providing meter input color, + 0 <= x <= 15. enable port meter ~~~~~~~~~~~~~~~~~ @@ -2585,6 +2591,31 @@ Set meter dscp table for the ethernet device:: testpmd> set port meter dscp table (port_id) (mtr_id) [(dscp_tbl_entry0) \ (dscp_tbl_entry1)...(dscp_tbl_entry63)] +set port meter vlan table +~~~~~~~~~~~~~~~~~~~~~~~~~ +Set meter vlan table for the ethernet device:: + + testpmd> set port meter vlan table (port_id) (mtr_id) [(vlan_tbl_entry0) \ + (vlan_tbl_entry1)...(vlan_tbl_entry15)] + +set port meter protocol +~~~~~~~~~~~~~~~~~~~~~~~ +Set meter protocol and corresponding priority:: + + testpmd> set port meter proto (port_id) (mtr_id) (proto) (prio) + +get port meter protocol +~~~~~~~~~~~~~~~~~~~~~~~ +Get meter protocol:: + + testpmd> get port meter proto (port_id) (mtr_id) + +get port meter protocol priority +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Get priority associated to meter protocol:: + + testpmd> get port meter proto_prio (port_id) (mtr_id) (proto) + set port meter stats mask ~~~~~~~~~~~~~~~~~~~~~~~~~