From: Gregory Etelson <getel...@nvidia.com> Syntax: actions .. indirect_list handle H conf C ..
H references shared action resources related to that handle. C references configuration array: if H was created from a list of actions A1 / A2 / ... / END, C[i] points to a flow configuration update of A[i]. Signed-off-by: Gregory Etelson <getel...@nvidia.com> --- app/test-pmd/cmdline_flow.c | 227 +++++++++++++++++++++++++++++++++--- app/test-pmd/config.c | 5 +- app/test-pmd/testpmd.h | 2 +- 3 files changed, 215 insertions(+), 19 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 7eb8e045b4..1644328bf4 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -66,6 +66,7 @@ enum index { COMMON_ACTIONS_TEMPLATE_ID, COMMON_TABLE_ID, COMMON_QUEUE_ID, + COMMON_METER_COLOR_NAME, /* TOP-level command. */ ADD, @@ -253,6 +254,7 @@ enum index { /* Indirect action arguments */ INDIRECT_ACTION_CREATE, INDIRECT_ACTION_LIST_CREATE, + INDIRECT_ACTION_FLOW_CONF_CREATE, INDIRECT_ACTION_UPDATE, INDIRECT_ACTION_DESTROY, INDIRECT_ACTION_QUERY, @@ -265,6 +267,7 @@ enum index { INDIRECT_ACTION_TRANSFER, INDIRECT_ACTION_SPEC, INDIRECT_ACTION_LIST, + INDIRECT_ACTION_FLOW_CONF, /* Indirect action destroy arguments */ INDIRECT_ACTION_DESTROY_ID, @@ -529,7 +532,6 @@ enum index { ITEM_PPP_PROTO_ID, ITEM_METER, ITEM_METER_COLOR, - ITEM_METER_COLOR_NAME, ITEM_QUOTA, ITEM_QUOTA_STATE, ITEM_QUOTA_STATE_NAME, @@ -585,6 +587,8 @@ enum index { ACTION_METER_COLOR_RED, ACTION_METER_ID, ACTION_METER_MARK, + ACTION_METER_MARK_CONF, + ACTION_METER_MARK_CONF_COLOR, ACTION_METER_PROFILE, ACTION_METER_PROFILE_ID2PTR, ACTION_METER_POLICY, @@ -669,6 +673,10 @@ enum index { ACTION_SAMPLE_INDEX_VALUE, ACTION_INDIRECT, ACTION_INDIRECT_LIST, + ACTION_INDIRECT_LIST_HANDLE, + ACTION_INDIRECT_LIST_CONF, + INDIRECT_LIST_ACTION_ID2PTR_HANDLE, + INDIRECT_LIST_ACTION_ID2PTR_CONF, ACTION_SHARED_INDIRECT, INDIRECT_ACTION_ID2PTR, ACTION_MODIFY_FIELD, @@ -1366,6 +1374,7 @@ static const enum index next_ia_create_attr[] = { INDIRECT_ACTION_TRANSFER, INDIRECT_ACTION_SPEC, INDIRECT_ACTION_LIST, + INDIRECT_ACTION_FLOW_CONF, ZERO, }; @@ -1375,6 +1384,13 @@ static const enum index next_ia[] = { ZERO }; +static const enum index next_ial[] = { + ACTION_INDIRECT_LIST_HANDLE, + ACTION_INDIRECT_LIST_CONF, + ACTION_NEXT, + ZERO +}; + static const enum index next_shia[] = { COMMON_INDIRECT_ACTION_PORT, ACTION_NEXT, @@ -2075,6 +2091,7 @@ static const enum index next_action[] = { ACTION_METER, ACTION_METER_COLOR, ACTION_METER_MARK, + ACTION_METER_MARK_CONF, ACTION_OF_DEC_NW_TTL, ACTION_OF_POP_VLAN, ACTION_OF_PUSH_VLAN, @@ -2754,6 +2771,10 @@ static int parse_ia_destroy(struct context *ctx, const struct token *token, static int parse_ia_id2ptr(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, unsigned int size); + +static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size); static int parse_ia_port(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, unsigned int size); @@ -2842,6 +2863,16 @@ static int comp_insertion_table_type(struct context *, const struct token *, static int comp_hash_table_type(struct context *, const struct token *, unsigned int, char *, unsigned int); +struct indlst_conf { + uint32_t id; + uint32_t conf_num; + struct rte_flow_action *actions; + const void **conf; + SLIST_ENTRY(indlst_conf) next; +}; + +static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); + /** Token definitions. */ static const struct token token_list[] = { /* Special tokens. */ @@ -3026,6 +3057,12 @@ static const struct token token_list[] = { .call = parse_int, .comp = comp_queue_id, }, + [COMMON_METER_COLOR_NAME] = { + .name = "color_name", + .help = "meter color name", + .call = parse_meter_color, + .comp = comp_meter_color, + }, /* Top-level command. */ [FLOW] = { .name = "flow", @@ -5769,17 +5806,11 @@ static const struct token token_list[] = { .name = "color", .help = "meter color", .next = NEXT(item_meter, - NEXT_ENTRY(ITEM_METER_COLOR_NAME), + NEXT_ENTRY(COMMON_METER_COLOR_NAME), item_param), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, color)), }, - [ITEM_METER_COLOR_NAME] = { - .name = "color_name", - .help = "meter color name", - .call = parse_meter_color, - .comp = comp_meter_color, - }, [ITEM_QUOTA] = { .name = "quota", .help = "match quota", @@ -6165,6 +6196,23 @@ static const struct token token_list[] = { .next = NEXT(action_meter_mark), .call = parse_vc, }, + [ACTION_METER_MARK_CONF] = { + .name = "meter_mark_conf", + .help = "meter mark configuration", + .priv = PRIV_ACTION(METER_MARK, + sizeof(struct rte_flow_action_meter_mark)), + .next = NEXT(NEXT_ENTRY(ACTION_METER_MARK_CONF_COLOR)), + .call = parse_vc, + }, + [ACTION_METER_MARK_CONF_COLOR] = { + .name = "mtr_update_init_color", + .help = "meter update init color", + .next = NEXT(NEXT_ENTRY(ACTION_NEXT), + NEXT_ENTRY(COMMON_METER_COLOR_NAME)), + .args = ARGS(ARGS_ENTRY + (struct rte_flow_indirect_update_flow_meter_mark, + init_color)), + }, [ACTION_METER_PROFILE] = { .name = "mtr_profile", .help = "meter profile id to use", @@ -7277,11 +7325,36 @@ static const struct token token_list[] = { [ACTION_INDIRECT_LIST] = { .name = "indirect_list", .help = "apply indirect list action by id", - .priv = PRIV_ACTION(INDIRECT_LIST, 0), - .next = NEXT(next_ia), - .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), + .priv = PRIV_ACTION(INDIRECT_LIST, + sizeof(struct + rte_flow_action_indirect_list)), + .next = NEXT(next_ial), .call = parse_vc, }, + [ACTION_INDIRECT_LIST_HANDLE] = { + .name = "handle", + .help = "indirect list handle", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [ACTION_INDIRECT_LIST_CONF] = { + .name = "conf", + .help = "indirect list configuration", + .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), + .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))), + }, + [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, +// .comp = comp_none, + }, + [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { + .type = "UNSIGNED", + .help = "unsigned integer value", + .call = parse_indlst_id2ptr, +// .comp = comp_none, + }, [ACTION_SHARED_INDIRECT] = { .name = "shared_indirect", .help = "apply indirect action by id and port", @@ -7336,6 +7409,12 @@ static const struct token token_list[] = { .next = NEXT(NEXT_ENTRY(ACTIONS, END)), .call = parse_ia, }, + [INDIRECT_ACTION_FLOW_CONF] = { + .name = "flow_conf", + .help = "specify actions configuration for indirect handle list", + .next = NEXT(NEXT_ENTRY(ACTIONS, END)), + .call = parse_ia, + }, [ACTION_POL_G] = { .name = "g_actions", .help = "submit a list of associated actions for green", @@ -7811,6 +7890,9 @@ parse_ia(struct context *ctx, const struct token *token, case INDIRECT_ACTION_LIST: out->command = INDIRECT_ACTION_LIST_CREATE; return len; + case INDIRECT_ACTION_FLOW_CONF: + out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; + return len; default: return -1; } @@ -11317,6 +11399,49 @@ parse_ia_id2ptr(struct context *ctx, const struct token *token, return ret; } +static int +parse_indlst_id2ptr(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void __rte_unused *buf, unsigned int __rte_unused size) +{ + struct rte_flow_action *action = ctx->object; + struct rte_flow_action_indirect_list *action_conf; + const struct indlst_conf *indlst_conf; + uint32_t id; + int ret; + + if (!action) + return -1; + ctx->objdata = 0; + ctx->object = &id; + ctx->objmask = NULL; + ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); + if (ret != (int)len) + return ret; + ctx->object = action; + action_conf = (void *)(uintptr_t)action->conf; + action_conf->conf = NULL; + switch (ctx->curr) { + case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: + action_conf->handle = (typeof(action_conf->handle)) + port_action_handle_get_by_id(ctx->port, id); + if (!action_conf->handle) { + printf("no indirect list handle for id %u\n", id); + return -1; + } + break; + case INDIRECT_LIST_ACTION_ID2PTR_CONF: + indlst_conf = indirect_action_list_conf_get(id); + if (!indlst_conf) + return -1; + action_conf->conf = (const void **)indlst_conf->conf; + break; + default: + break; + } + return ret; +} + static int parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, const char *str, unsigned int len, @@ -11549,11 +11674,10 @@ parse_meter_color(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, unsigned int size) { - struct rte_flow_item_meter_color *meter_color; unsigned int i; + struct buffer *out = buf; (void)token; - (void)buf; (void)size; for (i = 0; meter_colors[i]; ++i) if (!strcmp_partial(meter_colors[i], str, len)) @@ -11562,8 +11686,18 @@ parse_meter_color(struct context *ctx, const struct token *token, return -1; if (!ctx->object) return len; - meter_color = ctx->object; - meter_color->color = (enum rte_color)i; + if (ctx->prev == ACTION_METER_MARK_CONF_COLOR) { + struct rte_flow_action *action = + out->args.vc.actions + out->args.vc.actions_n - 1; + const struct arg *arg = pop_args(ctx); + + if (!arg) + return -1; + *(int *)RTE_PTR_ADD(action->conf, arg->offset) = i; + } else { + ((struct rte_flow_item_meter_color *) + ctx->object)->color = (enum rte_color)i; + } return len; } @@ -12356,6 +12490,64 @@ cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, *hdr = &cmd_flow_token_hdr; } +static SLIST_HEAD(, indlst_conf) indlst_conf_head = + SLIST_HEAD_INITIALIZER(); + +static void +indirect_action_flow_conf_create(const struct buffer *in) +{ + int len, ret; + uint32_t i; + struct indlst_conf *indlst_conf = NULL; + size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); + struct rte_flow_action *src = in->args.vc.actions; + + if (!in->args.vc.actions_n) + goto end; + len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); + if (len <= 0) + goto end; + len = RTE_ALIGN(len, 16); + + indlst_conf = calloc(1, base + len + + in->args.vc.actions_n * sizeof(uintptr_t)); + if (!indlst_conf) + goto end; + indlst_conf->id = in->args.vc.attr.group; + indlst_conf->conf_num = in->args.vc.actions_n - 1; + indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); + ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, + len, src, NULL); + if (ret <= 0) { + free(indlst_conf); + indlst_conf = NULL; + goto end; + } + indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); + for (i = 0; i < indlst_conf->conf_num; i++) + indlst_conf->conf[i] = indlst_conf->actions[i].conf; + SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); +end: + if (indlst_conf) + printf("created indirect action list configuration %u\n", + in->args.vc.attr.group); + else + printf("cannot create indirect action list configuration %u\n", + in->args.vc.attr.group); +} + +static const struct indlst_conf * +indirect_action_list_conf_get(uint32_t conf_id) +{ + const struct indlst_conf *conf; + + SLIST_FOREACH(conf, &indlst_conf_head, next) { + if (conf->id == conf_id) + return conf; + } + return NULL; +} + /** Dispatch parsed buffer to function calls. */ static void cmd_flow_parsed(const struct buffer *in) @@ -12479,6 +12671,7 @@ cmd_flow_parsed(const struct buffer *in) case INDIRECT_ACTION_LIST_CREATE: port_action_handle_create( in->port, in->args.vc.attr.group, + in->command == INDIRECT_ACTION_LIST_CREATE, &((const struct rte_flow_indir_action_conf) { .ingress = in->args.vc.attr.ingress, .egress = in->args.vc.attr.egress, @@ -12486,6 +12679,9 @@ cmd_flow_parsed(const struct buffer *in) }), in->args.vc.actions); break; + case INDIRECT_ACTION_FLOW_CONF_CREATE: + indirect_action_flow_conf_create(in); + break; case INDIRECT_ACTION_DESTROY: port_action_handle_destroy(in->port, in->args.ia_destroy.action_id_n, @@ -12563,6 +12759,7 @@ cmd_flow_parsed(const struct buffer *in) default: break; } + fflush(stdout); } /** Token generator and output processing callback (cmdline API). */ diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 36cfa7fe95..5ae4cb9a25 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1780,21 +1780,20 @@ action_list_handle_create(portid_t port_id, } /** Create indirect action */ int -port_action_handle_create(portid_t port_id, uint32_t id, +port_action_handle_create(portid_t port_id, uint32_t id, bool indirect_list, const struct rte_flow_indir_action_conf *conf, const struct rte_flow_action *action) { struct port_indirect_action *pia; int ret; struct rte_flow_error error; - bool is_indirect_list = action[1].type != RTE_FLOW_ACTION_TYPE_END; ret = action_alloc(port_id, id, &pia); if (ret) return ret; /* Poisoning to make sure PMDs update it in case of error. */ memset(&error, 0x22, sizeof(error)); - ret = is_indirect_list ? + ret = indirect_list ? action_list_handle_create(port_id, pia, conf, action, &error) : action_handle_create(port_id, pia, conf, action, &error); if (ret) { diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index eed5c70608..2e888cb2f9 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -903,7 +903,7 @@ void update_fwd_ports(portid_t new_pid); void set_fwd_eth_peer(portid_t port_id, char *peer_addr); void port_mtu_set(portid_t port_id, uint16_t mtu); -int port_action_handle_create(portid_t port_id, uint32_t id, +int port_action_handle_create(portid_t port_id, uint32_t id, bool indirect_list, const struct rte_flow_indir_action_conf *conf, const struct rte_flow_action *action); int port_action_handle_destroy(portid_t port_id, -- 2.18.1