From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0B4CFA04BA; Wed, 7 Oct 2020 20:37:03 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9C70D1B686; Wed, 7 Oct 2020 20:36:35 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 7A8D61B650 for ; Wed, 7 Oct 2020 20:36:32 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from andreyv@nvidia.com) with SMTP; 7 Oct 2020 21:36:29 +0300 Received: from nvidia.com (r-arch-host11.mtr.labs.mlnx [10.213.43.60]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 097IaJpV005729; Wed, 7 Oct 2020 21:36:29 +0300 From: Andrey Vesnovaty To: dev@dpdk.org Cc: jer@marvell.com, jerinjacobk@gmail.com, thomas@monjalon.net, ferruh.yigit@intel.com, stephen@networkplumber.org, bruce.richardson@intel.com, orika@nvidia.com, viacheslavo@nvidia.com, andrey.vesnovaty@gmail.com, mdr@ashroe.eu, nhorman@tuxdriver.com, ajit.khaparde@broadcom.com, samik.gupta@broadcom.com, Wenzhuo Lu , Beilei Xing , Bernard Iremonger Date: Wed, 7 Oct 2020 21:36:07 +0300 Message-Id: <20201007183607.5130-3-andreyv@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201007183607.5130-1-andreyv@nvidia.com> References: <20200702120511.16315-1-andreyv@mellanox.com> <20201007183607.5130-1-andreyv@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v6 2/2] app/testpmd: support shared action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" This patch adds shared action support to testpmd CLI. All shared actions created via testpmd CLI assigned ID for further reference in other CLI commands. Shared action ID supplied as CLI argument or assigned by testpmd is similar to flow ID & limited to scope of testpdm CLI. Create shared action syntax: flow shared_action (port) create {action_id (shared_action_id)} \ (action) / end Create shared action examples: flow shared_action 0 create action_id 100 \ rss queues 1 2 end / end This creates shared rss action with id 100 on port 0. flow shared_action 0 create action_id \ rss queues 0 1 end / end This creates shared rss action with id assigned by tetspmd on port 0. Update shared action syntax: flow shared_action (port) update (shared_action_id) (action) / end Update shared action example: flow shared_action 0 update 100 rss queues 0 3 end / end This updates shared rss action having id 100 on port 0 with rss to queues 0 3 (in create example rss queues were 1 & 2). Destroy shared action syntax: flow shared_action (port) destroy action_id (shared_action_id) \ { action_id (shared_action_id) [...]} Update shared action example: flow shared_action 0 destroy action_id 100 action_id 101 This destroys shared actions having id 100 & 101 Query shared action syntax: flow shared_action (port) query (shared_action_id) Query shared action example: flow shared_action 0 query 100 This queries shared actions having id 100 Use shared action as flow action syntax: flow create (port) ... / end actions {action / [...]} \ shared (action_id) / {action / [...]} end Use shared action as flow action example: flow create 0 ingress pattern ... / end \ actions shared 100 / end This creates flow rule where rss action is shared rss action having id 100. All shared action CLIs report status of the command. Shared action query CLI output depends on action type. Signed-off-by: Andrey Vesnovaty Acked-by: Ori Kam Signed-off-by: Andrey Vesnovaty --- app/test-pmd/cmdline_flow.c | 262 +++++++++++++++++++- app/test-pmd/config.c | 215 ++++++++++++++++ app/test-pmd/testpmd.h | 19 ++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 111 +++++++++ 4 files changed, 606 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 6e04d538ea..402ce69aa3 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -49,6 +49,7 @@ enum index { PORT_ID, GROUP_ID, PRIORITY_LEVEL, + SHARED_ACTION_ID, /* Top-level command. */ SET, @@ -60,6 +61,7 @@ enum index { /* Top-level command. */ FLOW, /* Sub-level commands. */ + SHARED_ACTION, VALIDATE, CREATE, DESTROY, @@ -89,6 +91,18 @@ enum index { EGRESS, TRANSFER, + /* Shared action arguments */ + SHARED_ACTION_CREATE, + SHARED_ACTION_UPDATE, + SHARED_ACTION_DESTROY, + SHARED_ACTION_QUERY, + + /* Shared action create arguments */ + SHARED_ACTION_CREATE_ID, + + /* Shared action destroy arguments */ + SHARED_ACTION_DESTROY_ID, + /* Validate/create pattern. */ PATTERN, ITEM_PARAM_IS, @@ -360,6 +374,8 @@ enum index { ACTION_SET_IPV6_DSCP_VALUE, ACTION_AGE, ACTION_AGE_TIMEOUT, + ACTION_SHARED, + SHARED_ACTION_ID2PTR, }; /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -653,6 +669,13 @@ struct buffer { enum index command; /**< Flow command. */ portid_t port; /**< Affected port ID. */ union { + struct { + uint32_t *action_id; + uint32_t action_id_n; + } sa_destroy; /**< Shared action destroy arguments. */ + struct { + uint32_t action_id; + } sa; /* Shared action query arguments */ struct { struct rte_flow_attr attr; struct rte_flow_item *pattern; @@ -709,6 +732,19 @@ struct parse_action_priv { .size = s, \ }) +static const enum index next_sa_create_attr[] = { + SHARED_ACTION_CREATE_ID, + ACTION_RSS, + ZERO, +}; + +static const enum index next_sa_subcmd[] = { + SHARED_ACTION_CREATE, + SHARED_ACTION_UPDATE, + SHARED_ACTION_DESTROY, + SHARED_ACTION_QUERY, +}; + static const enum index next_vc_attr[] = { GROUP, PRIORITY, @@ -743,6 +779,12 @@ static const enum index next_aged_attr[] = { ZERO, }; +static const enum index next_sa_destroy_attr[] = { + SHARED_ACTION_DESTROY_ID, + END, + ZERO, +}; + static const enum index item_param[] = { ITEM_PARAM_IS, ITEM_PARAM_SPEC, @@ -1193,6 +1235,7 @@ static const enum index next_action[] = { ACTION_SET_IPV4_DSCP, ACTION_SET_IPV6_DSCP, ACTION_AGE, + ACTION_SHARED, ZERO, }; @@ -1550,6 +1593,15 @@ 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_sa(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); +static int parse_sa_destroy(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size); +static int parse_sa_id2ptr(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size); static int comp_none(struct context *, const struct token *, unsigned int, char *, unsigned int); static int comp_boolean(struct context *, const struct token *, @@ -1688,13 +1740,21 @@ static const struct token token_list[] = { .call = parse_int, .comp = comp_none, }, + [SHARED_ACTION_ID] = { + .name = "{shared_action_id}", + .type = "SHARED_ACTION_ID", + .help = "shared action id", + .call = parse_int, + .comp = comp_none, + }, /* Top-level command. */ [FLOW] = { .name = "flow", .type = "{command} {port_id} [{arg} [...]]", .help = "manage ingress/egress flow rules", .next = NEXT(NEXT_ENTRY - (VALIDATE, + (SHARED_ACTION, + VALIDATE, CREATE, DESTROY, FLUSH, @@ -1705,7 +1765,45 @@ static const struct token token_list[] = { ISOLATE)), .call = parse_init, }, + /* Top-level command. */ + [SHARED_ACTION] = { + .name = "shared_action", + .type = "{command} {port_id} [{arg} [...]]", + .help = "manage shared actions", + .next = NEXT(next_sa_subcmd, NEXT_ENTRY(PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, port)), + .call = parse_sa, + }, /* Sub-level commands. */ + [SHARED_ACTION_CREATE] = { + .name = "create", + .help = "create shared action", + .next = NEXT(next_sa_create_attr), + .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), + .call = parse_sa, + }, + [SHARED_ACTION_UPDATE] = { + .name = "update", + .help = "update shared action", + .next = NEXT(NEXT_ENTRY(ACTION_RSS), + NEXT_ENTRY(SHARED_ACTION_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), + .call = parse_sa, + }, + [SHARED_ACTION_DESTROY] = { + .name = "destroy", + .help = "destroy shared action", + .next = NEXT(NEXT_ENTRY(SHARED_ACTION_DESTROY_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, port)), + .call = parse_sa_destroy, + }, + [SHARED_ACTION_QUERY] = { + .name = "query", + .help = "query shared action", + .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(SHARED_ACTION_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.sa.action_id)), + .call = parse_sa, + }, [VALIDATE] = { .name = "validate", .help = "check whether a flow rule can be created", @@ -3859,6 +3957,40 @@ static const struct token token_list[] = { .next = NEXT(action_age, NEXT_ENTRY(UNSIGNED)), .call = parse_vc_conf, }, + /* Shared action destroy arguments. */ + [SHARED_ACTION_DESTROY_ID] = { + .name = "action_id", + .help = "specify a shared action id to destroy", + .next = NEXT(next_sa_destroy_attr, + NEXT_ENTRY(SHARED_ACTION_ID)), + .args = ARGS(ARGS_ENTRY_PTR(struct buffer, + args.sa_destroy.action_id)), + .call = parse_sa_destroy, + }, + /* Shared action create arguments. */ + [SHARED_ACTION_CREATE_ID] = { + .name = "action_id", + .help = "specify a shared action id to create", + .next = NEXT(NEXT_ENTRY(ACTION_RSS), + NEXT_ENTRY(SHARED_ACTION_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), + }, + [ACTION_SHARED] = { + .name = "shared", + .help = "apply shared action by id", + .priv = PRIV_ACTION(SHARED, 0), + .next = NEXT(NEXT_ENTRY(SHARED_ACTION_ID2PTR)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), + .call = parse_vc, + }, + [SHARED_ACTION_ID2PTR] = { + .name = "{action_id}", + .type = "SHARED_ACTION_ID", + .help = "shared action id", + .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), + .call = parse_sa_id2ptr, + .comp = comp_none, + }, }; /** Remove and return last entry from argument stack. */ @@ -4043,6 +4175,91 @@ parse_init(struct context *ctx, const struct token *token, return len; } +/** Parse tokens for shared action commands. */ +static int +parse_sa(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 != SHARED_ACTION) + 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 SHARED_ACTION_CREATE: + case SHARED_ACTION_UPDATE: + out->args.vc.actions = + (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), + sizeof(double)); + out->args.vc.attr.group = UINT32_MAX; + /* fallthrough */ + case SHARED_ACTION_QUERY: + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + return len; + default: + return -1; + } +} + + +/** Parse tokens for shared action destroy command. */ +static int +parse_sa_destroy(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + uint32_t *action_id; + + /* 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 || out->command == SHARED_ACTION) { + if (ctx->curr != SHARED_ACTION_DESTROY) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + out->args.sa_destroy.action_id = + (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), + sizeof(double)); + return len; + } + action_id = out->args.sa_destroy.action_id + + out->args.sa_destroy.action_id_n++; + if ((uint8_t *)action_id > (uint8_t *)out + size) + return -1; + ctx->objdata = 0; + ctx->object = action_id; + ctx->objmask = NULL; + return len; +} + /** Parse tokens for validate/create commands. */ static int parse_vc(struct context *ctx, const struct token *token, @@ -6110,6 +6327,32 @@ parse_port(struct context *ctx, const struct token *token, return ret; } +static int +parse_sa_id2ptr(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct rte_flow_action *action = ctx->object; + uint32_t id; + int ret; + + (void)buf; + (void)size; + ctx->objdata = 0; + ctx->object = &id; + ctx->objmask = NULL; + ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); + ctx->object = action; + if (ret != (int)len) + return ret; + /* set shared action */ + if (action) { + action->conf = port_shared_action_get_by_id(ctx->port, id); + ret = (action->conf) ? ret : -1; + } + return ret; +} + /** Parse set command, initialize output buffer for subsequent tokens. */ static int parse_set_raw_encap_decap(struct context *ctx, const struct token *token, @@ -6559,6 +6802,23 @@ static void cmd_flow_parsed(const struct buffer *in) { switch (in->command) { + case SHARED_ACTION_CREATE: + port_shared_action_create(in->port, + in->args.vc.attr.group, + in->args.vc.actions); + break; + case SHARED_ACTION_DESTROY: + port_shared_action_destroy(in->port, + in->args.sa_destroy.action_id_n, + in->args.sa_destroy.action_id); + break; + case SHARED_ACTION_UPDATE: + port_shared_action_update(in->port, in->args.vc.attr.group, + in->args.vc.actions); + break; + case SHARED_ACTION_QUERY: + port_shared_action_query(in->port, in->args.sa.action_id); + break; case VALIDATE: port_flow_validate(in->port, &in->args.vc.attr, in->args.vc.pattern, in->args.vc.actions); diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 418ea6dda4..cee3f908ef 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1580,6 +1580,221 @@ rss_config_display(struct rte_flow_action_rss *rss_conf) } } +static struct port_shared_action * +action_get_by_id(portid_t port_id, uint32_t id) +{ + struct rte_port *port; + struct port_shared_action **ppsa; + struct port_shared_action *psa = NULL; + + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return NULL; + port = &ports[port_id]; + ppsa = &port->actions_list; + while (*ppsa) { + if ((*ppsa)->id == id) { + psa = *ppsa; + break; + } + ppsa = &(*ppsa)->next; + } + if (!psa) + printf("Failed to find shared action #%u on port %u\n", + id, port_id); + return psa; +} + +static int +action_alloc(portid_t port_id, uint32_t id, + struct port_shared_action **action) +{ + struct rte_port *port; + struct port_shared_action **ppsa; + struct port_shared_action *psa = NULL; + + *action = NULL; + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return -EINVAL; + port = &ports[port_id]; + if (id == UINT32_MAX) { + /* taking first available ID */ + if (port->actions_list) { + if (port->actions_list->id == UINT32_MAX - 1) { + printf("Highest shared action ID is already" + " assigned, delete it first\n"); + return -ENOMEM; + } + id = port->actions_list->id + 1; + } else { + id = 0; + } + } + psa = calloc(1, sizeof(*psa)); + if (!psa) { + printf("Allocation of port %u shared action failed\n", + port_id); + return -ENOMEM; + } + ppsa = &port->actions_list; + while (*ppsa && (*ppsa)->id > id) + ppsa = &(*ppsa)->next; + if (*ppsa && (*ppsa)->id == id) { + printf("Shared action #%u is already assigned," + " delete it first\n", id); + free(psa); + return -EINVAL; + } + psa->next = *ppsa; + psa->id = id; + *ppsa = psa; + *action = psa; + return 0; +} + +/** Create shared action */ +int +port_shared_action_create(portid_t port_id, uint32_t id, + const struct rte_flow_action *action) +{ + struct port_shared_action *psa; + int ret; + struct rte_flow_error error; + + ret = action_alloc(port_id, id, &psa); + if (ret) + return ret; + /* Poisoning to make sure PMDs update it in case of error. */ + memset(&error, 0x22, sizeof(error)); + psa->action = rte_flow_shared_action_create(port_id, NULL, action, + &error); + if (!psa->action) { + uint32_t destroy_id = psa->id; + port_shared_action_destroy(port_id, 1, &destroy_id); + return port_flow_complain(&error); + } + psa->type = action->type; + printf("Shared action #%u created\n", psa->id); + return 0; +} + +/** Destroy shared action */ +int +port_shared_action_destroy(portid_t port_id, + uint32_t n, + const uint32_t *actions) +{ + struct rte_port *port; + struct port_shared_action **tmp; + uint32_t c = 0; + int ret = 0; + + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return -EINVAL; + port = &ports[port_id]; + tmp = &port->actions_list; + while (*tmp) { + uint32_t i; + + for (i = 0; i != n; ++i) { + struct rte_flow_error error; + struct port_shared_action *psa = *tmp; + + if (actions[i] != psa->id) + continue; + /* + * Poisoning to make sure PMDs update it in case + * of error. + */ + memset(&error, 0x33, sizeof(error)); + + if (psa->action && rte_flow_shared_action_destroy( + port_id, psa->action, &error)) { + ret = port_flow_complain(&error); + continue; + } + *tmp = psa->next; + free(psa); + printf("Shared action #%u destroyed\n", psa->id); + break; + } + if (i == n) + tmp = &(*tmp)->next; + ++c; + } + return ret; +} + + +/** Get shared action by port + id */ +struct rte_flow_shared_action * +port_shared_action_get_by_id(portid_t port_id, uint32_t id) +{ + + struct port_shared_action *psa = action_get_by_id(port_id, id); + + return (psa) ? psa->action : NULL; +} + +/** Update shared action */ +int +port_shared_action_update(portid_t port_id, uint32_t id, + const struct rte_flow_action *action) +{ + struct rte_flow_error error; + struct rte_flow_shared_action *shared_action; + + shared_action = port_shared_action_get_by_id(port_id, id); + if (!shared_action) + return -EINVAL; + if (rte_flow_shared_action_update(port_id, shared_action, action, + &error)) { + return port_flow_complain(&error); + } + printf("Shared action #%u updated\n", id); + return 0; +} + +int +port_shared_action_query(portid_t port_id, uint32_t id) +{ + struct rte_flow_error error; + struct port_shared_action *psa; + uint64_t default_data; + void *data = NULL; + int ret = 0; + + psa = action_get_by_id(port_id, id); + if (!psa) + return -EINVAL; + switch (psa->type) { + case RTE_FLOW_ACTION_TYPE_RSS: + data = &default_data; + break; + default: + printf("Shared action %u (type: %d) on port %u doesn't support" + " query\n", id, psa->type, port_id); + return -1; + } + if (rte_flow_shared_action_query(port_id, psa->action, data, &error)) + ret = port_flow_complain(&error); + switch (psa->type) { + case RTE_FLOW_ACTION_TYPE_RSS: + if (!ret) + printf("Shared RSS action:\n\trefs:%u\n", + *((uint32_t *)data)); + data = NULL; + break; + default: + printf("Shared action %u (type: %d) on port %u doesn't support" + " query\n", id, psa->type, port_id); + ret = -1; + } + return ret; +} + /** Validate flow rule. */ int port_flow_validate(portid_t port_id, diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index c7e7e41a97..a78fc9f3f0 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -142,6 +142,14 @@ struct port_flow { uint8_t data[]; /**< Storage for flow rule description */ }; +/* Descriptor for shared action */ +struct port_shared_action { + struct port_shared_action *next; /**< Next flow in list. */ + uint32_t id; /**< Shared action ID. */ + enum rte_flow_action_type type; /**< Action type. */ + struct rte_flow_shared_action *action; /**< Shared action handle. */ +}; + /** * The data structure associated with each port. */ @@ -172,6 +180,8 @@ struct rte_port { uint32_t mc_addr_nb; /**< nb. of addr. in mc_addr_pool */ uint8_t slave_flag; /**< bonding slave port */ struct port_flow *flow_list; /**< Associated flows. */ + struct port_shared_action *actions_list; + /**< Associated shared actions. */ const struct rte_eth_rxtx_callback *rx_dump_cb[RTE_MAX_QUEUES_PER_PORT+1]; const struct rte_eth_rxtx_callback *tx_dump_cb[RTE_MAX_QUEUES_PER_PORT+1]; /**< metadata value to insert in Tx packets. */ @@ -748,6 +758,14 @@ void port_reg_bit_field_set(portid_t port_id, uint32_t reg_off, uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value); void port_reg_display(portid_t port_id, uint32_t reg_off); void port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t value); +int port_shared_action_create(portid_t port_id, uint32_t id, + const struct rte_flow_action *action); +int port_shared_action_destroy(portid_t port_id, + uint32_t n, const uint32_t *action); +struct rte_flow_shared_action *port_shared_action_get_by_id(portid_t port_id, + uint32_t id); +int port_shared_action_update(portid_t port_id, uint32_t id, + const struct rte_flow_action *action); int port_flow_validate(portid_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_item *pattern, @@ -756,6 +774,7 @@ int port_flow_create(portid_t port_id, const struct rte_flow_attr *attr, const struct rte_flow_item *pattern, const struct rte_flow_action *actions); +int port_shared_action_query(portid_t port_id, uint32_t id); void update_age_action_context(const struct rte_flow_action *actions, struct port_flow *pf); int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule); diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 72bdb1be43..f4b26ed307 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -4382,6 +4382,11 @@ This section lists supported actions and their attributes, if any. - ``dscp_value {unsigned}``: The new DSCP value to be set +- ``shared``: Use shared action created via + ``flow shared_action {port_id} create`` + + - ``shared_action_id {unsigned}``: Shared action ID to use + Destroying flow rules ~~~~~~~~~~~~~~~~~~~~~ @@ -4671,6 +4676,112 @@ If attach ``destroy`` parameter, the command will destroy all the list aged flow testpmd> flow aged 0 Port 0 total aged flows: 0 +Creating shared actions +~~~~~~~~~~~~~~~~~~~~~~~ +``flow shared_action {port_id} create`` creates shared action with optional +shared action ID. It is bound to ``rte_flow_shared_action_create()``:: + + flow shared_action {port_id} create [action_id {shared_action_id}] \ + {action} / end + +If successful, it will show:: + + Shared action #[...] created + +Otherwise, it will complain either that shared action already exists or that +some error occurred:: + + Shared action #[...] is already assigned, delete it first + +:: + + Caught error type [...] ([...]): [...] + +Create shared rss action with id 100 to queues 1 and 2 on port 0:: + + testpmd> flow shared_action 0 create action_id 100 \ + rss queues 1 2 end / end + +Create shared rss action with id assigned by testpmd to queues 1 and 2 on +port 0:: + + testpmd> flow shared_action 0 create action_id \ + rss queues 0 1 end / end + +Updating shared actions +~~~~~~~~~~~~~~~~~~~~~~~ +``flow shared_action {port_id} update`` updates configuration of the shared +action from its shared action ID (as returned by +``flow shared_action {port_id} create``). It is bound to +``rte_flow_shared_action_update()``:: + + flow shared_action {port_id} update {shared_action_id} {action} / end + +If successful, it will show:: + + Shared action #[...] updated + +Otherwise, it will complain either that shared action not found or that some +error occurred:: + + Failed to find shared action #[...] on port [...] + +:: + + Caught error type [...] ([...]): [...] + +Update shared rss action having id 100 on port 0 with rss to queues 0 and 3 +(in create example above rss queues were 1 and 2):: + + testpmd> flow shared_action 0 update 100 rss queues 0 3 end / end + +Destroying shared actions +~~~~~~~~~~~~~~~~~~~~~~~~~ +``flow shared_action {port_id} update`` destroys one or more shared actions +from their shared action IDs (as returned by +``flow shared_action {port_id} create``). It is bound to +``rte_flow_shared_action_destroy()``:: + + flow shared_action {port_id} destroy action_id {shared_action_id} [...] + +If successful, it will show:: + + Shared action #[...] destroyed + +It does not report anything for shared action IDs that do not exist. +The usual error message is shown when a shared action cannot be destroyed:: + + Caught error type [...] ([...]): [...] + +Destroy shared actions having id 100 & 101:: + + testpmd> flow shared_action 0 destroy action_id 100 action_id 101 + +Query shared actions +~~~~~~~~~~~~~~~~~~~~ +``flow shared_action {port_id} query`` queries the shared action from its +shared action ID (as returned by ``flow shared_action {port_id} create``). +It is bound to ``rte_flow_shared_action_query()``:: + + flow shared_action {port_id} query {shared_action_id} + +Currently only rss shared action supported. If successful, it will show:: + + Shared RSS action: + refs:[...] + +Otherwise, it will complain either that shared action not found or that some +error occurred:: + + Failed to find shared action #[...] on port [...] + +:: + + Caught error type [...] ([...]): [...] + +Query shared action having id 100:: + + testpmd> flow shared_action 0 query 100 Sample QinQ flow rules ~~~~~~~~~~~~~~~~~~~~~~ -- 2.26.2