ethdev: introduce indirect flow action

Right now, rte_flow_shared_action_* APIs are used for some shared
actions, like RSS, count. The shared action should be created before
using it inside a flow. These shared actions sometimes are not
really shared but just some indirect actions decoupled from a flow.

The new functions rte_flow_action_handle_* are added to replace
the current shared functions rte_flow_shared_action_*.

There are two types of flow actions:
1. the direct (normal) actions that could be created and stored
   within a flow rule. Such action is tied to its flow rule and
   cannot be reused.
2. the indirect action, in the past, named shared_action. It is
   created from a direct actioni, like count or rss, and then used
   in the flow rules with an object handle. The PMD will take care
   of the retrieve from indirect action to the direct action
   when it is referenced.

The indirect action is accessed (update / query) w/o any flow rule,
just via the action object handle. For example, when querying or
resetting a counter, it could be done out of any flow using this
counter, but only the handle of the counter action object is
required.
The indirect action object could be shared by different flows or
used by a single flow, depending on the direct action type and
the real-life requirements.
The handle of an indirect action object is opaque and defined in
each driver and possibly different per direct action type.

The old name "shared" is improper in a sense and should be replaced.

Since the APIs are changed from "rte_flow_shared_action*" to the new
"rte_flow_action_handle*", the testpmd application code and command
line interfaces also need to be updated to do the adaption.
The testpmd application user guide is also updated. All the "shared
action" related parts are replaced with "indirect action" to have a
correct explanation.

The parameter of "update" interface is also changed. A general
pointer will replace the rte_flow_action struct pointer due to the
facts:
1. Some action may not support fields updating. In the example of a
   counter, the only "update" supported should be the reset. So
   passing a rte_flow_action struct pointer is meaningless and
   there is even no such corresponding action struct. What's more,
   if more than one operations should be supported, for some other
   action, such pointer parameter may not meet the need.
2. Some action may need conditional or partial update, the current
   parameter will not provide the ability to indicate which part(s)
   to update.
   For different types of indirect action objects, the pointer could
   either be the same of rte_flow_action* struct - in order not to
   break the current driver implementation, or some wrapper
   structures with bits as masks to indicate which part to be
   updated, depending on real needs of the corresponding direct
   action. For different direct actions, the structures of indirect
   action objects updating will be different.

All the underlayer PMD callbacks will be moved to these new APIs.

The RTE_FLOW_ACTION_TYPE_SHARED is kept for now in order not to
break the ABI. All the implementations are changed by using
RTE_FLOW_ACTION_TYPE_INDIRECT.

Since the APIs are changed from "rte_flow_shared_action*" to the new
"rte_flow_action_handle*" and the "update" interface's 3rd input
parameter is changed to generic pointer, the mlx5 PMD that uses these
APIs needs to do the adaption to the new APIs as well.

Signed-off-by: Bing Zhao <bingz@nvidia.com>
Acked-by: Andrey Vesnovaty <andreyv@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
This commit is contained in:
Bing Zhao 2021-04-19 22:38:29 +08:00 committed by Ferruh Yigit
parent 1c1eb759e9
commit 4b61b8774b
16 changed files with 602 additions and 566 deletions

View File

@ -1002,23 +1002,23 @@ static void cmd_help_long_parsed(void *parsed_result,
" List and destroy aged flows"
" flow rules\n\n"
"flow shared_action {port_id} create"
" [action_id {shared_action_id}]"
"flow indirect_action {port_id} create"
" [action_id {indirect_action_id}]"
" [ingress] [egress]"
" action {action} / end\n"
" Create shared action.\n\n"
" Create indirect action.\n\n"
"flow shared_action {port_id} update"
" {shared_action_id} action {action} / end\n"
" Update shared action.\n\n"
"flow indirect_action {port_id} update"
" {indirect_action_id} action {action} / end\n"
" Update indirect action.\n\n"
"flow shared_action {port_id} destroy"
" action_id {shared_action_id} [...]\n"
" Destroy specific shared actions.\n\n"
"flow indirect_action {port_id} destroy"
" action_id {indirect_action_id} [...]\n"
" Destroy specific indirect actions.\n\n"
"flow shared_action {port_id} query"
" {shared_action_id}\n"
" Query an existing shared action.\n\n"
"flow indirect_action {port_id} query"
" {indirect_action_id}\n"
" Query an existing indirect action.\n\n"
"set vxlan ip-version (ipv4|ipv6) vni (vni) udp-src"
" (udp-src) udp-dst (udp-dst) ip-src (ip-src) ip-dst"

View File

@ -54,7 +54,7 @@ enum index {
PORT_ID,
GROUP_ID,
PRIORITY_LEVEL,
SHARED_ACTION_ID,
INDIRECT_ACTION_ID,
/* Top-level command. */
SET,
@ -68,7 +68,7 @@ enum index {
/* Top-level command. */
FLOW,
/* Sub-level commands. */
SHARED_ACTION,
INDIRECT_ACTION,
VALIDATE,
CREATE,
DESTROY,
@ -112,21 +112,21 @@ enum index {
DUMP_ALL,
DUMP_ONE,
/* Shared action arguments */
SHARED_ACTION_CREATE,
SHARED_ACTION_UPDATE,
SHARED_ACTION_DESTROY,
SHARED_ACTION_QUERY,
/* Indirect action arguments */
INDIRECT_ACTION_CREATE,
INDIRECT_ACTION_UPDATE,
INDIRECT_ACTION_DESTROY,
INDIRECT_ACTION_QUERY,
/* Shared action create arguments */
SHARED_ACTION_CREATE_ID,
SHARED_ACTION_INGRESS,
SHARED_ACTION_EGRESS,
SHARED_ACTION_TRANSFER,
SHARED_ACTION_SPEC,
/* Indirect action create arguments */
INDIRECT_ACTION_CREATE_ID,
INDIRECT_ACTION_INGRESS,
INDIRECT_ACTION_EGRESS,
INDIRECT_ACTION_TRANSFER,
INDIRECT_ACTION_SPEC,
/* Shared action destroy arguments */
SHARED_ACTION_DESTROY_ID,
/* Indirect action destroy arguments */
INDIRECT_ACTION_DESTROY_ID,
/* Validate/create pattern. */
PATTERN,
@ -416,8 +416,8 @@ enum index {
ACTION_SAMPLE_RATIO,
ACTION_SAMPLE_INDEX,
ACTION_SAMPLE_INDEX_VALUE,
ACTION_SHARED,
SHARED_ACTION_ID2PTR,
ACTION_INDIRECT,
INDIRECT_ACTION_ID2PTR,
ACTION_MODIFY_FIELD,
ACTION_MODIFY_FIELD_OP,
ACTION_MODIFY_FIELD_OP_VALUE,
@ -778,10 +778,10 @@ struct buffer {
struct {
uint32_t *action_id;
uint32_t action_id_n;
} sa_destroy; /**< Shared action destroy arguments. */
} ia_destroy; /**< Indirect action destroy arguments. */
struct {
uint32_t action_id;
} sa; /* Shared action query arguments */
} ia; /* Indirect action query arguments */
struct {
struct rte_flow_attr attr;
struct tunnel_ops tunnel_ops;
@ -841,12 +841,12 @@ struct parse_action_priv {
.size = s, \
})
static const enum index next_sa_create_attr[] = {
SHARED_ACTION_CREATE_ID,
SHARED_ACTION_INGRESS,
SHARED_ACTION_EGRESS,
SHARED_ACTION_TRANSFER,
SHARED_ACTION_SPEC,
static const enum index next_ia_create_attr[] = {
INDIRECT_ACTION_CREATE_ID,
INDIRECT_ACTION_INGRESS,
INDIRECT_ACTION_EGRESS,
INDIRECT_ACTION_TRANSFER,
INDIRECT_ACTION_SPEC,
ZERO,
};
@ -856,11 +856,11 @@ static const enum index next_dump_subcmd[] = {
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_ia_subcmd[] = {
INDIRECT_ACTION_CREATE,
INDIRECT_ACTION_UPDATE,
INDIRECT_ACTION_DESTROY,
INDIRECT_ACTION_QUERY,
ZERO,
};
@ -900,8 +900,8 @@ static const enum index next_aged_attr[] = {
ZERO,
};
static const enum index next_sa_destroy_attr[] = {
SHARED_ACTION_DESTROY_ID,
static const enum index next_ia_destroy_attr[] = {
INDIRECT_ACTION_DESTROY_ID,
END,
ZERO,
};
@ -1380,7 +1380,7 @@ static const enum index next_action[] = {
ACTION_SET_IPV6_DSCP,
ACTION_AGE,
ACTION_SAMPLE,
ACTION_SHARED,
ACTION_INDIRECT,
ACTION_MODIFY_FIELD,
ZERO,
};
@ -1797,13 +1797,13 @@ 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 *,
static int parse_ia(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
static int parse_sa_destroy(struct context *ctx, const struct token *token,
static int parse_ia_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,
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 comp_none(struct context *, const struct token *,
@ -1950,10 +1950,10 @@ 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",
[INDIRECT_ACTION_ID] = {
.name = "{indirect_action_id}",
.type = "INDIRECT_ACTION_ID",
.help = "indirect action id",
.call = parse_int,
.comp = comp_none,
},
@ -1963,7 +1963,7 @@ static const struct token token_list[] = {
.type = "{command} {port_id} [{arg} [...]]",
.help = "manage ingress/egress flow rules",
.next = NEXT(NEXT_ENTRY
(SHARED_ACTION,
(INDIRECT_ACTION,
VALIDATE,
CREATE,
DESTROY,
@ -1977,42 +1977,42 @@ static const struct token token_list[] = {
.call = parse_init,
},
/* Top-level command. */
[SHARED_ACTION] = {
.name = "shared_action",
[INDIRECT_ACTION] = {
.name = "indirect_action",
.type = "{command} {port_id} [{arg} [...]]",
.help = "manage shared actions",
.next = NEXT(next_sa_subcmd, NEXT_ENTRY(PORT_ID)),
.help = "manage indirect actions",
.next = NEXT(next_ia_subcmd, NEXT_ENTRY(PORT_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
.call = parse_sa,
.call = parse_ia,
},
/* Sub-level commands. */
[SHARED_ACTION_CREATE] = {
[INDIRECT_ACTION_CREATE] = {
.name = "create",
.help = "create shared action",
.next = NEXT(next_sa_create_attr),
.call = parse_sa,
.help = "create indirect action",
.next = NEXT(next_ia_create_attr),
.call = parse_ia,
},
[SHARED_ACTION_UPDATE] = {
[INDIRECT_ACTION_UPDATE] = {
.name = "update",
.help = "update shared action",
.next = NEXT(NEXT_ENTRY(SHARED_ACTION_SPEC),
NEXT_ENTRY(SHARED_ACTION_ID)),
.help = "update indirect action",
.next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC),
NEXT_ENTRY(INDIRECT_ACTION_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
.call = parse_sa,
.call = parse_ia,
},
[SHARED_ACTION_DESTROY] = {
[INDIRECT_ACTION_DESTROY] = {
.name = "destroy",
.help = "destroy shared action",
.next = NEXT(NEXT_ENTRY(SHARED_ACTION_DESTROY_ID)),
.help = "destroy indirect action",
.next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
.call = parse_sa_destroy,
.call = parse_ia_destroy,
},
[SHARED_ACTION_QUERY] = {
[INDIRECT_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,
.help = "query indirect action",
.next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(INDIRECT_ACTION_ID)),
.args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)),
.call = parse_ia,
},
[VALIDATE] = {
.name = "validate",
@ -4498,61 +4498,61 @@ static const struct token token_list[] = {
.call = parse_vc_action_sample_index,
.comp = comp_set_sample_index,
},
/* Shared action destroy arguments. */
[SHARED_ACTION_DESTROY_ID] = {
/* Indirect action destroy arguments. */
[INDIRECT_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)),
.help = "specify a indirect action id to destroy",
.next = NEXT(next_ia_destroy_attr,
NEXT_ENTRY(INDIRECT_ACTION_ID)),
.args = ARGS(ARGS_ENTRY_PTR(struct buffer,
args.sa_destroy.action_id)),
.call = parse_sa_destroy,
args.ia_destroy.action_id)),
.call = parse_ia_destroy,
},
/* Shared action create arguments. */
[SHARED_ACTION_CREATE_ID] = {
/* Indirect action create arguments. */
[INDIRECT_ACTION_CREATE_ID] = {
.name = "action_id",
.help = "specify a shared action id to create",
.next = NEXT(next_sa_create_attr,
NEXT_ENTRY(SHARED_ACTION_ID)),
.help = "specify a indirect action id to create",
.next = NEXT(next_ia_create_attr,
NEXT_ENTRY(INDIRECT_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)),
[ACTION_INDIRECT] = {
.name = "indirect",
.help = "apply indirect action by id",
.priv = PRIV_ACTION(INDIRECT, 0),
.next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)),
.args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))),
.call = parse_vc,
},
[SHARED_ACTION_ID2PTR] = {
[INDIRECT_ACTION_ID2PTR] = {
.name = "{action_id}",
.type = "SHARED_ACTION_ID",
.help = "shared action id",
.type = "INDIRECT_ACTION_ID",
.help = "indirect action id",
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_sa_id2ptr,
.call = parse_ia_id2ptr,
.comp = comp_none,
},
[SHARED_ACTION_INGRESS] = {
[INDIRECT_ACTION_INGRESS] = {
.name = "ingress",
.help = "affect rule to ingress",
.next = NEXT(next_sa_create_attr),
.call = parse_sa,
.next = NEXT(next_ia_create_attr),
.call = parse_ia,
},
[SHARED_ACTION_EGRESS] = {
[INDIRECT_ACTION_EGRESS] = {
.name = "egress",
.help = "affect rule to egress",
.next = NEXT(next_sa_create_attr),
.call = parse_sa,
.next = NEXT(next_ia_create_attr),
.call = parse_ia,
},
[SHARED_ACTION_TRANSFER] = {
[INDIRECT_ACTION_TRANSFER] = {
.name = "transfer",
.help = "affect rule to transfer",
.next = NEXT(next_sa_create_attr),
.call = parse_sa,
.next = NEXT(next_ia_create_attr),
.call = parse_ia,
},
[SHARED_ACTION_SPEC] = {
[INDIRECT_ACTION_SPEC] = {
.name = "action",
.help = "specify action to share",
.help = "specify action to create indirect handle",
.next = NEXT(next_action),
},
};
@ -4739,9 +4739,9 @@ parse_init(struct context *ctx, const struct token *token,
return len;
}
/** Parse tokens for shared action commands. */
/** Parse tokens for indirect action commands. */
static int
parse_sa(struct context *ctx, const struct token *token,
parse_ia(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@ -4754,7 +4754,7 @@ parse_sa(struct context *ctx, const struct token *token,
if (!out)
return len;
if (!out->command) {
if (ctx->curr != SHARED_ACTION)
if (ctx->curr != INDIRECT_ACTION)
return -1;
if (sizeof(*out) > size)
return -1;
@ -4766,26 +4766,26 @@ parse_sa(struct context *ctx, const struct token *token,
return len;
}
switch (ctx->curr) {
case SHARED_ACTION_CREATE:
case SHARED_ACTION_UPDATE:
case INDIRECT_ACTION_CREATE:
case INDIRECT_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:
case INDIRECT_ACTION_QUERY:
out->command = ctx->curr;
ctx->objdata = 0;
ctx->object = out;
ctx->objmask = NULL;
return len;
case SHARED_ACTION_EGRESS:
case INDIRECT_ACTION_EGRESS:
out->args.vc.attr.egress = 1;
return len;
case SHARED_ACTION_INGRESS:
case INDIRECT_ACTION_INGRESS:
out->args.vc.attr.ingress = 1;
return len;
case SHARED_ACTION_TRANSFER:
case INDIRECT_ACTION_TRANSFER:
out->args.vc.attr.transfer = 1;
return len;
default:
@ -4794,9 +4794,9 @@ parse_sa(struct context *ctx, const struct token *token,
}
/** Parse tokens for shared action destroy command. */
/** Parse tokens for indirect action destroy command. */
static int
parse_sa_destroy(struct context *ctx, const struct token *token,
parse_ia_destroy(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@ -4809,8 +4809,8 @@ parse_sa_destroy(struct context *ctx, const struct token *token,
/* 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)
if (!out->command || out->command == INDIRECT_ACTION) {
if (ctx->curr != INDIRECT_ACTION_DESTROY)
return -1;
if (sizeof(*out) > size)
return -1;
@ -4818,13 +4818,13 @@ parse_sa_destroy(struct context *ctx, const struct token *token,
ctx->objdata = 0;
ctx->object = out;
ctx->objmask = NULL;
out->args.sa_destroy.action_id =
out->args.ia_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++;
action_id = out->args.ia_destroy.action_id
+ out->args.ia_destroy.action_id_n++;
if ((uint8_t *)action_id > (uint8_t *)out + size)
return -1;
ctx->objdata = 0;
@ -7102,7 +7102,7 @@ parse_port(struct context *ctx, const struct token *token,
}
static int
parse_sa_id2ptr(struct context *ctx, const struct token *token,
parse_ia_id2ptr(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
void *buf, unsigned int size)
{
@ -7119,9 +7119,9 @@ parse_sa_id2ptr(struct context *ctx, const struct token *token,
ctx->object = action;
if (ret != (int)len)
return ret;
/* set shared action */
/* set indirect action */
if (action) {
action->conf = port_shared_action_get_by_id(ctx->port, id);
action->conf = port_action_handle_get_by_id(ctx->port, id);
ret = (action->conf) ? ret : -1;
}
return ret;
@ -7659,27 +7659,27 @@ static void
cmd_flow_parsed(const struct buffer *in)
{
switch (in->command) {
case SHARED_ACTION_CREATE:
port_shared_action_create(
case INDIRECT_ACTION_CREATE:
port_action_handle_create(
in->port, in->args.vc.attr.group,
&((const struct rte_flow_shared_action_conf) {
&((const struct rte_flow_indir_action_conf) {
.ingress = in->args.vc.attr.ingress,
.egress = in->args.vc.attr.egress,
.transfer = in->args.vc.attr.transfer,
}),
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);
case INDIRECT_ACTION_DESTROY:
port_action_handle_destroy(in->port,
in->args.ia_destroy.action_id_n,
in->args.ia_destroy.action_id);
break;
case SHARED_ACTION_UPDATE:
port_shared_action_update(in->port, in->args.vc.attr.group,
case INDIRECT_ACTION_UPDATE:
port_action_handle_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);
case INDIRECT_ACTION_QUERY:
port_action_handle_query(in->port, in->args.ia.action_id);
break;
case VALIDATE:
port_flow_validate(in->port, &in->args.vc.attr,

View File

@ -1391,38 +1391,38 @@ rss_config_display(struct rte_flow_action_rss *rss_conf)
}
}
static struct port_shared_action *
static struct port_indirect_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;
struct port_indirect_action **ppia;
struct port_indirect_action *pia = 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;
ppia = &port->actions_list;
while (*ppia) {
if ((*ppia)->id == id) {
pia = *ppia;
break;
}
ppsa = &(*ppsa)->next;
ppia = &(*ppia)->next;
}
if (!psa)
printf("Failed to find shared action #%u on port %u\n",
if (!pia)
printf("Failed to find indirect action #%u on port %u\n",
id, port_id);
return psa;
return pia;
}
static int
action_alloc(portid_t port_id, uint32_t id,
struct port_shared_action **action)
struct port_indirect_action **action)
{
struct rte_port *port;
struct port_shared_action **ppsa;
struct port_shared_action *psa = NULL;
struct port_indirect_action **ppia;
struct port_indirect_action *pia = NULL;
*action = NULL;
if (port_id_is_invalid(port_id, ENABLED_WARN) ||
@ -1433,7 +1433,7 @@ action_alloc(portid_t port_id, uint32_t id,
/* taking first available ID */
if (port->actions_list) {
if (port->actions_list->id == UINT32_MAX - 1) {
printf("Highest shared action ID is already"
printf("Highest indirect action ID is already"
" assigned, delete it first\n");
return -ENOMEM;
}
@ -1442,70 +1442,70 @@ action_alloc(portid_t port_id, uint32_t id,
id = 0;
}
}
psa = calloc(1, sizeof(*psa));
if (!psa) {
printf("Allocation of port %u shared action failed\n",
pia = calloc(1, sizeof(*pia));
if (!pia) {
printf("Allocation of port %u indirect 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,"
ppia = &port->actions_list;
while (*ppia && (*ppia)->id > id)
ppia = &(*ppia)->next;
if (*ppia && (*ppia)->id == id) {
printf("Indirect action #%u is already assigned,"
" delete it first\n", id);
free(psa);
free(pia);
return -EINVAL;
}
psa->next = *ppsa;
psa->id = id;
*ppsa = psa;
*action = psa;
pia->next = *ppia;
pia->id = id;
*ppia = pia;
*action = pia;
return 0;
}
/** Create shared action */
/** Create indirect action */
int
port_shared_action_create(portid_t port_id, uint32_t id,
const struct rte_flow_shared_action_conf *conf,
port_action_handle_create(portid_t port_id, uint32_t id,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action)
{
struct port_shared_action *psa;
struct port_indirect_action *pia;
int ret;
struct rte_flow_error error;
ret = action_alloc(port_id, id, &psa);
ret = action_alloc(port_id, id, &pia);
if (ret)
return ret;
if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
struct rte_flow_action_age *age =
(struct rte_flow_action_age *)(uintptr_t)(action->conf);
psa->age_type = ACTION_AGE_CONTEXT_TYPE_SHARED_ACTION;
age->context = &psa->age_type;
pia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION;
age->context = &pia->age_type;
}
/* 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, conf, action,
pia->handle = rte_flow_action_handle_create(port_id, conf, action,
&error);
if (!psa->action) {
uint32_t destroy_id = psa->id;
port_shared_action_destroy(port_id, 1, &destroy_id);
if (!pia->handle) {
uint32_t destroy_id = pia->id;
port_action_handle_destroy(port_id, 1, &destroy_id);
return port_flow_complain(&error);
}
psa->type = action->type;
printf("Shared action #%u created\n", psa->id);
pia->type = action->type;
printf("Indirect action #%u created\n", pia->id);
return 0;
}
/** Destroy shared action */
/** Destroy indirect action */
int
port_shared_action_destroy(portid_t port_id,
port_action_handle_destroy(portid_t port_id,
uint32_t n,
const uint32_t *actions)
{
struct rte_port *port;
struct port_shared_action **tmp;
struct port_indirect_action **tmp;
uint32_t c = 0;
int ret = 0;
@ -1519,9 +1519,9 @@ port_shared_action_destroy(portid_t port_id,
for (i = 0; i != n; ++i) {
struct rte_flow_error error;
struct port_shared_action *psa = *tmp;
struct port_indirect_action *pia = *tmp;
if (actions[i] != psa->id)
if (actions[i] != pia->id)
continue;
/*
* Poisoning to make sure PMDs update it in case
@ -1529,14 +1529,14 @@ port_shared_action_destroy(portid_t port_id,
*/
memset(&error, 0x33, sizeof(error));
if (psa->action && rte_flow_shared_action_destroy(
port_id, psa->action, &error)) {
if (pia->handle && rte_flow_action_handle_destroy(
port_id, pia->handle, &error)) {
ret = port_flow_complain(&error);
continue;
}
*tmp = psa->next;
printf("Shared action #%u destroyed\n", psa->id);
free(psa);
*tmp = pia->next;
printf("Indirect action #%u destroyed\n", pia->id);
free(pia);
break;
}
if (i == n)
@ -1547,60 +1547,60 @@ port_shared_action_destroy(portid_t port_id,
}
/** Get shared action by port + id */
struct rte_flow_shared_action *
port_shared_action_get_by_id(portid_t port_id, uint32_t id)
/** Get indirect action by port + id */
struct rte_flow_action_handle *
port_action_handle_get_by_id(portid_t port_id, uint32_t id)
{
struct port_shared_action *psa = action_get_by_id(port_id, id);
struct port_indirect_action *pia = action_get_by_id(port_id, id);
return (psa) ? psa->action : NULL;
return (pia) ? pia->handle : NULL;
}
/** Update shared action */
/** Update indirect action */
int
port_shared_action_update(portid_t port_id, uint32_t id,
port_action_handle_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;
struct rte_flow_action_handle *action_handle;
shared_action = port_shared_action_get_by_id(port_id, id);
if (!shared_action)
action_handle = port_action_handle_get_by_id(port_id, id);
if (!action_handle)
return -EINVAL;
if (rte_flow_shared_action_update(port_id, shared_action, action,
if (rte_flow_action_handle_update(port_id, action_handle, action,
&error)) {
return port_flow_complain(&error);
}
printf("Shared action #%u updated\n", id);
printf("Indirect action #%u updated\n", id);
return 0;
}
int
port_shared_action_query(portid_t port_id, uint32_t id)
port_action_handle_query(portid_t port_id, uint32_t id)
{
struct rte_flow_error error;
struct port_shared_action *psa;
struct port_indirect_action *pia;
uint64_t default_data;
void *data = NULL;
int ret = 0;
psa = action_get_by_id(port_id, id);
if (!psa)
pia = action_get_by_id(port_id, id);
if (!pia)
return -EINVAL;
switch (psa->type) {
switch (pia->type) {
case RTE_FLOW_ACTION_TYPE_RSS:
case RTE_FLOW_ACTION_TYPE_AGE:
data = &default_data;
break;
default:
printf("Shared action %u (type: %d) on port %u doesn't support"
" query\n", id, psa->type, port_id);
printf("Indirect action %u (type: %d) on port %u doesn't"
" support query\n", id, pia->type, port_id);
return -1;
}
if (rte_flow_shared_action_query(port_id, psa->action, data, &error))
if (rte_flow_action_handle_query(port_id, pia->handle, data, &error))
ret = port_flow_complain(&error);
switch (psa->type) {
switch (pia->type) {
case RTE_FLOW_ACTION_TYPE_RSS:
if (!ret)
printf("Shared RSS action:\n\trefs:%u\n",
@ -1622,8 +1622,8 @@ port_shared_action_query(portid_t port_id, uint32_t id)
data = NULL;
break;
default:
printf("Shared action %u (type: %d) on port %u doesn't support"
" query\n", id, psa->type, port_id);
printf("Indirect action %u (type: %d) on port %u doesn't"
" support query\n", id, pia->type, port_id);
ret = -1;
}
return ret;
@ -2065,7 +2065,7 @@ port_flow_aged(portid_t port_id, uint8_t destroy)
enum age_action_context_type *type;
union {
struct port_flow *pf;
struct port_shared_action *psa;
struct port_indirect_action *pia;
} ctx;
if (port_id_is_invalid(port_id, ENABLED_WARN) ||
@ -2115,11 +2115,11 @@ port_flow_aged(portid_t port_id, uint8_t destroy)
&ctx.pf->id))
total++;
break;
case ACTION_AGE_CONTEXT_TYPE_SHARED_ACTION:
ctx.psa = container_of(type, struct port_shared_action,
age_type);
printf("%-20s\t%" PRIu32 "\n", "Shared action",
ctx.psa->id);
case ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION:
ctx.pia = container_of(type,
struct port_indirect_action, age_type);
printf("%-20s\t%" PRIu32 "\n", "Indirect action",
ctx.pia->id);
break;
default:
printf("Error: invalid context type %u\n", port_id);

View File

@ -151,7 +151,7 @@ struct fwd_stream {
*/
enum age_action_context_type {
ACTION_AGE_CONTEXT_TYPE_FLOW,
ACTION_AGE_CONTEXT_TYPE_SHARED_ACTION,
ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION,
};
/** Descriptor for a single flow. */
@ -165,12 +165,12 @@ 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. */
/* Descriptor for indirect action */
struct port_indirect_action {
struct port_indirect_action *next; /**< Next flow in list. */
uint32_t id; /**< Indirect action ID. */
enum rte_flow_action_type type; /**< Action type. */
struct rte_flow_shared_action *action; /**< Shared action handle. */
struct rte_flow_action_handle *handle; /**< Indirect action handle. */
enum age_action_context_type age_type; /**< Age action context type. */
};
@ -222,8 +222,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. */
struct port_indirect_action *actions_list;
/**< Associated indirect actions. */
LIST_HEAD(, port_flow_tunnel) flow_tunnel_list;
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];
@ -801,14 +801,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_shared_action_conf *conf,
int port_action_handle_create(portid_t port_id, uint32_t id,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action);
int port_shared_action_destroy(portid_t port_id,
int port_action_handle_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,
struct rte_flow_action_handle *port_action_handle_get_by_id(portid_t port_id,
uint32_t id);
int port_shared_action_update(portid_t port_id, uint32_t id,
int port_action_handle_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,
@ -820,7 +820,7 @@ int port_flow_create(portid_t port_id,
const struct rte_flow_item *pattern,
const struct rte_flow_action *actions,
const struct tunnel_ops *tunnel_ops);
int port_shared_action_query(portid_t port_id, uint32_t id);
int port_action_handle_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);

View File

@ -1719,7 +1719,7 @@ that counter.
For ports within the same switch domain then the counter id namespace extends
to all ports within that switch domain.
The shared flag is DEPRECATED and ``SHARED`` ``COUNT`` action should be used
The shared flag is DEPRECATED and ``INDIRECT`` ``COUNT`` action should be used
to make shared counters.
.. _table_rte_flow_action_count:
@ -2742,25 +2742,26 @@ packets, and must have a fate action.
| ``actions`` | sub-action list for sampling |
+--------------+---------------------------------+
Action: ``SHARED``
^^^^^^^^^^^^^^^^^^
Action: ``INDIRECT``
^^^^^^^^^^^^^^^^^^^^
Flow utilize shared action by handle as returned from
``rte_flow_shared_action_create()``.
Flow utilize indirect action by handle as returned from
``rte_flow_action_handle_create()``.
The behaviour of the shared action defined by ``action`` argument of type
``struct rte_flow_action`` passed to ``rte_flow_shared_action_create()``.
The behaviour of the indirect action defined by ``action`` argument of type
``struct rte_flow_action`` passed to ``rte_flow_action_handle_create()``.
Multiple flows can use the same shared action.
The shared action can be in-place updated by ``rte_flow_shared_action_update()``
without destroying flow and creating flow again.
The indirect action can be used by a single flow or shared among multiple flows.
The indirect action can be in-place updated by ``rte_flow_action_handle_update()``
without destroying flow and creating flow again. The fields that could be
updated depend on the type of the ``action`` and different for every type.
The shared action specified data (e.g. counter) can be queried by
``rte_flow_shared_action_query()``.
The indirect action specified data (e.g. counter) can be queried by
``rte_flow_action_handle_query()``.
.. _table_rte_flow_shared_action:
.. _table_rte_flow_action_handle:
.. table:: SHARED
.. table:: INDIRECT
+---------------+
| Field |

View File

@ -288,6 +288,13 @@ API Changes
``rte_cryptodev_raw_dequeue_burst`` got a new parameter
``max_nb_to_dequeue`` to provide flexible control on dequeue.
* ethdev: The experimental flow API for shared action has been generalized
as a flow action handle used in rules through an indirect action.
The functions ``rte_flow_shared_action_*`` manipulating the action object
are replaced with ``rte_flow_action_handle_*``.
The action ``RTE_FLOW_ACTION_TYPE_SHARED`` is deprecated and can be
replaced with ``RTE_FLOW_ACTION_TYPE_INDIRECT``.
ABI Changes
-----------

View File

@ -4055,10 +4055,10 @@ 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``
- ``indirect``: Use indirect action created via
``flow indirect_action {port_id} create``
- ``shared_action_id {unsigned}``: Shared action ID to use
- ``indirect_action_id {unsigned}``: Indirect action ID to use
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
@ -4349,113 +4349,117 @@ 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()``::
Creating indirect actions
~~~~~~~~~~~~~~~~~~~~~~~~~
flow shared_action {port_id} create [action_id {shared_action_id}]
``flow indirect_action {port_id} create`` creates indirect action with optional
indirect action ID. It is bound to ``rte_flow_action_handle_create()``::
flow indirect_action {port_id} create [action_id {indirect_action_id}]
[ingress] [egress] [transfer] action {action} / end
If successful, it will show::
Shared action #[...] created
Indirect action #[...] created
Otherwise, it will complain either that shared action already exists or that
Otherwise, it will complain either that indirect action already exists or that
some error occurred::
Shared action #[...] is already assigned, delete it first
Indirect 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::
Create indirect rss action with id 100 to queues 1 and 2 on port 0::
testpmd> flow shared_action 0 create action_id 100 \
testpmd> flow indirect_action 0 create action_id 100 \
ingress action rss queues 1 2 end / end
Create shared rss action with id assigned by testpmd to queues 1 and 2 on
Create indirect rss action with id assigned by testpmd to queues 1 and 2 on
port 0::
testpmd> flow shared_action 0 create action_id \
testpmd> flow indirect_action 0 create action_id \
ingress action 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()``::
Updating indirect actions
~~~~~~~~~~~~~~~~~~~~~~~~~
flow shared_action {port_id} update {shared_action_id}
``flow indirect_action {port_id} update`` updates configuration of the indirect
action from its indirect action ID (as returned by
``flow indirect_action {port_id} create``). It is bound to
``rte_flow_action_handle_update()``::
flow indirect_action {port_id} update {indirect_action_id}
action {action} / end
If successful, it will show::
Shared action #[...] updated
Indirect action #[...] updated
Otherwise, it will complain either that shared action not found or that some
Otherwise, it will complain either that indirect action not found or that some
error occurred::
Failed to find shared action #[...] on port [...]
Failed to find indirect action #[...] on port [...]
::
Caught error type [...] ([...]): [...]
Update shared rss action having id 100 on port 0 with rss to queues 0 and 3
Update indirect 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 action rss queues 0 3 end / end
testpmd> flow indirect_action 0 update 100 action 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()``::
Destroying indirect actions
~~~~~~~~~~~~~~~~~~~~~~~~~~~
flow shared_action {port_id} destroy action_id {shared_action_id} [...]
``flow indirect_action {port_id} destroy`` destroys one or more indirect actions
from their indirect action IDs (as returned by
``flow indirect_action {port_id} create``). It is bound to
``rte_flow_action_handle_destroy()``::
flow indirect_action {port_id} destroy action_id {indirect_action_id} [...]
If successful, it will show::
Shared action #[...] destroyed
Indirect 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::
It does not report anything for indirect action IDs that do not exist.
The usual error message is shown when a indirect action cannot be destroyed::
Caught error type [...] ([...]): [...]
Destroy shared actions having id 100 & 101::
Destroy indirect actions having id 100 & 101::
testpmd> flow shared_action 0 destroy action_id 100 action_id 101
testpmd> flow indirect_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()``::
Query indirect actions
~~~~~~~~~~~~~~~~~~~~~~
flow shared_action {port_id} query {shared_action_id}
``flow indirect_action {port_id} query`` queries the indirect action from its
indirect action ID (as returned by ``flow indirect_action {port_id} create``).
It is bound to ``rte_flow_action_handle_query()``::
Currently only rss shared action supported. If successful, it will show::
flow indirect_action {port_id} query {indirect_action_id}
Shared RSS action:
Currently only rss indirect action supported. If successful, it will show::
Indirect RSS action:
refs:[...]
Otherwise, it will complain either that shared action not found or that some
Otherwise, it will complain either that indirect action not found or that some
error occurred::
Failed to find shared action #[...] on port [...]
Failed to find indirect action #[...] on port [...]
::
Caught error type [...] ([...]): [...]
Query shared action having id 100::
Query indirect action having id 100::
testpmd> flow shared_action 0 query 100
testpmd> flow indirect_action 0 query 100
Sample QinQ flow rules
~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1341,7 +1341,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
* then this will return directly without any action.
*/
mlx5_flow_list_flush(dev, &priv->flows, true);
mlx5_shared_action_flush(dev);
mlx5_action_handle_flush(dev);
mlx5_flow_meter_flush(dev, NULL);
/* Prevent crashes when queues are still in use. */
dev->rx_pkt_burst = removed_rx_burst;

View File

@ -192,8 +192,8 @@
#define MLX5_HAIRPIN_QUEUE_STRIDE 6
#define MLX5_HAIRPIN_JUMBO_LOG_SIZE (14 + 2)
/* Maximum number of shared actions supported by rte_flow */
#define MLX5_MAX_SHARED_ACTIONS 2
/* Maximum number of indirect actions supported by rte_flow */
#define MLX5_MAX_INDIRECT_ACTIONS 2
/*
* Linux definition of static_assert is found in /usr/include/assert.h.

View File

@ -567,23 +567,23 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
},
};
static struct rte_flow_shared_action *
mlx5_shared_action_create(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
static struct rte_flow_action_handle *
mlx5_action_handle_create(struct rte_eth_dev *dev,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error);
static int mlx5_shared_action_destroy
static int mlx5_action_handle_destroy
(struct rte_eth_dev *dev,
struct rte_flow_shared_action *shared_action,
struct rte_flow_action_handle *handle,
struct rte_flow_error *error);
static int mlx5_shared_action_update
static int mlx5_action_handle_update
(struct rte_eth_dev *dev,
struct rte_flow_shared_action *shared_action,
const struct rte_flow_action *action,
struct rte_flow_action_handle *handle,
const void *update,
struct rte_flow_error *error);
static int mlx5_shared_action_query
static int mlx5_action_handle_query
(struct rte_eth_dev *dev,
const struct rte_flow_shared_action *action,
const struct rte_flow_action_handle *handle,
void *data,
struct rte_flow_error *error);
static int
@ -622,10 +622,10 @@ static const struct rte_flow_ops mlx5_flow_ops = {
.query = mlx5_flow_query,
.dev_dump = mlx5_flow_dev_dump,
.get_aged_flows = mlx5_flow_get_aged_flows,
.shared_action_create = mlx5_shared_action_create,
.shared_action_destroy = mlx5_shared_action_destroy,
.shared_action_update = mlx5_shared_action_update,
.shared_action_query = mlx5_shared_action_query,
.action_handle_create = mlx5_action_handle_create,
.action_handle_destroy = mlx5_action_handle_destroy,
.action_handle_update = mlx5_action_handle_update,
.action_handle_query = mlx5_action_handle_query,
.tunnel_decap_set = mlx5_flow_tunnel_decap_set,
.tunnel_match = mlx5_flow_tunnel_match,
.tunnel_action_decap_release = mlx5_flow_tunnel_action_release,
@ -3401,31 +3401,31 @@ flow_aso_age_get_by_idx(struct rte_eth_dev *dev, uint32_t age_idx)
return &pool->actions[offset - 1];
}
/* maps shared action to translated non shared in some actions array */
struct mlx5_translated_shared_action {
struct rte_flow_shared_action *action; /**< Shared action */
int index; /**< Index in related array of rte_flow_action */
/* maps indirect action to translated direct in some actions array */
struct mlx5_translated_action_handle {
struct rte_flow_action_handle *action; /**< Indirect action handle. */
int index; /**< Index in related array of rte_flow_action. */
};
/**
* Translates actions of type RTE_FLOW_ACTION_TYPE_SHARED to related
* non shared action if translation possible.
* This functionality used to run same execution path for both shared & non
* shared actions on flow create. All necessary preparations for shared
* action handling should be preformed on *shared* actions list returned
* Translates actions of type RTE_FLOW_ACTION_TYPE_INDIRECT to related
* direct action if translation possible.
* This functionality used to run same execution path for both direct and
* indirect actions on flow create. All necessary preparations for indirect
* action handling should be performed on *handle* actions list returned
* from this call.
*
* @param[in] dev
* Pointer to Ethernet device.
* @param[in] actions
* List of actions to translate.
* @param[out] shared
* List to store translated shared actions.
* @param[in, out] shared_n
* Size of *shared* array. On return should be updated with number of shared
* actions retrieved from the *actions* list.
* @param[out] handle
* List to store translated indirect action object handles.
* @param[in, out] indir_n
* Size of *handle* array. On return should be updated with number of
* indirect actions retrieved from the *actions* list.
* @param[out] translated_actions
* List of actions where all shared actions were translated to non shared
* List of actions where all indirect actions were translated to direct
* if possible. NULL if no translation took place.
* @param[out] error
* Pointer to the error structure.
@ -3434,10 +3434,10 @@ struct mlx5_translated_shared_action {
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
flow_shared_actions_translate(struct rte_eth_dev *dev,
flow_action_handles_translate(struct rte_eth_dev *dev,
const struct rte_flow_action actions[],
struct mlx5_translated_shared_action *shared,
int *shared_n,
struct mlx5_translated_action_handle *handle,
int *indir_n,
struct rte_flow_action **translated_actions,
struct rte_flow_error *error)
{
@ -3446,23 +3446,23 @@ flow_shared_actions_translate(struct rte_eth_dev *dev,
size_t actions_size;
int n;
int copied_n = 0;
struct mlx5_translated_shared_action *shared_end = NULL;
struct mlx5_translated_action_handle *handle_end = NULL;
for (n = 0; actions[n].type != RTE_FLOW_ACTION_TYPE_END; n++) {
if (actions[n].type != RTE_FLOW_ACTION_TYPE_SHARED)
if (actions[n].type != RTE_FLOW_ACTION_TYPE_INDIRECT)
continue;
if (copied_n == *shared_n) {
if (copied_n == *indir_n) {
return rte_flow_error_set
(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
NULL, "too many shared actions");
}
rte_memcpy(&shared[copied_n].action, &actions[n].conf,
rte_memcpy(&handle[copied_n].action, &actions[n].conf,
sizeof(actions[n].conf));
shared[copied_n].index = n;
handle[copied_n].index = n;
copied_n++;
}
n++;
*shared_n = copied_n;
*indir_n = copied_n;
if (!copied_n)
return 0;
actions_size = sizeof(struct rte_flow_action) * n;
@ -3472,28 +3472,28 @@ flow_shared_actions_translate(struct rte_eth_dev *dev,
return -ENOMEM;
}
memcpy(translated, actions, actions_size);
for (shared_end = shared + copied_n; shared < shared_end; shared++) {
for (handle_end = handle + copied_n; handle < handle_end; handle++) {
struct mlx5_shared_action_rss *shared_rss;
uint32_t act_idx = (uint32_t)(uintptr_t)shared->action;
uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET)
- 1);
uint32_t act_idx = (uint32_t)(uintptr_t)handle->action;
uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx &
((1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1);
switch (type) {
case MLX5_SHARED_ACTION_TYPE_RSS:
case MLX5_INDIRECT_ACTION_TYPE_RSS:
shared_rss = mlx5_ipool_get
(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx);
translated[shared->index].type =
translated[handle->index].type =
RTE_FLOW_ACTION_TYPE_RSS;
translated[shared->index].conf =
translated[handle->index].conf =
&shared_rss->origin;
break;
case MLX5_SHARED_ACTION_TYPE_AGE:
case MLX5_INDIRECT_ACTION_TYPE_AGE:
if (priv->sh->flow_hit_aso_en) {
translated[shared->index].type =
translated[handle->index].type =
(enum rte_flow_action_type)
MLX5_RTE_FLOW_ACTION_TYPE_AGE;
translated[shared->index].conf =
translated[handle->index].conf =
(void *)(uintptr_t)idx;
break;
}
@ -3502,7 +3502,7 @@ flow_shared_actions_translate(struct rte_eth_dev *dev,
mlx5_free(translated);
return rte_flow_error_set
(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
NULL, "invalid shared action type");
NULL, "invalid indirect action type");
}
}
*translated_actions = translated;
@ -3524,21 +3524,21 @@ flow_shared_actions_translate(struct rte_eth_dev *dev,
*/
static uint32_t
flow_get_shared_rss_action(struct rte_eth_dev *dev,
struct mlx5_translated_shared_action *shared,
struct mlx5_translated_action_handle *handle,
int shared_n)
{
struct mlx5_translated_shared_action *shared_end;
struct mlx5_translated_action_handle *handle_end;
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_shared_action_rss *shared_rss;
for (shared_end = shared + shared_n; shared < shared_end; shared++) {
uint32_t act_idx = (uint32_t)(uintptr_t)shared->action;
uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;
for (handle_end = handle + shared_n; handle < handle_end; handle++) {
uint32_t act_idx = (uint32_t)(uintptr_t)handle->action;
uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx &
((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);
((1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1);
switch (type) {
case MLX5_SHARED_ACTION_TYPE_RSS:
case MLX5_INDIRECT_ACTION_TYPE_RSS:
shared_rss = mlx5_ipool_get
(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],
idx);
@ -5548,9 +5548,9 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
struct rte_flow *flow = NULL;
struct mlx5_flow *dev_flow;
const struct rte_flow_action_rss *rss = NULL;
struct mlx5_translated_shared_action
shared_actions[MLX5_MAX_SHARED_ACTIONS];
int shared_actions_n = MLX5_MAX_SHARED_ACTIONS;
struct mlx5_translated_action_handle
indir_actions[MLX5_MAX_INDIRECT_ACTIONS];
int indir_actions_n = MLX5_MAX_INDIRECT_ACTIONS;
union {
struct mlx5_flow_expand_rss buf;
uint8_t buffer[2048];
@ -5590,9 +5590,9 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
MLX5_ASSERT(wks);
rss_desc = &wks->rss_desc;
ret = flow_shared_actions_translate(dev, original_actions,
shared_actions,
&shared_actions_n,
ret = flow_action_handles_translate(dev, original_actions,
indir_actions,
&indir_actions_n,
&translated_actions, error);
if (ret < 0) {
MLX5_ASSERT(translated_actions == NULL);
@ -5653,8 +5653,8 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
buf->entries = 1;
buf->entry[0].pattern = (void *)(uintptr_t)items;
}
rss_desc->shared_rss = flow_get_shared_rss_action(dev, shared_actions,
shared_actions_n);
rss_desc->shared_rss = flow_get_shared_rss_action(dev, indir_actions,
indir_actions_n);
for (i = 0; i < buf->entries; ++i) {
/* Initialize flow split data. */
flow_split_info.prefix_layers = 0;
@ -5833,14 +5833,14 @@ mlx5_flow_validate(struct rte_eth_dev *dev,
struct rte_flow_error *error)
{
int hairpin_flow;
struct mlx5_translated_shared_action
shared_actions[MLX5_MAX_SHARED_ACTIONS];
int shared_actions_n = MLX5_MAX_SHARED_ACTIONS;
struct mlx5_translated_action_handle
indir_actions[MLX5_MAX_INDIRECT_ACTIONS];
int indir_actions_n = MLX5_MAX_INDIRECT_ACTIONS;
const struct rte_flow_action *actions;
struct rte_flow_action *translated_actions = NULL;
int ret = flow_shared_actions_translate(dev, original_actions,
shared_actions,
&shared_actions_n,
int ret = flow_action_handles_translate(dev, original_actions,
indir_actions,
&indir_actions_n,
&translated_actions, error);
if (ret)
@ -7213,12 +7213,12 @@ mlx5_flow_get_aged_flows(struct rte_eth_dev *dev, void **contexts,
/* Wrapper for driver action_validate op callback */
static int
flow_drv_action_validate(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
const struct mlx5_flow_driver_ops *fops,
struct rte_flow_error *error)
{
static const char err_msg[] = "shared action validation unsupported";
static const char err_msg[] = "indirect action validation unsupported";
if (!fops->action_validate) {
DRV_LOG(ERR, "port %u %s.", dev->data->port_id, err_msg);
@ -7234,8 +7234,8 @@ flow_drv_action_validate(struct rte_eth_dev *dev,
*
* @param dev
* Pointer to Ethernet device structure.
* @param[in] action
* Handle for the shared action to be destroyed.
* @param[in] handle
* Handle for the indirect action object to be destroyed.
* @param[out] error
* Perform verbose error reporting if not NULL. PMDs initialize this
* structure in case of error only.
@ -7246,11 +7246,11 @@ flow_drv_action_validate(struct rte_eth_dev *dev,
* @note: wrapper for driver action_create op callback.
*/
static int
mlx5_shared_action_destroy(struct rte_eth_dev *dev,
struct rte_flow_shared_action *action,
mlx5_action_handle_destroy(struct rte_eth_dev *dev,
struct rte_flow_action_handle *handle,
struct rte_flow_error *error)
{
static const char err_msg[] = "shared action destruction unsupported";
static const char err_msg[] = "indirect action destruction unsupported";
struct rte_flow_attr attr = { .transfer = 0 };
const struct mlx5_flow_driver_ops *fops =
flow_get_drv_ops(flow_get_drv_type(dev, &attr));
@ -7261,18 +7261,18 @@ mlx5_shared_action_destroy(struct rte_eth_dev *dev,
NULL, err_msg);
return -rte_errno;
}
return fops->action_destroy(dev, action, error);
return fops->action_destroy(dev, handle, error);
}
/* Wrapper for driver action_destroy op callback */
static int
flow_drv_action_update(struct rte_eth_dev *dev,
struct rte_flow_shared_action *action,
const void *action_conf,
struct rte_flow_action_handle *handle,
const void *update,
const struct mlx5_flow_driver_ops *fops,
struct rte_flow_error *error)
{
static const char err_msg[] = "shared action update unsupported";
static const char err_msg[] = "indirect action update unsupported";
if (!fops->action_update) {
DRV_LOG(ERR, "port %u %s.", dev->data->port_id, err_msg);
@ -7280,18 +7280,18 @@ flow_drv_action_update(struct rte_eth_dev *dev,
NULL, err_msg);
return -rte_errno;
}
return fops->action_update(dev, action, action_conf, error);
return fops->action_update(dev, handle, update, error);
}
/* Wrapper for driver action_destroy op callback */
static int
flow_drv_action_query(struct rte_eth_dev *dev,
const struct rte_flow_shared_action *action,
const struct rte_flow_action_handle *handle,
void *data,
const struct mlx5_flow_driver_ops *fops,
struct rte_flow_error *error)
{
static const char err_msg[] = "shared action query unsupported";
static const char err_msg[] = "indirect action query unsupported";
if (!fops->action_query) {
DRV_LOG(ERR, "port %u %s.", dev->data->port_id, err_msg);
@ -7299,29 +7299,31 @@ flow_drv_action_query(struct rte_eth_dev *dev,
NULL, err_msg);
return -rte_errno;
}
return fops->action_query(dev, action, data, error);
return fops->action_query(dev, handle, data, error);
}
/**
* Create shared action for reuse in multiple flow rules.
* Create indirect action for reuse in multiple flow rules.
*
* @param dev
* Pointer to Ethernet device structure.
* @param conf
* Pointer to indirect action object configuration.
* @param[in] action
* Action configuration for shared action creation.
* Action configuration for indirect action object creation.
* @param[out] error
* Perform verbose error reporting if not NULL. PMDs initialize this
* structure in case of error only.
* @return
* A valid handle in case of success, NULL otherwise and rte_errno is set.
*/
static struct rte_flow_shared_action *
mlx5_shared_action_create(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
static struct rte_flow_action_handle *
mlx5_action_handle_create(struct rte_eth_dev *dev,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error)
{
static const char err_msg[] = "shared action creation unsupported";
static const char err_msg[] = "indirect action creation unsupported";
struct rte_flow_attr attr = { .transfer = 0 };
const struct mlx5_flow_driver_ops *fops =
flow_get_drv_ops(flow_get_drv_type(dev, &attr));
@ -7338,19 +7340,20 @@ mlx5_shared_action_create(struct rte_eth_dev *dev,
}
/**
* Updates inplace the shared action configuration pointed by *action* handle
* with the configuration provided as *action* argument.
* The update of the shared action configuration effects all flow rules reusing
* the action via handle.
* Updates inplace the indirect action configuration pointed by *handle*
* with the configuration provided as *update* argument.
* The update of the indirect action configuration effects all flow rules
* reusing the action via handle.
*
* @param dev
* Pointer to Ethernet device structure.
* @param[in] shared_action
* Handle for the shared action to be updated.
* @param[in] action
* @param[in] handle
* Handle for the indirect action to be updated.
* @param[in] update
* Action specification used to modify the action pointed by handle.
* *action* should be of same type with the action pointed by the *action*
* handle argument, otherwise considered as invalid.
* *update* could be of same type with the action pointed by the *handle*
* handle argument, or some other structures like a wrapper, depending on
* the indirect action type.
* @param[out] error
* Perform verbose error reporting if not NULL. PMDs initialize this
* structure in case of error only.
@ -7359,9 +7362,9 @@ mlx5_shared_action_create(struct rte_eth_dev *dev,
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
mlx5_shared_action_update(struct rte_eth_dev *dev,
struct rte_flow_shared_action *shared_action,
const struct rte_flow_action *action,
mlx5_action_handle_update(struct rte_eth_dev *dev,
struct rte_flow_action_handle *handle,
const void *update,
struct rte_flow_error *error)
{
struct rte_flow_attr attr = { .transfer = 0 };
@ -7369,26 +7372,27 @@ mlx5_shared_action_update(struct rte_eth_dev *dev,
flow_get_drv_ops(flow_get_drv_type(dev, &attr));
int ret;
ret = flow_drv_action_validate(dev, NULL, action, fops, error);
ret = flow_drv_action_validate(dev, NULL,
(const struct rte_flow_action *)update, fops, error);
if (ret)
return ret;
return flow_drv_action_update(dev, shared_action, action->conf, fops,
return flow_drv_action_update(dev, handle, update, fops,
error);
}
/**
* Query the shared action by handle.
* Query the indirect action by handle.
*
* This function allows retrieving action-specific data such as counters.
* Data is gathered by special action which may be present/referenced in
* more than one flow rule definition.
*
* \see RTE_FLOW_ACTION_TYPE_COUNT
* see @RTE_FLOW_ACTION_TYPE_COUNT
*
* @param dev
* Pointer to Ethernet device structure.
* @param[in] action
* Handle for the shared action to query.
* @param[in] handle
* Handle for the indirect action to query.
* @param[in, out] data
* Pointer to storage for the associated query data type.
* @param[out] error
@ -7399,8 +7403,8 @@ mlx5_shared_action_update(struct rte_eth_dev *dev,
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
mlx5_shared_action_query(struct rte_eth_dev *dev,
const struct rte_flow_shared_action *action,
mlx5_action_handle_query(struct rte_eth_dev *dev,
const struct rte_flow_action_handle *handle,
void *data,
struct rte_flow_error *error)
{
@ -7408,11 +7412,11 @@ mlx5_shared_action_query(struct rte_eth_dev *dev,
const struct mlx5_flow_driver_ops *fops =
flow_get_drv_ops(flow_get_drv_type(dev, &attr));
return flow_drv_action_query(dev, action, data, fops, error);
return flow_drv_action_query(dev, handle, data, fops, error);
}
/**
* Destroy all shared actions.
* Destroy all indirect actions (shared RSS).
*
* @param dev
* Pointer to Ethernet device.
@ -7421,7 +7425,7 @@ mlx5_shared_action_query(struct rte_eth_dev *dev,
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
int
mlx5_shared_action_flush(struct rte_eth_dev *dev)
mlx5_action_handle_flush(struct rte_eth_dev *dev)
{
struct rte_flow_error error;
struct mlx5_priv *priv = dev->data->dev_private;
@ -7431,8 +7435,8 @@ mlx5_shared_action_flush(struct rte_eth_dev *dev)
ILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],
priv->rss_shared_actions, idx, shared_rss, next) {
ret |= mlx5_shared_action_destroy(dev,
(struct rte_flow_shared_action *)(uintptr_t)idx, &error);
ret |= mlx5_action_handle_destroy(dev,
(struct rte_flow_action_handle *)(uintptr_t)idx, &error);
}
return ret;
}

View File

@ -38,11 +38,11 @@ enum mlx5_rte_flow_action_type {
MLX5_RTE_FLOW_ACTION_TYPE_AGE,
};
#define MLX5_SHARED_ACTION_TYPE_OFFSET 30
#define MLX5_INDIRECT_ACTION_TYPE_OFFSET 30
enum {
MLX5_SHARED_ACTION_TYPE_RSS,
MLX5_SHARED_ACTION_TYPE_AGE,
MLX5_INDIRECT_ACTION_TYPE_RSS,
MLX5_INDIRECT_ACTION_TYPE_AGE,
};
/* Matches on selected register. */
@ -1151,7 +1151,7 @@ struct mlx5_shared_action_rss {
rte_spinlock_t action_rss_sl; /**< Shared RSS action spinlock. */
};
struct rte_flow_shared_action {
struct rte_flow_action_handle {
uint32_t id;
};
@ -1232,26 +1232,26 @@ typedef int (*mlx5_flow_get_aged_flows_t)
struct rte_flow_error *error);
typedef int (*mlx5_flow_action_validate_t)
(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error);
typedef struct rte_flow_shared_action *(*mlx5_flow_action_create_t)
typedef struct rte_flow_action_handle *(*mlx5_flow_action_create_t)
(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error);
typedef int (*mlx5_flow_action_destroy_t)
(struct rte_eth_dev *dev,
struct rte_flow_shared_action *action,
struct rte_flow_action_handle *action,
struct rte_flow_error *error);
typedef int (*mlx5_flow_action_update_t)
(struct rte_eth_dev *dev,
struct rte_flow_shared_action *action,
const void *action_conf,
struct rte_flow_action_handle *action,
const void *update,
struct rte_flow_error *error);
typedef int (*mlx5_flow_action_query_t)
(struct rte_eth_dev *dev,
const struct rte_flow_shared_action *action,
const struct rte_flow_action_handle *action,
void *data,
struct rte_flow_error *error);
typedef int (*mlx5_flow_sync_domain_t)
@ -1482,7 +1482,7 @@ int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,
int mlx5_flow_meter_flush(struct rte_eth_dev *dev,
struct rte_mtr_error *error);
int mlx5_flow_dv_discover_counter_offset_support(struct rte_eth_dev *dev);
int mlx5_shared_action_flush(struct rte_eth_dev *dev);
int mlx5_action_handle_flush(struct rte_eth_dev *dev);
void mlx5_release_tunnel_hub(struct mlx5_dev_ctx_shared *sh, uint16_t port_id);
int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh);

View File

@ -12870,7 +12870,7 @@ __flow_dv_action_rss_setup(struct rte_eth_dev *dev,
*/
static uint32_t
__flow_dv_action_rss_create(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action_rss *rss,
struct rte_flow_error *error)
{
@ -12893,7 +12893,7 @@ __flow_dv_action_rss_create(struct rte_eth_dev *dev,
"cannot allocate resource memory");
goto error_rss_init;
}
if (idx > (1u << MLX5_SHARED_ACTION_TYPE_OFFSET)) {
if (idx > (1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET)) {
rte_flow_error_set(error, E2BIG,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
"rss action number out of range");
@ -13006,7 +13006,7 @@ __flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,
}
/**
* Create shared action, lock free,
* Create indirect action, lock free,
* (mutex should be acquired by caller).
* Dispatcher for action type specific call.
*
@ -13015,7 +13015,7 @@ __flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,
* @param[in] conf
* Shared action configuration.
* @param[in] action
* Action specification used to create shared action.
* Action specification used to create indirect action.
* @param[out] error
* Perform verbose error reporting if not NULL. Initialized in case of
* error only.
@ -13024,9 +13024,9 @@ __flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,
* A valid shared action handle in case of success, NULL otherwise and
* rte_errno is set.
*/
static struct rte_flow_shared_action *
static struct rte_flow_action_handle *
flow_dv_action_create(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *err)
{
@ -13036,13 +13036,13 @@ flow_dv_action_create(struct rte_eth_dev *dev,
switch (action->type) {
case RTE_FLOW_ACTION_TYPE_RSS:
ret = __flow_dv_action_rss_create(dev, conf, action->conf, err);
idx = (MLX5_SHARED_ACTION_TYPE_RSS <<
MLX5_SHARED_ACTION_TYPE_OFFSET) | ret;
idx = (MLX5_INDIRECT_ACTION_TYPE_RSS <<
MLX5_INDIRECT_ACTION_TYPE_OFFSET) | ret;
break;
case RTE_FLOW_ACTION_TYPE_AGE:
ret = flow_dv_translate_create_aso_age(dev, action->conf, err);
idx = (MLX5_SHARED_ACTION_TYPE_AGE <<
MLX5_SHARED_ACTION_TYPE_OFFSET) | ret;
idx = (MLX5_INDIRECT_ACTION_TYPE_AGE <<
MLX5_INDIRECT_ACTION_TYPE_OFFSET) | ret;
if (ret) {
struct mlx5_aso_age_action *aso_age =
flow_aso_age_get_by_idx(dev, ret);
@ -13057,19 +13057,19 @@ flow_dv_action_create(struct rte_eth_dev *dev,
NULL, "action type not supported");
break;
}
return ret ? (struct rte_flow_shared_action *)(uintptr_t)idx : NULL;
return ret ? (struct rte_flow_action_handle *)(uintptr_t)idx : NULL;
}
/**
* Destroy the shared action.
* Destroy the indirect action.
* Release action related resources on the NIC and the memory.
* Lock free, (mutex should be acquired by caller).
* Dispatcher for action type specific call.
*
* @param[in] dev
* Pointer to the Ethernet device structure.
* @param[in] action
* The shared action object to be removed.
* @param[in] handle
* The indirect action object handle to be removed.
* @param[out] error
* Perform verbose error reporting if not NULL. Initialized in case of
* error only.
@ -13079,25 +13079,25 @@ flow_dv_action_create(struct rte_eth_dev *dev,
*/
static int
flow_dv_action_destroy(struct rte_eth_dev *dev,
struct rte_flow_shared_action *action,
struct rte_flow_action_handle *handle,
struct rte_flow_error *error)
{
uint32_t act_idx = (uint32_t)(uintptr_t)action;
uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);
uint32_t act_idx = (uint32_t)(uintptr_t)handle;
uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1);
int ret;
switch (type) {
case MLX5_SHARED_ACTION_TYPE_RSS:
case MLX5_INDIRECT_ACTION_TYPE_RSS:
return __flow_dv_action_rss_release(dev, idx, error);
case MLX5_SHARED_ACTION_TYPE_AGE:
case MLX5_INDIRECT_ACTION_TYPE_AGE:
ret = flow_dv_aso_age_release(dev, idx);
if (ret)
/*
* In this case, the last flow has a reference will
* actually release the age action.
*/
DRV_LOG(DEBUG, "Shared age action %" PRIu32 " was"
DRV_LOG(DEBUG, "Indirect age action %" PRIu32 " was"
" released with references %d.", idx, ret);
return 0;
default:
@ -13180,12 +13180,13 @@ __flow_dv_action_rss_update(struct rte_eth_dev *dev, uint32_t idx,
*
* @param[in] dev
* Pointer to the Ethernet device structure.
* @param[in] action
* The shared action object to be updated.
* @param[in] action_conf
* Action specification used to modify *action*.
* *action_conf* should be of type correlating with type of the *action*,
* otherwise considered as invalid.
* @param[in] handle
* The indirect action object handle to be updated.
* @param[in] update
* Action specification used to modify the action pointed by *handle*.
* *update* could be of same type with the action pointed by the *handle*
* handle argument, or some other structures like a wrapper, depending on
* the indirect action type.
* @param[out] error
* Perform verbose error reporting if not NULL. Initialized in case of
* error only.
@ -13195,16 +13196,18 @@ __flow_dv_action_rss_update(struct rte_eth_dev *dev, uint32_t idx,
*/
static int
flow_dv_action_update(struct rte_eth_dev *dev,
struct rte_flow_shared_action *action,
const void *action_conf,
struct rte_flow_action_handle *handle,
const void *update,
struct rte_flow_error *err)
{
uint32_t act_idx = (uint32_t)(uintptr_t)action;
uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);
uint32_t act_idx = (uint32_t)(uintptr_t)handle;
uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1);
const void *action_conf;
switch (type) {
case MLX5_SHARED_ACTION_TYPE_RSS:
case MLX5_INDIRECT_ACTION_TYPE_RSS:
action_conf = ((const struct rte_flow_action *)update)->conf;
return __flow_dv_action_rss_update(dev, idx, action_conf, err);
default:
return rte_flow_error_set(err, ENOTSUP,
@ -13216,17 +13219,17 @@ flow_dv_action_update(struct rte_eth_dev *dev,
static int
flow_dv_action_query(struct rte_eth_dev *dev,
const struct rte_flow_shared_action *action, void *data,
const struct rte_flow_action_handle *handle, void *data,
struct rte_flow_error *error)
{
struct mlx5_age_param *age_param;
struct rte_flow_query_age *resp;
uint32_t act_idx = (uint32_t)(uintptr_t)action;
uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);
uint32_t act_idx = (uint32_t)(uintptr_t)handle;
uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET;
uint32_t idx = act_idx & ((1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1);
switch (type) {
case MLX5_SHARED_ACTION_TYPE_AGE:
case MLX5_INDIRECT_ACTION_TYPE_AGE:
age_param = &flow_aso_age_get_by_idx(dev, idx)->age_params;
resp = data;
resp->aged = __atomic_load_n(&age_param->state,
@ -14002,7 +14005,7 @@ flow_dv_counter_allocate(struct rte_eth_dev *dev)
}
/**
* Validate shared action.
* Validate indirect action.
* Dispatcher for action type specific validation.
*
* @param[in] dev
@ -14010,7 +14013,7 @@ flow_dv_counter_allocate(struct rte_eth_dev *dev)
* @param[in] conf
* Shared action configuration.
* @param[in] action
* The shared action object to validate.
* The indirect action object to validate.
* @param[out] error
* Perform verbose error reporting if not NULL. Initialized in case of
* error only.
@ -14020,7 +14023,7 @@ flow_dv_counter_allocate(struct rte_eth_dev *dev)
*/
static int
flow_dv_action_validate(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *err)
{

View File

@ -180,12 +180,12 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(MODIFY_FIELD,
sizeof(struct rte_flow_action_modify_field)),
/**
* Shared action represented as handle of type
* (struct rte_flow_shared action *) stored in conf field (see
* Indirect action represented as handle of type
* (struct rte_flow_action_handle *) stored in conf field (see
* struct rte_flow_action); no need for additional structure to * store
* shared action handle.
* indirect action handle.
*/
MK_FLOW_ACTION(SHARED, 0),
MK_FLOW_ACTION(INDIRECT, 0),
};
int
@ -1068,53 +1068,53 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
NULL, rte_strerror(ENOTSUP));
}
struct rte_flow_shared_action *
rte_flow_shared_action_create(uint16_t port_id,
const struct rte_flow_shared_action_conf *conf,
struct rte_flow_action_handle *
rte_flow_action_handle_create(uint16_t port_id,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error)
{
struct rte_flow_shared_action *shared_action;
struct rte_flow_action_handle *handle;
const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
if (unlikely(!ops))
return NULL;
if (unlikely(!ops->shared_action_create)) {
if (unlikely(!ops->action_handle_create)) {
rte_flow_error_set(error, ENOSYS,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
rte_strerror(ENOSYS));
return NULL;
}
shared_action = ops->shared_action_create(&rte_eth_devices[port_id],
conf, action, error);
if (shared_action == NULL)
handle = ops->action_handle_create(&rte_eth_devices[port_id],
conf, action, error);
if (handle == NULL)
flow_err(port_id, -rte_errno, error);
return shared_action;
return handle;
}
int
rte_flow_shared_action_destroy(uint16_t port_id,
struct rte_flow_shared_action *action,
struct rte_flow_error *error)
rte_flow_action_handle_destroy(uint16_t port_id,
struct rte_flow_action_handle *handle,
struct rte_flow_error *error)
{
int ret;
const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
if (unlikely(!ops))
return -rte_errno;
if (unlikely(!ops->shared_action_destroy))
if (unlikely(!ops->action_handle_destroy))
return rte_flow_error_set(error, ENOSYS,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOSYS));
ret = ops->shared_action_destroy(&rte_eth_devices[port_id], action,
error);
ret = ops->action_handle_destroy(&rte_eth_devices[port_id],
handle, error);
return flow_err(port_id, ret, error);
}
int
rte_flow_shared_action_update(uint16_t port_id,
struct rte_flow_shared_action *action,
const struct rte_flow_action *update,
rte_flow_action_handle_update(uint16_t port_id,
struct rte_flow_action_handle *handle,
const void *update,
struct rte_flow_error *error)
{
int ret;
@ -1122,18 +1122,18 @@ rte_flow_shared_action_update(uint16_t port_id,
if (unlikely(!ops))
return -rte_errno;
if (unlikely(!ops->shared_action_update))
if (unlikely(!ops->action_handle_update))
return rte_flow_error_set(error, ENOSYS,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOSYS));
ret = ops->shared_action_update(&rte_eth_devices[port_id], action,
ret = ops->action_handle_update(&rte_eth_devices[port_id], handle,
update, error);
return flow_err(port_id, ret, error);
}
int
rte_flow_shared_action_query(uint16_t port_id,
const struct rte_flow_shared_action *action,
rte_flow_action_handle_query(uint16_t port_id,
const struct rte_flow_action_handle *handle,
void *data,
struct rte_flow_error *error)
{
@ -1142,11 +1142,11 @@ rte_flow_shared_action_query(uint16_t port_id,
if (unlikely(!ops))
return -rte_errno;
if (unlikely(!ops->shared_action_query))
if (unlikely(!ops->action_handle_query))
return rte_flow_error_set(error, ENOSYS,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOSYS));
ret = ops->shared_action_query(&rte_eth_devices[port_id], action,
ret = ops->action_handle_query(&rte_eth_devices[port_id], handle,
data, error);
return flow_err(port_id, ret, error);
}

View File

@ -1821,7 +1821,7 @@ enum rte_flow_action_type {
* Enables counters for this flow rule.
*
* These counters can be retrieved and reset through rte_flow_query() or
* rte_flow_shared_action_query() if the action provided via handle,
* rte_flow_action_handle_query() if the action provided via handle,
* see struct rte_flow_query_count.
*
* See struct rte_flow_action_count.
@ -2250,6 +2250,9 @@ enum rte_flow_action_type {
RTE_FLOW_ACTION_TYPE_SAMPLE,
/**
* @deprecated
* @see RTE_FLOW_ACTION_TYPE_INDIRECT
*
* Describe action shared across multiple flow rules.
*
* Allow multiple rules reference the same action by handle (see
@ -2267,6 +2270,14 @@ enum rte_flow_action_type {
* See struct rte_flow_action_modify_field.
*/
RTE_FLOW_ACTION_TYPE_MODIFY_FIELD,
/**
* An action handle is referenced in a rule through an indirect action.
*
* The same action handle may be used in multiple rules for the same
* or different ethdev ports.
*/
RTE_FLOW_ACTION_TYPE_INDIRECT,
};
/**
@ -2357,7 +2368,7 @@ struct rte_flow_query_age {
* ``struct rte_flow_query_count``.
*
* @deprecated Shared attribute is deprecated, use generic
* RTE_FLOW_ACTION_TYPE_SHARED action.
* RTE_FLOW_ACTION_TYPE_INDIRECT action.
*
* The shared flag indicates whether the counter is unique to the flow rule the
* action is specified with, or whether it is a shared counter.
@ -2847,17 +2858,23 @@ struct rte_flow_action_set_dscp {
};
/**
* RTE_FLOW_ACTION_TYPE_SHARED
* @warning
* @b EXPERIMENTAL: this structure may change without prior notice
*
* Opaque type returned after successfully creating a shared action.
* RTE_FLOW_ACTION_TYPE_INDIRECT
*
* This handle can be used to manage and query the related action:
* - share it across multiple flow rules
* - update action configuration
* - query action data
* - destroy action
* Opaque type returned after successfully creating an indirect action object.
* The definition of the object handle is different per driver or
* per direct action type.
*
* This handle can be used to manage and query the related direct action:
* - referenced in single flow rule or across multiple flow rules
* over multiple ports
* - update action object configuration
* - query action object data
* - destroy action object
*/
struct rte_flow_shared_action;
struct rte_flow_action_handle;
/**
* Field IDs for MODIFY_FIELD action.
@ -3631,25 +3648,22 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
uint32_t nb_contexts, struct rte_flow_error *error);
/**
* Specify shared action configuration
* Specify indirect action object configuration
*/
struct rte_flow_shared_action_conf {
struct rte_flow_indir_action_conf {
/**
* Flow direction for shared action configuration.
* Flow direction for the indirect action configuration.
*
* Shared action should be valid at least for one flow direction,
* Action should be valid at least for one flow direction,
* otherwise it is invalid for both ingress and egress rules.
*/
uint32_t ingress:1;
/**< Action valid for rules applied to ingress traffic. */
uint32_t egress:1;
/**< Action valid for rules applied to egress traffic. */
/**
* When set to 1, indicates that the action is valid for
* transfer traffic; otherwise, for non-transfer traffic.
*
* See struct rte_flow_attr.
*/
uint32_t transfer:1;
};
@ -3658,16 +3672,17 @@ struct rte_flow_shared_action_conf {
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Create shared action for reuse in multiple flow rules.
* The created shared action has single state and configuration
* across all flow rules using it.
* Create an indirect action object that can be used in flow rules
* via its handle.
* The created object handle has single state and configuration
* across all the flow rules using it.
*
* @param[in] port_id
* The port identifier of the Ethernet device.
* @param[in] conf
* Shared action configuration.
* Action configuration for the indirect action object creation.
* @param[in] action
* Action configuration for shared action creation.
* Specific configuration of the indirect action object.
* @param[out] error
* Perform verbose error reporting if not NULL. PMDs initialize this
* structure in case of error only.
@ -3681,9 +3696,9 @@ struct rte_flow_shared_action_conf {
* - (ENOTSUP) if *action* valid but unsupported.
*/
__rte_experimental
struct rte_flow_shared_action *
rte_flow_shared_action_create(uint16_t port_id,
const struct rte_flow_shared_action_conf *conf,
struct rte_flow_action_handle *
rte_flow_action_handle_create(uint16_t port_id,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error);
@ -3691,12 +3706,12 @@ rte_flow_shared_action_create(uint16_t port_id,
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Destroy the shared action by handle.
* Destroy indirect action by handle.
*
* @param[in] port_id
* The port identifier of the Ethernet device.
* @param[in] action
* Handle for the shared action to be destroyed.
* @param[in] handle
* Handle for the indirect action object to be destroyed.
* @param[out] error
* Perform verbose error reporting if not NULL. PMDs initialize this
* structure in case of error only.
@ -3711,27 +3726,30 @@ rte_flow_shared_action_create(uint16_t port_id,
*/
__rte_experimental
int
rte_flow_shared_action_destroy(uint16_t port_id,
struct rte_flow_shared_action *action,
rte_flow_action_handle_destroy(uint16_t port_id,
struct rte_flow_action_handle *handle,
struct rte_flow_error *error);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Update in-place the shared action configuration pointed by *action* handle
* with the configuration provided as *update* argument.
* The update of the shared action configuration effects all flow rules reusing
* the action via handle.
* Update in-place the action configuration and / or state pointed
* by action *handle* with the configuration provided as *update* argument.
* The update of the action configuration effects all flow rules reusing
* the action via *handle*.
* The update general pointer provides the ability of partial updating.
*
* @param[in] port_id
* The port identifier of the Ethernet device.
* @param[in] action
* Handle for the shared action to be updated.
* @param[in] handle
* Handle for the indirect action object to be updated.
* @param[in] update
* Action specification used to modify the action pointed by handle.
* *update* should be of same type with the action pointed by the *action*
* handle argument, otherwise considered as invalid.
* Update profile specification used to modify the action pointed by handle.
* *update* could be with the same type of the immediate action corresponding
* to the *handle* argument when creating, or a wrapper structure includes
* action configuration to be updated and bit fields to indicate the member
* of fields inside the action to update.
* @param[out] error
* Perform verbose error reporting if not NULL. PMDs initialize this
* structure in case of error only.
@ -3742,32 +3760,32 @@ rte_flow_shared_action_destroy(uint16_t port_id,
* - (-EIO) if underlying device is removed.
* - (-EINVAL) if *update* invalid.
* - (-ENOTSUP) if *update* valid but unsupported.
* - (-ENOENT) if action pointed by *ctx* was not found.
* - (-ENOENT) if indirect action object pointed by *handle* was not found.
* rte_errno is also set.
*/
__rte_experimental
int
rte_flow_shared_action_update(uint16_t port_id,
struct rte_flow_shared_action *action,
const struct rte_flow_action *update,
rte_flow_action_handle_update(uint16_t port_id,
struct rte_flow_action_handle *handle,
const void *update,
struct rte_flow_error *error);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Query the shared action by handle.
* Query the direct action by corresponding indirect action object handle.
*
* Retrieve action-specific data such as counters.
* Data is gathered by special action which may be present/referenced in
* more than one flow rule definition.
*
* \see RTE_FLOW_ACTION_TYPE_COUNT
* @see RTE_FLOW_ACTION_TYPE_COUNT
*
* @param port_id
* Port identifier of Ethernet device.
* @param[in] action
* Handle for the shared action to query.
* @param[in] handle
* Handle for the action object to query.
* @param[in, out] data
* Pointer to storage for the associated query data type.
* @param[out] error
@ -3779,10 +3797,9 @@ rte_flow_shared_action_update(uint16_t port_id,
*/
__rte_experimental
int
rte_flow_shared_action_query(uint16_t port_id,
const struct rte_flow_shared_action *action,
void *data,
struct rte_flow_error *error);
rte_flow_action_handle_query(uint16_t port_id,
const struct rte_flow_action_handle *handle,
void *data, struct rte_flow_error *error);
/* Tunnel has a type and the key information. */
struct rte_flow_tunnel {

View File

@ -84,27 +84,27 @@ struct rte_flow_ops {
void **context,
uint32_t nb_contexts,
struct rte_flow_error *err);
/** See rte_flow_shared_action_create() */
struct rte_flow_shared_action *(*shared_action_create)
/** See rte_flow_action_handle_create() */
struct rte_flow_action_handle *(*action_handle_create)
(struct rte_eth_dev *dev,
const struct rte_flow_shared_action_conf *conf,
const struct rte_flow_indir_action_conf *conf,
const struct rte_flow_action *action,
struct rte_flow_error *error);
/** See rte_flow_shared_action_destroy() */
int (*shared_action_destroy)
/** See rte_flow_action_handle_destroy() */
int (*action_handle_destroy)
(struct rte_eth_dev *dev,
struct rte_flow_shared_action *shared_action,
struct rte_flow_action_handle *handle,
struct rte_flow_error *error);
/** See rte_flow_shared_action_update() */
int (*shared_action_update)
/** See rte_flow_action_handle_update() */
int (*action_handle_update)
(struct rte_eth_dev *dev,
struct rte_flow_shared_action *shared_action,
const struct rte_flow_action *update,
struct rte_flow_action_handle *handle,
const void *update,
struct rte_flow_error *error);
/** See rte_flow_shared_action_query() */
int (*shared_action_query)
/** See rte_flow_action_handle_query() */
int (*action_handle_query)
(struct rte_eth_dev *dev,
const struct rte_flow_shared_action *shared_action,
const struct rte_flow_action_handle *handle,
void *data,
struct rte_flow_error *error);
/** See rte_flow_tunnel_decap_set() */

View File

@ -231,10 +231,6 @@ EXPERIMENTAL {
rte_eth_fec_get_capability;
rte_eth_fec_get;
rte_eth_fec_set;
rte_flow_shared_action_create;
rte_flow_shared_action_destroy;
rte_flow_shared_action_query;
rte_flow_shared_action_update;
rte_flow_tunnel_decap_set;
rte_flow_tunnel_match;
rte_flow_get_restore_info;
@ -246,6 +242,10 @@ EXPERIMENTAL {
# added in 21.05
rte_eth_representor_info_get;
rte_flow_action_handle_create;
rte_flow_action_handle_destroy;
rte_flow_action_handle_update;
rte_flow_action_handle_query;
};
INTERNAL {