@@ -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). */
@@ -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) {
@@ -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,