@@ -145,6 +145,7 @@ enum index {
QUEUE_INDIRECT_ACTION_CREATE,
QUEUE_INDIRECT_ACTION_UPDATE,
QUEUE_INDIRECT_ACTION_DESTROY,
+ QUEUE_INDIRECT_ACTION_QUERY,
/* Queue indirect action create arguments */
QUEUE_INDIRECT_ACTION_CREATE_ID,
@@ -161,6 +162,9 @@ enum index {
QUEUE_INDIRECT_ACTION_DESTROY_ID,
QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE,
+ /* Queue indirect action query arguments */
+ QUEUE_INDIRECT_ACTION_QUERY_POSTPONE,
+
/* Push arguments. */
PUSH_QUEUE,
@@ -1171,6 +1175,7 @@ static const enum index next_qia_subcmd[] = {
QUEUE_INDIRECT_ACTION_CREATE,
QUEUE_INDIRECT_ACTION_UPDATE,
QUEUE_INDIRECT_ACTION_DESTROY,
+ QUEUE_INDIRECT_ACTION_QUERY,
ZERO,
};
@@ -1197,6 +1202,12 @@ static const enum index next_qia_destroy_attr[] = {
ZERO,
};
+static const enum index next_qia_query_attr[] = {
+ QUEUE_INDIRECT_ACTION_QUERY_POSTPONE,
+ END,
+ ZERO,
+};
+
static const enum index next_ia_create_attr[] = {
INDIRECT_ACTION_CREATE_ID,
INDIRECT_ACTION_INGRESS,
@@ -3013,6 +3024,14 @@ static const struct token token_list[] = {
.next = NEXT(next_qia_destroy_attr),
.call = parse_qia_destroy,
},
+ [QUEUE_INDIRECT_ACTION_QUERY] = {
+ .name = "query",
+ .help = "query indirect action",
+ .next = NEXT(next_qia_query_attr,
+ NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
+ .call = parse_qia,
+ },
/* Indirect action destroy arguments. */
[QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = {
.name = "postpone",
@@ -3038,6 +3057,14 @@ static const struct token token_list[] = {
NEXT_ENTRY(COMMON_BOOLEAN)),
.args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
},
+ /* Indirect action update arguments. */
+ [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = {
+ .name = "postpone",
+ .help = "postpone query operation",
+ .next = NEXT(next_qia_query_attr,
+ NEXT_ENTRY(COMMON_BOOLEAN)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+ },
/* Indirect action create arguments. */
[QUEUE_INDIRECT_ACTION_CREATE_ID] = {
.name = "action_id",
@@ -6682,6 +6709,8 @@ parse_qia(struct context *ctx, const struct token *token,
(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
sizeof(double));
out->args.vc.attr.group = UINT32_MAX;
+ /* fallthrough */
+ case QUEUE_INDIRECT_ACTION_QUERY:
out->command = ctx->curr;
ctx->objdata = 0;
ctx->object = out;
@@ -10509,6 +10538,11 @@ cmd_flow_parsed(const struct buffer *in)
in->args.vc.attr.group,
in->args.vc.actions);
break;
+ case QUEUE_INDIRECT_ACTION_QUERY:
+ port_queue_action_handle_query(in->port,
+ in->queue, in->postpone,
+ in->args.vc.attr.group);
+ break;
case INDIRECT_ACTION_CREATE:
port_action_handle_create(
in->port, in->args.vc.attr.group,
@@ -2080,44 +2080,18 @@ port_action_handle_update(portid_t port_id, uint32_t id,
return 0;
}
-int
-port_action_handle_query(portid_t port_id, uint32_t id)
+static void
+port_action_handle_query_dump(uint32_t type, union port_action_query *query)
{
- struct rte_flow_error error;
- struct port_indirect_action *pia;
- union {
- struct rte_flow_query_count count;
- struct rte_flow_query_age age;
- struct rte_flow_action_conntrack ct;
- } query;
-
- pia = action_get_by_id(port_id, id);
- if (!pia)
- return -EINVAL;
- switch (pia->type) {
- case RTE_FLOW_ACTION_TYPE_AGE:
- case RTE_FLOW_ACTION_TYPE_COUNT:
- break;
- default:
- fprintf(stderr,
- "Indirect action %u (type: %d) on port %u doesn't support query\n",
- id, pia->type, port_id);
- return -ENOTSUP;
- }
- /* Poisoning to make sure PMDs update it in case of error. */
- memset(&error, 0x55, sizeof(error));
- memset(&query, 0, sizeof(query));
- if (rte_flow_action_handle_query(port_id, pia->handle, &query, &error))
- return port_flow_complain(&error);
- switch (pia->type) {
+ switch (type) {
case RTE_FLOW_ACTION_TYPE_AGE:
printf("Indirect AGE action:\n"
" aged: %u\n"
" sec_since_last_hit_valid: %u\n"
" sec_since_last_hit: %" PRIu32 "\n",
- query.age.aged,
- query.age.sec_since_last_hit_valid,
- query.age.sec_since_last_hit);
+ query->age.aged,
+ query->age.sec_since_last_hit_valid,
+ query->age.sec_since_last_hit);
break;
case RTE_FLOW_ACTION_TYPE_COUNT:
printf("Indirect COUNT action:\n"
@@ -2125,10 +2099,10 @@ port_action_handle_query(portid_t port_id, uint32_t id)
" bytes_set: %u\n"
" hits: %" PRIu64 "\n"
" bytes: %" PRIu64 "\n",
- query.count.hits_set,
- query.count.bytes_set,
- query.count.hits,
- query.count.bytes);
+ query->count.hits_set,
+ query->count.bytes_set,
+ query->count.hits,
+ query->count.bytes);
break;
case RTE_FLOW_ACTION_TYPE_CONNTRACK:
printf("Conntrack Context:\n"
@@ -2138,47 +2112,76 @@ port_action_handle_query(portid_t port_id, uint32_t id)
" Factor: %u, Retrans: %u, TCP flags: %u\n"
" Last Seq: %u, Last ACK: %u\n"
" Last Win: %u, Last End: %u\n",
- query.ct.peer_port,
- query.ct.is_original_dir ? "Original" : "Reply",
- query.ct.enable, query.ct.live_connection,
- query.ct.selective_ack, query.ct.challenge_ack_passed,
- query.ct.last_direction ? "Original" : "Reply",
- query.ct.liberal_mode, query.ct.state,
- query.ct.max_ack_window, query.ct.retransmission_limit,
- query.ct.last_index, query.ct.last_seq,
- query.ct.last_ack, query.ct.last_window,
- query.ct.last_end);
+ query->ct.peer_port,
+ query->ct.is_original_dir ? "Original" : "Reply",
+ query->ct.enable, query->ct.live_connection,
+ query->ct.selective_ack, query->ct.challenge_ack_passed,
+ query->ct.last_direction ? "Original" : "Reply",
+ query->ct.liberal_mode, query->ct.state,
+ query->ct.max_ack_window, query->ct.retransmission_limit,
+ query->ct.last_index, query->ct.last_seq,
+ query->ct.last_ack, query->ct.last_window,
+ query->ct.last_end);
printf(" Original Dir:\n"
" scale: %u, fin: %u, ack seen: %u\n"
" unacked data: %u\n Sent end: %u,"
" Reply end: %u, Max win: %u, Max ACK: %u\n",
- query.ct.original_dir.scale,
- query.ct.original_dir.close_initiated,
- query.ct.original_dir.last_ack_seen,
- query.ct.original_dir.data_unacked,
- query.ct.original_dir.sent_end,
- query.ct.original_dir.reply_end,
- query.ct.original_dir.max_win,
- query.ct.original_dir.max_ack);
+ query->ct.original_dir.scale,
+ query->ct.original_dir.close_initiated,
+ query->ct.original_dir.last_ack_seen,
+ query->ct.original_dir.data_unacked,
+ query->ct.original_dir.sent_end,
+ query->ct.original_dir.reply_end,
+ query->ct.original_dir.max_win,
+ query->ct.original_dir.max_ack);
printf(" Reply Dir:\n"
" scale: %u, fin: %u, ack seen: %u\n"
" unacked data: %u\n Sent end: %u,"
" Reply end: %u, Max win: %u, Max ACK: %u\n",
- query.ct.reply_dir.scale,
- query.ct.reply_dir.close_initiated,
- query.ct.reply_dir.last_ack_seen,
- query.ct.reply_dir.data_unacked,
- query.ct.reply_dir.sent_end,
- query.ct.reply_dir.reply_end,
- query.ct.reply_dir.max_win,
- query.ct.reply_dir.max_ack);
+ query->ct.reply_dir.scale,
+ query->ct.reply_dir.close_initiated,
+ query->ct.reply_dir.last_ack_seen,
+ query->ct.reply_dir.data_unacked,
+ query->ct.reply_dir.sent_end,
+ query->ct.reply_dir.reply_end,
+ query->ct.reply_dir.max_win,
+ query->ct.reply_dir.max_ack);
+ break;
+ default:
+ fprintf(stderr,
+ "Indirect action (type: %d) doesn't support query\n",
+ type);
+ break;
+ }
+
+}
+
+int
+port_action_handle_query(portid_t port_id, uint32_t id)
+{
+ struct rte_flow_error error;
+ struct port_indirect_action *pia;
+ union port_action_query query;
+
+ pia = action_get_by_id(port_id, id);
+ if (!pia)
+ return -EINVAL;
+ switch (pia->type) {
+ case RTE_FLOW_ACTION_TYPE_AGE:
+ case RTE_FLOW_ACTION_TYPE_COUNT:
break;
default:
fprintf(stderr,
"Indirect action %u (type: %d) on port %u doesn't support query\n",
id, pia->type, port_id);
- break;
+ return -ENOTSUP;
}
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x55, sizeof(error));
+ memset(&query, 0, sizeof(query));
+ if (rte_flow_action_handle_query(port_id, pia->handle, &query, &error))
+ return port_flow_complain(&error);
+ port_action_handle_query_dump(pia->type, &query);
return 0;
}
@@ -2670,6 +2673,7 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
bool found;
struct rte_flow_error error = { RTE_FLOW_ERROR_TYPE_NONE, NULL, NULL };
struct rte_flow_action_age *age = age_action_get(actions);
+ struct queue_job *job;
port = &ports[port_id];
if (port->flow_list) {
@@ -2713,9 +2717,18 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
return -EINVAL;
}
+ job = calloc(1, sizeof(*job));
+ if (!job) {
+ printf("Queue flow create job allocate failed\n");
+ return -ENOMEM;
+ }
+ job->type = QUEUE_JOB_TYPE_FLOW_CREATE;
+
pf = port_flow_new(NULL, pattern, actions, &error);
- if (!pf)
+ if (!pf) {
+ free(job);
return port_flow_complain(&error);
+ }
if (age) {
pf->age_type = ACTION_AGE_CONTEXT_TYPE_FLOW;
age->context = &pf->age_type;
@@ -2723,16 +2736,18 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
/* Poisoning to make sure PMDs update it in case of error. */
memset(&error, 0x11, sizeof(error));
flow = rte_flow_async_create(port_id, queue_id, &op_attr, pt->table,
- pattern, pattern_idx, actions, actions_idx, NULL, &error);
+ pattern, pattern_idx, actions, actions_idx, job, &error);
if (!flow) {
uint32_t flow_id = pf->id;
port_queue_flow_destroy(port_id, queue_id, true, 1, &flow_id);
+ free(job);
return port_flow_complain(&error);
}
pf->next = port->flow_list;
pf->id = id;
pf->flow = flow;
+ job->pf = pf;
port->flow_list = pf;
printf("Flow rule #%u creation enqueued\n", pf->id);
return 0;
@@ -2748,6 +2763,7 @@ port_queue_flow_destroy(portid_t port_id, queueid_t queue_id,
struct port_flow **tmp;
uint32_t c = 0;
int ret = 0;
+ struct queue_job *job;
if (port_id_is_invalid(port_id, ENABLED_WARN) ||
port_id == (portid_t)RTE_PORT_ALL)
@@ -2774,14 +2790,22 @@ port_queue_flow_destroy(portid_t port_id, queueid_t queue_id,
* update it in case of error.
*/
memset(&error, 0x33, sizeof(error));
+ job = calloc(1, sizeof(*job));
+ if (!job) {
+ printf("Queue flow destroy job allocate failed\n");
+ return -ENOMEM;
+ }
+ job->type = QUEUE_JOB_TYPE_FLOW_DESTROY;
+ job->pf = pf;
+
if (rte_flow_async_destroy(port_id, queue_id, &op_attr,
- pf->flow, NULL, &error)) {
+ pf->flow, job, &error)) {
+ free(job);
ret = port_flow_complain(&error);
continue;
}
printf("Flow rule #%u destruction enqueued\n", pf->id);
*tmp = pf->next;
- free(pf);
break;
}
if (i == n)
@@ -2803,6 +2827,7 @@ port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,
struct port_indirect_action *pia;
int ret;
struct rte_flow_error error;
+ struct queue_job *job;
ret = action_alloc(port_id, id, &pia);
if (ret)
@@ -2813,6 +2838,13 @@ port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,
printf("Queue #%u is invalid\n", queue_id);
return -EINVAL;
}
+ job = calloc(1, sizeof(*job));
+ if (!job) {
+ printf("Queue action create job allocate failed\n");
+ return -ENOMEM;
+ }
+ job->type = QUEUE_JOB_TYPE_ACTION_CREATE;
+ job->pia = pia;
if (action->type == RTE_FLOW_ACTION_TYPE_AGE) {
struct rte_flow_action_age *age =
@@ -2824,11 +2856,12 @@ port_queue_action_handle_create(portid_t port_id, uint32_t queue_id,
/* Poisoning to make sure PMDs update it in case of error. */
memset(&error, 0x88, sizeof(error));
pia->handle = rte_flow_async_action_handle_create(port_id, queue_id,
- &attr, conf, action, NULL, &error);
+ &attr, conf, action, job, &error);
if (!pia->handle) {
uint32_t destroy_id = pia->id;
port_queue_action_handle_destroy(port_id, queue_id,
postpone, 1, &destroy_id);
+ free(job);
return port_flow_complain(&error);
}
pia->type = action->type;
@@ -2847,6 +2880,7 @@ port_queue_action_handle_destroy(portid_t port_id,
struct port_indirect_action **tmp;
uint32_t c = 0;
int ret = 0;
+ struct queue_job *job;
if (port_id_is_invalid(port_id, ENABLED_WARN) ||
port_id == (portid_t)RTE_PORT_ALL)
@@ -2873,17 +2907,23 @@ port_queue_action_handle_destroy(portid_t port_id,
* of error.
*/
memset(&error, 0x99, sizeof(error));
+ job = calloc(1, sizeof(*job));
+ if (!job) {
+ printf("Queue action destroy job allocate failed\n");
+ return -ENOMEM;
+ }
+ job->type = QUEUE_JOB_TYPE_ACTION_DESTROY;
+ job->pia = pia;
if (pia->handle &&
rte_flow_async_action_handle_destroy(port_id,
- queue_id, &attr, pia->handle, NULL, &error)) {
+ queue_id, &attr, pia->handle, job, &error)) {
ret = port_flow_complain(&error);
continue;
}
*tmp = pia->next;
printf("Indirect action #%u destruction queued\n",
pia->id);
- free(pia);
break;
}
if (i == n)
@@ -2903,6 +2943,7 @@ port_queue_action_handle_update(portid_t port_id,
struct rte_port *port;
struct rte_flow_error error;
struct rte_flow_action_handle *action_handle;
+ struct queue_job *job;
action_handle = port_action_handle_get_by_id(port_id, id);
if (!action_handle)
@@ -2914,8 +2955,56 @@ port_queue_action_handle_update(portid_t port_id,
return -EINVAL;
}
+ job = calloc(1, sizeof(*job));
+ if (!job) {
+ printf("Queue action update job allocate failed\n");
+ return -ENOMEM;
+ }
+ job->type = QUEUE_JOB_TYPE_ACTION_UPDATE;
+
if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
- action_handle, action, NULL, &error)) {
+ action_handle, action, job, &error)) {
+ free(job);
+ return port_flow_complain(&error);
+ }
+ printf("Indirect action #%u update queued\n", id);
+ return 0;
+}
+
+/** Enqueue indirect action query operation. */
+int
+port_queue_action_handle_query(portid_t port_id,
+ uint32_t queue_id, bool postpone, uint32_t id)
+{
+ const struct rte_flow_op_attr attr = { .postpone = postpone};
+ struct rte_port *port;
+ struct rte_flow_error error;
+ struct rte_flow_action_handle *action_handle;
+ struct port_indirect_action *pia;
+ struct queue_job *job;
+
+ pia = action_get_by_id(port_id, id);
+ action_handle = pia ? pia->handle : NULL;
+ if (!action_handle)
+ return -EINVAL;
+
+ port = &ports[port_id];
+ if (queue_id >= port->queue_nb) {
+ printf("Queue #%u is invalid\n", queue_id);
+ return -EINVAL;
+ }
+
+ job = calloc(1, sizeof(*job));
+ if (!job) {
+ printf("Queue action update job allocate failed\n");
+ return -ENOMEM;
+ }
+ job->type = QUEUE_JOB_TYPE_ACTION_QUERY;
+ job->pia = pia;
+
+ if (rte_flow_async_action_handle_query(port_id, queue_id, &attr,
+ action_handle, &job->query, job, &error)) {
+ free(job);
return port_flow_complain(&error);
}
printf("Indirect action #%u update queued\n", id);
@@ -2960,6 +3049,7 @@ port_queue_flow_pull(portid_t port_id, queueid_t queue_id)
int ret = 0;
int success = 0;
int i;
+ struct queue_job *job;
if (port_id_is_invalid(port_id, ENABLED_WARN) ||
port_id == (portid_t)RTE_PORT_ALL)
@@ -2989,6 +3079,14 @@ port_queue_flow_pull(portid_t port_id, queueid_t queue_id)
for (i = 0; i < ret; i++) {
if (res[i].status == RTE_FLOW_OP_SUCCESS)
success++;
+ job = (struct queue_job *)res[i].user_data;
+ if (job->type == QUEUE_JOB_TYPE_FLOW_DESTROY)
+ free(job->pf);
+ else if (job->type == QUEUE_JOB_TYPE_ACTION_DESTROY)
+ free(job->pia);
+ else if (job->type == QUEUE_JOB_TYPE_ACTION_QUERY)
+ port_action_handle_query_dump(job->pia->type, &job->query);
+ free(job);
}
printf("Queue #%u pulled %u operations (%u failed, %u succeeded)\n",
queue_id, ret, ret - success, success);
@@ -105,6 +105,15 @@ enum {
/**< allocate mempool natively, use rte_pktmbuf_pool_create_extbuf */
};
+enum {
+ QUEUE_JOB_TYPE_FLOW_CREATE,
+ QUEUE_JOB_TYPE_FLOW_DESTROY,
+ QUEUE_JOB_TYPE_ACTION_CREATE,
+ QUEUE_JOB_TYPE_ACTION_DESTROY,
+ QUEUE_JOB_TYPE_ACTION_UPDATE,
+ QUEUE_JOB_TYPE_ACTION_QUERY,
+};
+
/**
* The data structure associated with RX and TX packet burst statistics
* that are recorded for each forwarding stream.
@@ -220,6 +229,23 @@ struct port_indirect_action {
enum age_action_context_type age_type; /**< Age action context type. */
};
+/* Descriptor for action query data. */
+union port_action_query {
+ struct rte_flow_query_count count;
+ struct rte_flow_query_age age;
+ struct rte_flow_action_conntrack ct;
+};
+
+/* Descriptor for queue job. */
+struct queue_job {
+ uint32_t type; /**< Job type. */
+ union {
+ struct port_flow *pf;
+ struct port_indirect_action *pia;
+ };
+ union port_action_query query;
+};
+
struct port_flow_tunnel {
LIST_ENTRY(port_flow_tunnel) chain;
struct rte_flow_action *pmd_actions;
@@ -980,6 +1006,8 @@ int port_queue_action_handle_destroy(portid_t port_id,
int port_queue_action_handle_update(portid_t port_id, uint32_t queue_id,
bool postpone, uint32_t id,
const struct rte_flow_action *action);
+int port_queue_action_handle_query(portid_t port_id, uint32_t queue_id,
+ bool postpone, uint32_t id);
int port_queue_flow_push(portid_t port_id, queueid_t queue_id);
int port_queue_flow_pull(portid_t port_id, queueid_t queue_id);
int port_flow_validate(portid_t port_id,
@@ -3911,6 +3911,22 @@ Asynchronous version of indirect action update API.
void *user_data,
struct rte_flow_error *error);
+Enqueue indirect action query operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Asynchronous version of indirect action query API.
+
+.. code-block:: c
+
+ int
+ rte_flow_async_action_handle_query(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *q_ops_attr,
+ struct rte_flow_action_handle *action_handle,
+ void *data,
+ void *user_data,
+ struct rte_flow_error *error);
+
Push enqueued operations
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -55,6 +55,11 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+* **Added support for queue based async query in rte_flow.**
+
+ Added new API ``rte_flow_async_action_handle_query()``, to query the
+ action asynchronously.
+
Removed Items
-------------
@@ -4676,6 +4676,25 @@ Query indirect action having id 100::
testpmd> flow indirect_action 0 query 100
+Enqueueing query of indirect actions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``flow queue indirect_action query`` adds query operation for an indirect
+action to a queue. It is bound to ``rte_flow_async_action_handle_query()``::
+
+ flow queue {port_id} indirect_action {queue_id} query
+ {indirect_action_id} [postpone {boolean}]
+
+If successful, it will show::
+
+ Indirect action #[...] query queued
+
+Otherwise it will show an error message of the form::
+
+ Caught error type [...] ([...]): [...]
+
+``flow queue pull`` must be called to retrieve the operation status.
+
Sample QinQ flow rules
~~~~~~~~~~~~~~~~~~~~~~
@@ -1844,3 +1844,21 @@ rte_flow_async_action_handle_update(uint16_t port_id,
action_handle, update, user_data, error);
return flow_err(port_id, ret, error);
}
+
+int
+rte_flow_async_action_handle_query(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ const struct rte_flow_action_handle *action_handle,
+ void *data,
+ void *user_data,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+ int ret;
+
+ ret = ops->async_action_handle_query(dev, queue_id, op_attr,
+ action_handle, data, user_data, error);
+ return flow_err(port_id, ret, error);
+}
@@ -5612,6 +5612,50 @@ rte_flow_async_action_handle_update(uint16_t port_id,
const void *update,
void *user_data,
struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue indirect action query operation.
+ *
+ * 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.
+ * Data will be available only when completion event returns.
+ *
+ * @see rte_flow_async_action_handle_query
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param[in] queue_id
+ * Flow queue which is used to query the action.
+ * @param[in] op_attr
+ * Indirect action update operation attributes.
+ * @param[in] action_handle
+ * Handle for the action object to query.
+ * @param[in, out] data
+ * Pointer to storage for the associated query data type.
+ * The out data will be available only when completion event returns
+ * from rte_flow_pull.
+ * @param[in] user_data
+ * The user data that will be returned on the completion events.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL. PMDs initialize this
+ * structure in case of error only.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+__rte_experimental
+int
+rte_flow_async_action_handle_query(uint16_t port_id,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ const struct rte_flow_action_handle *action_handle,
+ void *data,
+ void *user_data,
+ struct rte_flow_error *error);
#ifdef __cplusplus
}
#endif
@@ -260,6 +260,15 @@ struct rte_flow_ops {
const void *update,
void *user_data,
struct rte_flow_error *error);
+ /** See rte_flow_async_action_handle_query() */
+ int (*async_action_handle_query)
+ (struct rte_eth_dev *dev,
+ uint32_t queue_id,
+ const struct rte_flow_op_attr *op_attr,
+ const struct rte_flow_action_handle *action_handle,
+ void *data,
+ void *user_data,
+ struct rte_flow_error *error);
};
/**
@@ -285,6 +285,9 @@ EXPERIMENTAL {
rte_mtr_color_in_protocol_priority_get;
rte_mtr_color_in_protocol_set;
rte_mtr_meter_vlan_table_update;
+
+ # added in 22.11
+ rte_flow_async_action_handle_query;
};
INTERNAL {