From patchwork Mon Apr 19 16:08:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawei Wang X-Patchwork-Id: 91775 X-Patchwork-Delegate: ferruh.yigit@amd.com 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 9D3C6A0524; Mon, 19 Apr 2021 18:08:38 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 665A6413A2; Mon, 19 Apr 2021 18:08:33 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by mails.dpdk.org (Postfix) with ESMTP id 1846341393 for ; Mon, 19 Apr 2021 18:08:30 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jiaweiw@nvidia.com) with SMTP; 19 Apr 2021 19:08:27 +0300 Received: from nvidia.com (gen-l-vrt-281.mtl.labs.mlnx [10.237.44.1]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 13JG8QLs024825; Mon, 19 Apr 2021 19:08:26 +0300 From: Jiawei Wang To: matan@nvidia.com, orika@nvidia.com, viacheslavo@nvidia.com, shahafs@nvidia.com, Xiaoyun Li Cc: dev@dpdk.org, thomas@monjalon.net, rasland@nvidia.com, roniba@nvidia.com, Haifei Luo Date: Mon, 19 Apr 2021 19:08:25 +0300 Message-Id: <1618848506-37569-3-git-send-email-jiaweiw@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1618848506-37569-1-git-send-email-jiaweiw@nvidia.com> References: <20210415092023.2089541-1-lizh@nvidia.com> <1618848506-37569-1-git-send-email-jiaweiw@nvidia.com> Subject: [dpdk-dev] [PATCH v9 2/2] app/testpmd: support policy actions per color 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 Sender: "dev" From: Haifei Luo Add the create/del policy CLIs to support actions per color. The CLIs are: Create: add port meter policy (port_id) (policy_id) g_actions (actions) y_actions (actions) r_actions (actions) Delete: del port meter policy (port_id) (policy_id) Examples: testpmd> add port meter policy 0 1 g_actions rss / end y_actions end r_actions drop / end testpmd> del port meter policy 0 1 Signed-off-by: Haifei Luo Acked-by: Matan Azrad --- app/test-pmd/cmdline.c | 13 ++- app/test-pmd/cmdline_flow.c | 118 +++++++++++++++++++++++++++- app/test-pmd/cmdline_mtr.c | 85 ++++++++++++++++++-- app/test-pmd/cmdline_mtr.h | 3 + app/test-pmd/config.c | 32 ++++++++ app/test-pmd/testpmd.h | 2 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 30 ++++++- 7 files changed, 269 insertions(+), 14 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index e244df2..35452db 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -705,9 +705,8 @@ static void cmd_help_long_parsed(void *parsed_result, "del port meter profile (port_id) (profile_id)\n" " meter profile delete\n\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" + "create port meter (port_id) (mtr_id) (profile_id) (policy_id) (meter_enable)\n" + "(stats_mask) (shared) (use_pre_meter_color) [(dscp_tbl_entry0) (dscp_tbl_entry1)...\n" "(dscp_tbl_entry63)]\n" " meter create\n\n" @@ -720,6 +719,13 @@ static void cmd_help_long_parsed(void *parsed_result, "del port meter (port_id) (mtr_id)\n" " meter delete\n\n" + "add port meter policy (port_id) (policy_id) g_actions (actions)\n" + "y_actions (actions) r_actions (actions)\n" + " meter policy add\n\n" + + "del port meter policy (port_id) (policy_id)\n" + " meter policy delete\n\n" + "set port meter profile (port_id) (mtr_id) (profile_id)\n" " meter update meter profile\n\n" @@ -17072,6 +17078,7 @@ struct cmd_showport_macs_result { (cmdline_parse_inst_t *)&cmd_enable_port_meter, (cmdline_parse_inst_t *)&cmd_disable_port_meter, (cmdline_parse_inst_t *)&cmd_del_port_meter, + (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_stats_mask, diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 0127d9e..1d69eb9 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -55,6 +55,10 @@ enum index { GROUP_ID, PRIORITY_LEVEL, SHARED_ACTION_ID, + POLICY_ID, + + /* TOP-level command. */ + ADD, /* Top-level command. */ SET, @@ -293,6 +297,9 @@ enum index { ITEM_GENEVE_OPT_TYPE, ITEM_GENEVE_OPT_LENGTH, ITEM_GENEVE_OPT_DATA, + ITEM_POL_PORT, + ITEM_POL_METER, + ITEM_POL_POLICY, /* Validate/create actions. */ ACTIONS, @@ -431,6 +438,9 @@ enum index { ACTION_MODIFY_FIELD_SRC_OFFSET, ACTION_MODIFY_FIELD_SRC_VALUE, ACTION_MODIFY_FIELD_WIDTH, + ACTION_POL_G, + ACTION_POL_Y, + ACTION_POL_R, }; /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -814,6 +824,9 @@ struct buffer { struct { int destroy; } aged; /**< Aged arguments. */ + struct { + uint32_t policy_id; + } policy;/**< Policy arguments. */ } args; /**< Command arguments. */ }; @@ -1797,6 +1810,9 @@ static int parse_ipv6_addr(struct context *, const struct token *, static int parse_port(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_mp(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_sa(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1835,7 +1851,7 @@ static int comp_set_modify_field_id(struct context *, const struct token *, [ZERO] = { .name = "ZERO", .help = "null entry, abused as the entry point", - .next = NEXT(NEXT_ENTRY(FLOW)), + .next = NEXT(NEXT_ENTRY(FLOW, ADD)), }, [END] = { .name = "", @@ -1957,6 +1973,13 @@ static int comp_set_modify_field_id(struct context *, const struct token *, .call = parse_int, .comp = comp_none, }, + [POLICY_ID] = { + .name = "{policy_id}", + .type = "POLCIY_ID", + .help = "policy id", + .call = parse_int, + .comp = comp_none, + }, /* Top-level command. */ [FLOW] = { .name = "flow", @@ -4555,6 +4578,54 @@ static int comp_set_modify_field_id(struct context *, const struct token *, .help = "specify action to share", .next = NEXT(next_action), }, + [ACTION_POL_G] = { + .name = "g_actions", + .help = "submit a list of associated actions for green", + .next = NEXT(next_action), + .call = parse_mp, + }, + [ACTION_POL_Y] = { + .name = "y_actions", + .help = "submit a list of associated actions for yellow", + .next = NEXT(next_action), + }, + [ACTION_POL_R] = { + .name = "r_actions", + .help = "submit a list of associated actions for red", + .next = NEXT(next_action), + }, + + /* Top-level command. */ + [ADD] = { + .name = "add", + .type = "port meter policy {port_id} {arg}", + .help = "add port meter policy", + .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), + .call = parse_init, + }, + /* Sub-level commands. */ + [ITEM_POL_PORT] = { + .name = "port", + .help = "add port meter policy", + .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), + }, + [ITEM_POL_METER] = { + .name = "meter", + .help = "add port meter policy", + .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), + }, + [ITEM_POL_POLICY] = { + .name = "policy", + .help = "add port meter policy", + .next = NEXT(NEXT_ENTRY(ACTION_POL_R), + NEXT_ENTRY(ACTION_POL_Y), + NEXT_ENTRY(ACTION_POL_G), + NEXT_ENTRY(POLICY_ID), + NEXT_ENTRY(PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), + ARGS_ENTRY(struct buffer, port)), + .call = parse_mp, + }, }; /** Remove and return last entry from argument stack. */ @@ -4739,6 +4810,47 @@ static int comp_set_modify_field_id(struct context *, const struct token *, return len; } +/** Parse tokens for meter policy action commands. */ +static int +parse_mp(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->command) { + if (ctx->curr != ITEM_POL_POLICY) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + out->args.vc.data = (uint8_t *)out + size; + return len; + } + switch (ctx->curr) { + case ACTION_POL_G: + out->args.vc.actions = + (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), + sizeof(double)); + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + return len; + default: + return -1; + } +} + /** Parse tokens for shared action commands. */ static int parse_sa(struct context *ctx, const struct token *token, @@ -7726,6 +7838,10 @@ static int comp_set_modify_field_id(struct context *, const struct token *, case TUNNEL_LIST: port_flow_tunnel_list(in->port); break; + case ACTION_POL_G: + port_meter_policy_add(in->port, in->args.policy.policy_id, + in->args.vc.actions); + break; default: break; } diff --git a/app/test-pmd/cmdline_mtr.c b/app/test-pmd/cmdline_mtr.c index aa454af..eff2473 100644 --- a/app/test-pmd/cmdline_mtr.c +++ b/app/test-pmd/cmdline_mtr.c @@ -37,6 +37,8 @@ [RTE_MTR_ERROR_TYPE_STATS] = "stats", [RTE_MTR_ERROR_TYPE_SHARED] = "shared meter", + [RTE_MTR_ERROR_TYPE_METER_POLICY_ID] = "meter policy id", + [RTE_MTR_ERROR_TYPE_METER_POLICY] = "meter policy null", }; const char *errstr; @@ -56,6 +58,12 @@ error->type); } +void +print_mtr_err_msg(struct rte_mtr_error *error) +{ + print_err_msg(error); +} + static int parse_uint(uint64_t *value, const char *str) { @@ -705,6 +713,7 @@ struct cmd_create_port_meter_result { uint16_t port_id; uint32_t mtr_id; uint32_t profile_id; + uint32_t policy_id; cmdline_fixed_string_t meter_enable; cmdline_fixed_string_t g_action; cmdline_fixed_string_t y_action; @@ -732,6 +741,9 @@ struct cmd_create_port_meter_result { cmdline_parse_token_num_t cmd_create_port_meter_profile_id = TOKEN_NUM_INITIALIZER( struct cmd_create_port_meter_result, profile_id, RTE_UINT32); +cmdline_parse_token_num_t cmd_create_port_meter_policy_id = + TOKEN_NUM_INITIALIZER( + struct cmd_create_port_meter_result, policy_id, RTE_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"); @@ -775,7 +787,7 @@ static void cmd_create_port_meter_parsed(void *parsed_result, /* Meter params */ memset(¶ms, 0, sizeof(struct rte_mtr_params)); params.meter_profile_id = res->profile_id; - + params.meter_policy_id = res->policy_id; /* Parse meter input color string params */ ret = parse_meter_color_str(c_str, &use_prev_meter_color, &dscp_table); if (ret) { @@ -790,7 +802,6 @@ static void cmd_create_port_meter_parsed(void *parsed_result, 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); @@ -805,7 +816,6 @@ static void cmd_create_port_meter_parsed(void *parsed_result, .f = cmd_create_port_meter_parsed, .data = NULL, .help_str = "create port meter (yes|no) " - "(R|Y|G|D) (R|Y|G|D) (R|Y|G|D) " " " "[ ...]", .tokens = { @@ -815,10 +825,8 @@ static void cmd_create_port_meter_parsed(void *parsed_result, (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_policy_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, @@ -948,6 +956,71 @@ static void cmd_disable_port_meter_parsed(void *parsed_result, }, }; +/* *** Delete Port Meter Policy Object *** */ +struct cmd_del_port_meter_policy_result { + cmdline_fixed_string_t del; + cmdline_fixed_string_t port; + cmdline_fixed_string_t meter; + cmdline_fixed_string_t policy; + uint16_t port_id; + uint32_t policy_id; +}; + +cmdline_parse_token_string_t cmd_del_port_meter_policy_del = + TOKEN_STRING_INITIALIZER( + struct cmd_del_port_meter_policy_result, del, "del"); +cmdline_parse_token_string_t cmd_del_port_meter_policy_port = + TOKEN_STRING_INITIALIZER( + struct cmd_del_port_meter_policy_result, port, "port"); +cmdline_parse_token_string_t cmd_del_port_meter_policy_meter = + TOKEN_STRING_INITIALIZER( + struct cmd_del_port_meter_policy_result, meter, "meter"); +cmdline_parse_token_string_t cmd_del_port_meter_policy_policy = + TOKEN_STRING_INITIALIZER( + struct cmd_del_port_meter_policy_result, policy, "policy"); +cmdline_parse_token_num_t cmd_del_port_meter_policy_port_id = + TOKEN_NUM_INITIALIZER( + struct cmd_del_port_meter_policy_result, port_id, RTE_UINT16); +cmdline_parse_token_num_t cmd_del_port_meter_policy_policy_id = + TOKEN_NUM_INITIALIZER( + struct cmd_del_port_meter_policy_result, policy_id, RTE_UINT32); + +static void cmd_del_port_meter_policy_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_del_port_meter_policy_result *res = parsed_result; + struct rte_mtr_error error; + uint32_t policy_id = res->policy_id; + uint16_t port_id = res->port_id; + int ret; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + /* Delete Meter Policy*/ + ret = rte_mtr_meter_policy_delete(port_id, policy_id, &error); + if (ret != 0) { + print_err_msg(&error); + return; + } +} + +cmdline_parse_inst_t cmd_del_port_meter_policy = { + .f = cmd_del_port_meter_policy_parsed, + .data = NULL, + .help_str = "Delete port meter policy", + .tokens = { + (void *)&cmd_del_port_meter_policy_del, + (void *)&cmd_del_port_meter_policy_port, + (void *)&cmd_del_port_meter_policy_meter, + (void *)&cmd_del_port_meter_policy_policy, + (void *)&cmd_del_port_meter_policy_port_id, + (void *)&cmd_del_port_meter_policy_policy_id, + NULL, + }, +}; + /* *** Delete Port Meter Object *** */ struct cmd_del_port_meter_result { cmdline_fixed_string_t del; diff --git a/app/test-pmd/cmdline_mtr.h b/app/test-pmd/cmdline_mtr.h index 7e2713c..2415fc1 100644 --- a/app/test-pmd/cmdline_mtr.h +++ b/app/test-pmd/cmdline_mtr.h @@ -4,6 +4,7 @@ #ifndef _CMDLINE_MTR_H_ #define _CMDLINE_MTR_H_ +#include /* Traffic Metering and Policing */ extern cmdline_parse_inst_t cmd_show_port_meter_cap; @@ -15,9 +16,11 @@ extern cmdline_parse_inst_t cmd_enable_port_meter; extern cmdline_parse_inst_t cmd_disable_port_meter; 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_stats_mask; extern cmdline_parse_inst_t cmd_show_port_meter_stats; +void print_mtr_err_msg(struct rte_mtr_error *error); #endif /* _CMDLINE_MTR_H_ */ diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index d4b0e85..5e81d24 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef RTE_NET_IXGBE #include @@ -52,6 +53,7 @@ #include #include "testpmd.h" +#include "cmdline_mtr.h" #define ETHDEV_FWVERS_LEN 32 @@ -1464,6 +1466,36 @@ void port_flow_tunnel_create(portid_t port_id, const struct tunnel_ops *ops) return 0; } +/** Add port meter policy */ +int +port_meter_policy_add(portid_t port_id, uint32_t policy_id, + const struct rte_flow_action *actions) +{ + struct rte_mtr_error error; + const struct rte_flow_action *act = actions; + const struct rte_flow_action *start; + struct rte_mtr_meter_policy_params policy; + uint32_t i = 0, act_n; + int ret; + + for (i = 0; i < RTE_COLORS; i++) { + for (act_n = 0, start = act; + act->type != RTE_FLOW_ACTION_TYPE_END; act++) + act_n++; + if (act_n && act->type == RTE_FLOW_ACTION_TYPE_END) + policy.actions[i] = start; + else + policy.actions[i] = NULL; + act++; + } + ret = rte_mtr_meter_policy_add(port_id, + policy_id, + &policy, &error); + if (ret) + print_mtr_err_msg(&error); + return ret; +} + /** Create shared action */ int port_shared_action_create(portid_t port_id, uint32_t id, diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 36d8535..2a9c24b 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -838,6 +838,8 @@ struct port_flow_tunnel * void port_flow_tunnel_destroy(portid_t port_id, uint32_t tunnel_id); void port_flow_tunnel_create(portid_t port_id, const struct tunnel_ops *ops); int port_flow_isolate(portid_t port_id, int set); +int port_meter_policy_add(portid_t port_id, uint32_t policy_id, + const struct rte_flow_action *actions); void rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id); void tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id); diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index e3e2c34..232468e 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -2765,13 +2765,37 @@ Delete meter profile from the ethernet device:: testpmd> del port meter profile (port_id) (profile_id) +create port policy +~~~~~~~~~~~~~~~~~~ + +Create new policy object for the ethernet device:: + + testpmd> add port meter policy (port_id) (policy_id) g_actions \ + {action} y_actions {action} r_actions {action} + +where: + +* ``policy_id``: policy ID. +* ``action``: action lists for green/yellow/red colors. + +delete port policy +~~~~~~~~~~~~~~~~~~ + +Delete policy object for the ethernet device:: + + testpmd> del port meter policy (port_id) (policy_id) + +where: + +* ``policy_id``: policy ID. + create port meter ~~~~~~~~~~~~~~~~~ Create new meter object for the ethernet device:: testpmd> create port meter (port_id) (mtr_id) (profile_id) \ - (meter_enable) (g_action) (y_action) (r_action) (stats_mask) (shared) \ + (policy_id) (meter_enable) (stats_mask) (shared) \ (use_pre_meter_color) [(dscp_tbl_entry0) (dscp_tbl_entry1)...\ (dscp_tbl_entry63)] @@ -2779,11 +2803,9 @@ where: * ``mtr_id``: meter object ID. * ``profile_id``: ID for the meter profile. +* ``policy_id``: ID for the policy. * ``meter_enable``: When this parameter has a non-zero value, the meter object gets enabled at the time of creation, otherwise remains disabled. -* ``g_action``: Policer action for the packet with green color. -* ``y_action``: Policer action for the packet with yellow color. -* ``r_action``: Policer action for the packet with red color. * ``stats_mask``: Mask of statistics counter types to be enabled for the meter object. * ``shared``: When this parameter has a non-zero value, the meter object is