Add testpmd CLI interface for the group set miss actions API: flow group 0 group_id 1 ingress set_miss_actions jump group 3 / end flow group 0 group_id 1 ingress set_miss_actions end
Signed-off-by: Tomer Shmilovich <tshmilov...@nvidia.com> Acked-by: Ori Kam <or...@nvidia.com> --- app/test-pmd/cmdline_flow.c | 112 ++++++++++++++++++++++++++++++++++++ app/test-pmd/config.c | 27 +++++++++ app/test-pmd/testpmd.h | 2 + 3 files changed, 141 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 94827bcc4a..b3b8893e37 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -86,6 +86,7 @@ enum index { PATTERN_TEMPLATE, ACTIONS_TEMPLATE, TABLE, + FLOW_GROUP, INDIRECT_ACTION, VALIDATE, CREATE, @@ -206,6 +207,13 @@ enum index { TABLE_PATTERN_TEMPLATE, TABLE_ACTIONS_TEMPLATE, + /* Group arguments */ + GROUP_ID, + GROUP_INGRESS, + GROUP_EGRESS, + GROUP_TRANSFER, + GROUP_SET_MISS_ACTIONS, + /* Tunnel arguments. */ TUNNEL_CREATE, TUNNEL_CREATE_TYPE, @@ -1293,6 +1301,14 @@ static const enum index next_at_destroy_attr[] = { ZERO, }; +static const enum index next_group_attr[] = { + GROUP_INGRESS, + GROUP_EGRESS, + GROUP_TRANSFER, + GROUP_SET_MISS_ACTIONS, + ZERO, +}; + static const enum index next_table_subcmd[] = { TABLE_CREATE, TABLE_DESTROY, @@ -2678,6 +2694,9 @@ static int parse_push(struct context *, const struct token *, static int parse_pull(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_group(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_tunnel(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -3021,6 +3040,7 @@ static const struct token token_list[] = { PATTERN_TEMPLATE, ACTIONS_TEMPLATE, TABLE, + FLOW_GROUP, INDIRECT_ACTION, VALIDATE, CREATE, @@ -3411,6 +3431,46 @@ static const struct token token_list[] = { .call = parse_table, }, /* Top-level command. */ + [FLOW_GROUP] = { + .name = "group", + .help = "manage flow groups", + .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, port)), + .call = parse_group, + }, + /* Sub-level commands. */ + [GROUP_SET_MISS_ACTIONS] = { + .name = "set_miss_actions", + .help = "set group miss actions", + .next = NEXT(next_action), + .call = parse_group, + }, + /* Group arguments */ + [GROUP_ID] = { + .name = "group_id", + .help = "group id", + .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), + }, + [GROUP_INGRESS] = { + .name = "ingress", + .help = "group ingress attr", + .next = NEXT(next_group_attr), + .call = parse_group, + }, + [GROUP_EGRESS] = { + .name = "egress", + .help = "group egress attr", + .next = NEXT(next_group_attr), + .call = parse_group, + }, + [GROUP_TRANSFER] = { + .name = "transfer", + .help = "group transfer attr", + .next = NEXT(next_group_attr), + .call = parse_group, + }, + /* Top-level command. */ [QUEUE] = { .name = "queue", .help = "queue a flow rule operation", @@ -10449,6 +10509,54 @@ parse_pull(struct context *ctx, const struct token *token, return len; } +static int +parse_group(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 != FLOW_GROUP) + 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 GROUP_INGRESS: + out->args.vc.attr.ingress = 1; + return len; + case GROUP_EGRESS: + out->args.vc.attr.egress = 1; + return len; + case GROUP_TRANSFER: + out->args.vc.attr.transfer = 1; + return len; + case GROUP_SET_MISS_ACTIONS: + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), + sizeof(double)); + return len; + default: + return -1; + } +} + static int parse_flex(struct context *ctx, const struct token *token, const char *str, unsigned int len, @@ -12329,6 +12437,10 @@ cmd_flow_parsed(const struct buffer *in) in->args.table_destroy.table_id_n, in->args.table_destroy.table_id); break; + case GROUP_SET_MISS_ACTIONS: + port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, + in->args.vc.actions); + break; case QUEUE_CREATE: port_queue_flow_create(in->port, in->queue, in->postpone, in->args.vc.table_id, in->args.vc.rule_id, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 3d1da99307..709864bb44 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -3514,6 +3514,33 @@ port_queue_flow_pull(portid_t port_id, queueid_t queue_id) return ret; } +/* Set group miss actions */ +int +port_queue_group_set_miss_actions(portid_t port_id, const struct rte_flow_attr *attr, + const struct rte_flow_action *actions) +{ + struct rte_flow_group_attr gattr = { + .ingress = attr->ingress, + .egress = attr->egress, + .transfer = attr->transfer, + }; + struct rte_flow_error error; + int ret = 0; + + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return -EINVAL; + + memset(&error, 0x66, sizeof(error)); + ret = rte_flow_group_set_miss_actions(port_id, attr->group, &gattr, actions, &error); + + if (ret < 0) + return port_flow_complain(&error); + + printf("Group #%u set miss actions succeeded\n", attr->group); + return ret; +} + /** Create flow rule. */ int port_flow_create(portid_t port_id, diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index f1df6a8faf..e69b76f380 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -979,6 +979,8 @@ int port_flow_template_table_create(portid_t port_id, uint32_t id, int port_flow_template_table_destroy(portid_t port_id, uint32_t n, const uint32_t *table); int port_flow_template_table_flush(portid_t port_id); +int port_queue_group_set_miss_actions(portid_t port_id, const struct rte_flow_attr *attr, + const struct rte_flow_action *actions); int port_queue_flow_create(portid_t port_id, queueid_t queue_id, bool postpone, uint32_t table_id, uint32_t rule_idx, uint32_t pattern_idx, uint32_t actions_idx, -- 2.34.1