From: Ivan Malov <ivan.malov@arknetworks.am>
To: Qi Zhang <qi.z.zhang@intel.com>
Cc: thomas@monjalon.net, orika@nvidia.com, david.marchand@redhat.com,
bruce.richardson@intel.com, jerinj@marvell.com,
ferruh.yigit@amd.com, john.mcnamara@intel.com,
helin.zhang@intel.com, techboard@dpdk.org, dev@dpdk.org
Subject: Re: [RFC] lib/ethdev: introduce table driven APIs
Date: Mon, 12 Jun 2023 19:32:32 +0400 (+04) [thread overview]
Message-ID: <3b4c548-bf1f-ad57-6587-ad2b427d08e@arknetworks.am> (raw)
In-Reply-To: <20230612111539.462084-1-qi.z.zhang@intel.com>
Hi,
Thanks for sending the RFC. Sounds interesting.
My impression is that this API is rather low-level, so the
question is how does the application find a vendor-neutral
approach to discover and use specific table to do some job?
For example, the application needs to do some tunnel match
and decapsulation. It invokes rte_flow_table_list_get and
rte_flow_table_info_get. Say, there're four different
tables. How does the application know which of the
tables fits the purpose of tunnel match / decap?
Especially in the case when different tables
have overlapping match fields / actions.
Does the application have to expect some common names for
the same-purpose tables across different vendors/PMDs?
I'm asking because I'm trying to figure out how major
flow-based applications are expected to use the new
API in a generic, vendor-neutral manner.
Also, now you mention the pipeline approach, it appears
that the application may want to do some match/actions
in one table, then send the matched packet to another
one, using a jump action of sorts. But sometimes such
jumps are confined to specific paths. For example,
there are tables A, B, C and D, and the NIC only
allows transitions A -> C -> D or A -> D.
So my question is how does the proposed API expose
such constraints on packet transitions between
various tables?
Thank you.
On Mon, 12 Jun 2023, Qi Zhang wrote:
> The patch addresses the problem statement [1] by introducing
> a set of "Table-Driven" APIs in rte_flow.
>
> This approach is inspired by p4land/tdi [2] and is particularly
> beneficial for P4 programmable network controller drivers.
> It provides the following advantages:
>
> * Easy integration of DPDK as a P4 runtime [3] backend.
> * Reduced effort for PMDs to enable flow offloading when the packet
> processing unit is abstracted as a pipeline of match/action tables
> in low-level drivers.
>
> The new APIs can be categoried into 5 types
>
> 1. Learning APIs
>
> Retrieve information about attributes supported by each table
> and action specification in the current pipeline.
>
> rte_flow_table_list_get
> rte_flow_table_info_get
> rte_flow_table_info_get_by_name
> rte_flow_table_key_field_info_get
> rte_flow_table_key_field_info_get_by_name
> rte_flow_action_spec_list_group
> rte_flow_action_spec_info_get
> rte_flow_action_spec_info_get_by_name
> rte_flow_action_spec_field_info_get_by_name
>
> 2. Key / Action Object Management API:
>
> Create, destroy, and clone key and action objects.
>
> rte_flow_table_key_create
> rte_flow_table_key_destroy
> rte_flow_table_key_clone
> rte_flow_table_key_field_set
> rte_flow_table_key_field_set_by_name
> rte_flow_table_key_field_set_with_mask
> rte_flow_table_key_field_set_with_mask_by_name
> rte_flow_table_key_field_set_with_range
> rte_flow_table_key_field_set_with_range_by_name
> rte_flow_table_key_field_set_with_prefix_
> rte_flow_table_key_field_set_with_prefix_by_name
>
> rte_flow_table_action_create
> rte_flow_table_action_destroy
> rte_flow_table_action_clone
> rte_flow_table_action_field_get
> rte_flow_table_action_field_set
> rte_flow_table_action_field_set_by_name
>
> 3. Table Entry Update Synchronized APIs:
>
> Enable synchronized table updates, ensuring the updates are
> run-to-completion.
>
> rte_flow_table_entry_add
> rte_flow_table_entry_query
> rte_flow_table_entry_del
> rte_flow_table_entry_count_query
> rte_flow_table_default_action_set
> rte_flow_table_default_action_cancel
>
> 4. Table Entry Update Asynchronized APIs
>
> Provide asynchronous table update mode using a
> prepare/commit/pull pattern.
>
> rte_flow_table_entry_add_prepare
> rte_flow_table_entry_del_prepare
> rte_flow_table_update_status_commit
> rte_flow_table_update_status_pull
>
> 5. DPDK to PNA Interpretation APIs
>
> Facilitate APIs that map the DPDK context to the P4 Portable
> NIC Architecture (PNA) context, enabling interoperability between
> DPDK and PNA applications
>
> rte_flow_pna_port_get
> rte_flow_pna_rx_queue_get
> rte_flow_pna_tx_queue_get
>
> Follow the example in Problem Statement [1], to create a rule for
> table decap_vxlan_tcp_table with action decap_vxlan_fwd, we can
> use the following code.
>
> Code Snippet:
>
> /* Get the table info */
> struct rte_flow_table_info tbl_info;
> rte_flow_table_info_get_by_name(port_id, "decap_vxlan_tcp_table", &tbl_info);
>
> /* Create the key */
> struct rte_flow_table_key *key;
> rte_flow_table_key_create(port_id, tbl_info->id, &key);
>
> /* Set the key fields */
> rte_flow_table_key_field_set_by_name(port_id, key, "wire_port", &wire_port, 2);
> rte_flow_table_key_field_set_by_name(port_id, key, "tun_ip_src", &tun_ip_src, 4);
> rte_flow_table_key_field_set_by_name(port_id, key, "tun_ip_dst", &tun_ip_dst, 4);
> rte_flow_table_key_field_set_by_name(port_id, key, "vni", &vni, 3);
> rte_flow_table_key_field_set_by_name(port_id, key, "ipv4_src", &ipv4_src, 4);
> rte_flow_table_key_field_set_by_name(port_id, key, "ipv4_dst", &ipv4_dst, 4);
> rte_flow_table_key_field_set_by_name(port_id, key, "src_port", &src_port, 2);
> rte_flow_table_key_field_set_by_name(port_id, key, "dst_port", &dst_port, 2);
>
> /* Get the action spec info */
> struct rte_flow_action_spec_info as_info;
> rte_flow_action_spec_info_get_by_name(port_id, "decap_vxlan_fwd", &as_info);
>
> /* Create the action */
> struct rte_flow_table_action *action;
> rte_flow_table_action_create(port_id, as_info->id, &action);
>
> /* Set the action fields */
> rte_flow_table_action_field_set_by_name(port_id, action, "mod_id", &mod_id, 3);
> rte_flow_table_action_field_set_by_name(port_id, action, "port_id", &target_port_id, 2);
>
> /* Add the entry */
> rte_flow_table_entry_add(port_id, tbl_info->id, key, action);
>
> /* destroy key and action */
> rte_flow_table_action_destroy(port_id, action);
> rte_flow_table_key_destroy(port_id, key);
>
> ...
>
> Below code demonstrates how to use the prepare/commit/pull for
> high performance table entry updates.
>
> Code Snipped:
>
> struct rte_flow_table_key *keys[BATCH_SIZE];
> struct rte_flow_table_action *actions[BATCH_SIZE];
> struct rte_flow_table_update_status stats[BATCH_SIZE];
>
> /* Create Keys and Actions */
> for (i = 0; i < BATCH_SIZE; i++) {
> rte_flow_table_key_create(port_id, table_id, &keys[i]);
> /* set key field */
> rte_flow_table_key_field_set(...)
>
> rte_flow_table_action_create(port_id, table_id, spec_id, &actions[i]);
> /* set action field */
> rte_flow_table_action_field_set(...)
> }
>
> /* program loop */
> While (condition = true) {
>
> /* Prepare entry adding */
> for (i = 0; i < BATCH_SIZE; i++) {
> struct rte_flow_table_key *key = keys[i];
> struct rte_flow_table_action *action = actions[i];
>
> rte_flow_table_entry_add_prepare(port_id, TABLE_ID, key, action);
> }
>
> /* Commit to hardware */
> rte_flow_table_update_commit(port_id);
>
> /* pull status */
> int count = 0;
> while (count < BATCH_SIZE) {
> count += rte_flow_table_update_status_pull(port_id, stats, BATCH_SIZE, NULL);
> }
>
> /* reused Key and Action object */
> for (i = 0; i< BATCH_SIZE; i++) {
> struct rte_flow_table_key *key = stats[i].key;
> struct rte_flow_table_action *action = stats[i].action;
>
> rte_flow_table_key_field_set(...);
> rte_flow_table_action_field_set(...)
> }
> }
>
> ...
>
> NOTE: For simplicity, error check and the rte_flow_error
> parameter for each API has been omitted:
>
> [1]. http://mails.dpdk.org/archives/dev/2023-May/267719.html
> [2]. https://github.com/p4lang/tdi/
> [3]. https://p4.org/p4-spec/p4runtime/main/P4Runtime-Spec.html
>
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
> lib/ethdev/rte_flow_table.h | 1261 +++++++++++++++++++++++++++++++++++
> 1 file changed, 1261 insertions(+)
> create mode 100644 lib/ethdev/rte_flow_table.h
>
> diff --git a/lib/ethdev/rte_flow_table.h b/lib/ethdev/rte_flow_table.h
> new file mode 100644
> index 0000000000..31edf57a0f
> --- /dev/null
> +++ b/lib/ethdev/rte_flow_table.h
> @@ -0,0 +1,1261 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2023 Intel Corporation.
> + */
> +
> +#ifndef RTE_FLOW_TABLE_H_
> +#define RTE_FLOW_TABLE_H_
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +/**
> + * Max number of key field in a table.
> + */
> +#define RTE_FLOW_TABLE_KEY_FIELD_NUM_MAX 256
> +/**
> + * Max number of action spec in a table.
> + */
> +#define RTE_FLOW_TABLE_ACTION_SPEC_NUM_MAX 64
> +/**
> + * Max number of field in an action spec.
> + */
> +#define RTE_FLOW_ACTION_SPEC_FIELD_NUM_MAX 16
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Table key match type.
> + *
> + * To specify the key match type of a table.
> + */
> +enum rte_flow_table_key_match_type {
> + RTE_FLOW_TABLE_KEY_MATCH_TYPE_EXACT, /**< Exact match. */
> + RTE_FLOW_TABLE_KEY_MATCH_TYPE_WILDCARD, /**< Wildcard match. */
> + RTE_FLOW_TABLE_KEY_MATCH_TYPE_RANGE, /**< Range match. */
> + RTE_FLOW_TABLE_KEY_MATCH_TYPE_LPM, /**< longest prefix match. */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Byte order.
> + *
> + * To specify the byte order of table key / action field value in bytes.
> + */
> +enum rte_flow_byte_order {
> + RTE_FLOW_BYTE_ORDER_HOST, /**< follow host byte order. */
> + RTE_FLOW_BYTE_ORDER_NETWORK, /**< follow network byte order. */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Flow rule table info.
> + *
> + * A structure stores the properties of a flow rule table.
> + * Typically, a flow rule table represents to a P4 table which describe a
> + * match/action unit in packet process pipeline.
> + */
> +struct rte_flow_table_info {
> + uint32_t id; /**< Identifier of a table within the ethdev. */
> + const char *name; /**< Name of the table. */
> + const char *annotation; /**< Human readable message about this table. */
> + uint16_t key_field_num; /**< Number of key field. */
> + uint32_t key_fields[RTE_FLOW_TABLE_KEY_FIELD_NUM_MAX]; /**< Key field id array. */
> + uint16_t action_spec_num; /**< Number of action spec. */
> + uint32_t action_specs[RTE_FLOW_TABLE_ACTION_SPEC_NUM_MAX]; /**< Action spec id array */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Table key field info.
> + *
> + * A structure stores the properties of a table key field.
> + */
> +struct rte_flow_table_key_field_info {
> + uint32_t table_id; /**< Identifier of a table within the ethdev. */
> + uint32_t field_id; /**< Identifier of the key field within the table. */
> + const char *name; /**< Name of the key field. */
> + const char *annotation; /**< Human readable message about this key field. */
> + enum rte_flow_table_key_match_type match_type; /**< Key match type. */
> + uint16_t bit_width; /**< Bit width of the field value. */
> + uint16_t byte_width; /**< Number of bytes to store the field value. */
> + /**
> + * Byte order of the byte array that store the key value.
> + */
> + enum rte_flow_byte_order byte_order;
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Action spec info.
> + *
> + * A structure stores the properties of a action specification.
> + * Typically, a action specification represents a P4 Action.
> + */
> +struct rte_flow_action_spec_info {
> + uint32_t id; /**< Identifier of a action spec within the ethdev. */
> + const char *name; /**< Name of the action spec. */
> + const char *annotation; /**< Human readable message about this action spec */
> + uint16_t field_num; /**< Number of fields */
> + uint32_t fields[RTE_FLOW_ACTION_SPEC_FIELD_NUM_MAX]; /**< Field id array */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Action spec field info.
> + *
> + * A structure stores the properties of a action spec field.
> + */
> +struct rte_flow_action_spec_field_info {
> + uint32_t spec_id; /**< Identifier of a action spec within the ethdev. */
> + uint32_t field_id; /**< Identifier of the field within the action spec. */
> + const char *name; /**< Name of the field. */
> + const char *annotation; /**< Human readable message about this action spec. */
> + uint16_t bit_width; /**< Bit width of the field value */
> + uint16_t byte_width; /**< Number of bytes to store the field value. */
> + /**
> + * Byte order of the byte array that stores the key value.
> + */
> + enum rte_flow_byte_order byte_order;
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Table Key object.
> + *
> + * A structure represent a table key object, should be created / destroyed by
> + * rte_flow_table_key_create and rte_flow_table_key_destroy.
> + */
> +struct rte_flow_table_key {
> + uint32_t table_id; /**< Indicate which table the key instance belongs to. */
> + int ref_cnt; /**< Reference count, in async ops it prevents the object be destoried .*/
> + uint8_t data[]; /**< PMD specific data. */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Action object.
> + *
> + * A structure represent a table action object, should be created / destroyed by
> + * rte_flow_table_action_create and rte_flow_table_action_destroy.
> + */
> +struct rte_flow_table_action {
> + uint32_t table_id; /**< Indicate which table the action instance belongs to. */
> + uint32_t spec_id; /**< Indicate which action spec the action follow. */
> + int ref_cnt; /**< Reference count, in async ops it prevents the object be destoried .*/
> + uint8_t data[]; /**< PMD specific data. */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * ID list.
> + *
> + * An id list with variant size, should be created by
> + * rte_flow_table_list_popup or rte_flow_action_spec_list_popup.
> + *
> + * Application need to free the list by rte_free.
> + */
> +struct rte_flow_id_list {
> + uint32_t num; /**< Number of the id list */
> + uint32_t ids[]; /**< ID array */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Popup table id list.
> + *
> + * A variant size list that store all table identifiers will be created.
> + * Application need to free the list by rte_free.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[out] list
> + * A variant size id list, store all table identifiers of current ethernet
> + * device.
> + * @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_table_list_popup(uint16_t port_id,
> + struct rte_flow_id_list **list,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get table info by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[out] info
> + * Pointer to store the table info.
> + * @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_table_info_get(uint16_t port_id,
> + uint32_t table_id,
> + struct rte_flow_table_info *info,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> +* @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get table info by name.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] name
> + * Table name.
> + * @param[out] info
> + * Pointer to store the table info.
> + * @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_table_info_get_by_name(uint16_t port_id,
> + const char *name,
> + struct rte_flow_table_info *info,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get table key info by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] field_id
> + * Key field identifier.
> + * @param[info] info
> + * Pointer to store the table key field info.
> + * @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_table_key_field_info_get(uint16_t port_id,
> + uint32_t table_id,
> + uint32_t field_id,
> + struct rte_flow_table_key_field_info *info,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Popup action spec id list.
> + *
> + * A variant size list that store all action spec identifiers will be created.
> + * Application need to free the list by rte_free.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @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_action_spec_list_popup(uint16_t port_id,
> + struct rte_flow_id_list **list,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get action spec info by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] spec_id
> + * Action spec identifier.
> + * @info[out] info
> + * Pointer to store the action spec info.
> + * @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_action_spec_info_get(uint16_t port_id,
> + uint32_t spec_id,
> + struct rte_flow_action_spec_info *info,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get action spec info by name.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] name
> + * Action spec name.
> + * @info[out] info
> + * Pointer to store the action spec info.
> + * @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_action_spec_info_get_by_name(uint16_t port_id,
> + const char *name,
> + struct rte_flow_action_spec_info *info,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get action spec field info by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] spec_id
> + * Action spec identifier.
> + * @param[in] field_id
> + * Field identifier.
> + * @param[out] info
> + * Pointer to store the action spec field info.
> + * @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_action_spec_field_info_get(uint16_t port_id,
> + uint32_t spec_id,
> + uint32_t field_id,
> + struct rte_flow_action_spec_field_info *info,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Create a table key object.
> + *
> + * Application need to call rte_flow_table_key_destroy to free the key object.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[out] key
> + * Table key object created by PMD.
> + * @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_table_key_create(uint16_t port_id,
> + uint32_t table_id,
> + struct rte_flow_table_key **key,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Destroy a table key object.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to destroy.
> + * @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_table_key_destroy(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Create an table action object.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] spec_id
> + * Action spec identifier.
> + * @param[out] action
> + * Action key created by PMD.
> + * @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_table_action_create(uint16_t port_id,
> + uint32_t table_id,
> + uint32_t spec_id,
> + struct rte_flow_table_action **action,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Destroy an table action object.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] action
> + * Action object to destroy.
> + * @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_table_action_destroy(uint16_t port_id,
> + struct rte_flow_table_action *action,
> + struct rte_flow_error *error);
> +
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set table key field value by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] field_id
> + * key field identifier.
> + * @param[in] value
> + * Byte array to store the value
> + * @param[in] size
> + * Size of the byte array.
> + * @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_table_key_field_set(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + uint32_t field_id,
> + const uint8_t *value,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set table key field value by name.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] name
> + * key field name.
> + * @param[in] value
> + * Byte array to store the value to match.
> + * @param[in] size
> + * Size of the byte array.
> + * @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_table_key_field_set_by_name(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + const char *name,
> + const uint8_t *value,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set wildcard match key field by identifier.
> + *
> + * For wildcard match, only a bit set in mask should be matched.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] field_id
> + * Key field identifier.
> + * @param[in] value
> + * Byte array stores the value to match.
> + * @param[in] mask
> + * Byte array stores the bit mask.
> + * @param[in] size
> + * Size of value and mask byte array.
> + * @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_table_key_field_set_with_mask(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + uint32_t field_id,
> + const uint8_t *value,
> + const uint8_t *mask,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set wildcard match key field by name.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] name
> + * Key field name.
> + * @param[in] value
> + * Byte array stores the value to match.
> + * @param[in] mask
> + * Byte array stores the bit mask.
> + * @param[in] size
> + * Size of value and mask byte array.
> + * @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_table_key_field_set_with_mask_by_name(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + const char *name,
> + const uint8_t *value,
> + const uint8_t *mask,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set range match key field by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] field_id
> + * Key field identifier.
> + * @param[in] min
> + * Byte array stores the min value of the range to match
> + * @param[in] max
> + * Byte array stores the max value of the range to match
> + * @param[in] size
> + * Size of the min and max byte array
> + * @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_table_key_field_set_with_range(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + uint32_t field_id,
> + const uint8_t *min,
> + const uint8_t *max,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set range match key field by name.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] name
> + * Key field name.
> + * @param[in] min
> + * Byte array stores the min value of the range to match
> + * @param[in] max
> + * Byte array stores the max value of the range to match
> + * @param[in] size
> + * Size of the min and max byte array
> + * @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_table_key_field_set_with_range_by_name(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + const char *name,
> + const uint8_t *min,
> + const uint8_t *max,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set lpm match key field by identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] field_id
> + * Key field identifier.
> + * @param[in] value
> + * Byte array stores the value to match.
> + * @param[in] size
> + * Size of value byte array.
> + * @param[in] prefix
> + * Bits of the prefix to match, must <= (8 * size)
> + * @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_table_key_field_set_with_prefix(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + uint32_t field_id,
> + const uint8_t *value,
> + uint16_t size,
> + uint16_t prefix,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set lpm match key field by name.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to update.
> + * @param[in] name
> + * Key field name.
> + * @param[in] value
> + * Byte array stores the value to match.
> + * @param[in] size
> + * Size of value byte array.
> + * @param[in] prefix
> + * Bits of the prefix to match, must <= (8 * size)
> + * @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_table_key_field_set_with_prefix_by_name(uint16_t port_id,
> + struct rte_flow_table_key *key,
> + const char* name,
> + const uint8_t *value,
> + uint16_t size,
> + uint16_t prefix,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set action field value.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] action
> + * Action object to update.
> + * @param[in] field_id
> + * Field identifier.
> + * @param[in] value
> + * Byte array stores the value of the field.
> + * @param[in] size
> + * Size of the byte array.
> + * @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_table_action_field_set(uint16_t port_id,
> + struct rte_flow_table_action *action,
> + uint32_t field_id,
> + const uint8_t *value,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * get action field value, application may use rte_flow_table_entry_query
> + * to query by key and use this API to figure out each action field.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] action
> + * Action object to query.
> + * @param[in] field_id
> + * Field identifier.
> + * @param[out] value
> + * Byte array stores the value of the field.
> + * @param[in | out] size
> + * Input as size of the byte array, return the size of the value.
> + * @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_table_action_field_get(uint16_t port_id,
> + const struct rte_flow_table_action *action,
> + uint32_t field_id,
> + uint8_t *value,
> + uint16_t *size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] action
> + * Action object to update.
> + * @param[in] name
> + * Field name.
> + * @param[in] value
> + * Byte array stores the value of the field.
> + * @param[in] size
> + * Size of the byte array.
> + * @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_table_action_field_set_by_name(uint16_t port_id,
> + struct rte_flow_action *action,
> + const char *name,
> + const uint8_t *value,
> + uint16_t size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Set table default action.
> + *
> + * The default action will take effect when a packet hit no rules.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier
> + * @param[in] action
> + * Default action object.
> + * @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_table_default_action_set(uint16_t port_id,
> + uint32_t table_id,
> + const struct rte_flow_table_action *action,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Cancel table default action
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @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_table_default_action_cancel(uint32_t port_id,
> + uint32_t table_id,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Add matching rule as a table entry, the rule take effect immediately
> + * after the API call.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] key
> + * Table key object.
> + * @param[in] action
> + * Action object.
> + * @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_table_entry_add(uint16_t port_id,
> + uint32_t table_id,
> + const struct rte_flow_table_key *key,
> + const struct rte_flow_table_action *action,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Query action of a table entry.
> + *
> + * If success, a new rte_flow_table_action object will be created.
> + * Use rte_flow_table_action_destroy to free the resource.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] key
> + * Table key object.
> + * @param[out] action
> + * Action object returned.
> + * @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_table_entry_query(uint16_t port_id,
> + uint32_t table_id,
> + const struct rte_flow_table_key *key,
> + struct rte_flow_table_action **action,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Delete a table entry, this take effect immeidatly after the API call.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] key
> + * Table key object to match.
> + * @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_table_entry_del(uint16_t port_id,
> + uint32_t table_id,
> + const struct rte_flow_table_key *key,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Query rule hit counters.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] key
> + * Table key object to match.
> + * @param[out] count
> + * Pointer stores the hit counters.
> + * @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_table_entry_count_query(uint16_t port_id,
> + uint32_t table_id,
> + const struct rte_flow_table_key *key,
> + struct rte_flow_query_count *count,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Clone a table key object.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] key
> + * Table key object to clone.
> + * @param[out] new_key
> + * New table key object be created by PMD.
> + * @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_table_key_clone(uint16_t port_id,
> + const struct rte_flow_table_key *key,
> + struct rte_flow_table_key **new_key,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Clone a action object.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] action
> + * Action object to clone.
> + * @param[out] new_action
> + * New action object be created by PMD.
> + * @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_table_action_clone(uint16_t port_id,
> + const struct rte_flow_action *action,
> + struct rte_flow_action **new_action,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Prepare table entry adding.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] key
> + * Table key object.
> + * @param[in] action
> + * Action object.
> + * @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_table_entry_add_prepare(uint16_t port_id,
> + uint32_t table_id,
> + struct rte_flow_table_key *key,
> + struct rte_flow_table_action *action,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Prepare table entry deletion.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] table_id
> + * Table identifier.
> + * @param[in] key
> + * Table key object to match.
> + * @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_table_entry_del_prepare(uint16_t port_id,
> + uint32_t table_id,
> + struct rte_flow_table_key *key,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Commit all prepared adding and deletion requests.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @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_table_update_commit(uint16_t port_id,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Table entry operation type.
> + */
> +
> +enum rte_flow_table_update_op {
> + RTE_FLOW_TABLE_ENTRY_OP_ADD, /* Add an entry */
> + RTE_FLOW_TABLE_ENTRY_OP_DEL, /* Delete an entry */
> + RTE_FLOW_TABLE_ENTRY_OP_QRY, /* Query an entry */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Table entry update status.
> + */
> +struct rte_flow_table_update_status {
> + struct rte_flow_table_key *key; /**< Table key object of the entry */
> + struct rte_flow_table_action *action; /**< Action object of the entry */
> + enum rte_flow_table_update_op op; /**< Operation type */
> + enum rte_flow_error_type err; /**< Error type */
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Pull table entry update status.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[out] stats
> + * An array stores the status of all finished entry adding / delete
> + * requests.
> + * @param[in] size
> + * Size of the input array.
> + * @param[out] error
> + * Perform verbose error reporting if not NULL. PMDs initialize this
> + * structure in case of error only.
> + *
> + * @return
> + * >=0 on success, indiates the number of status be pulled.
> + * A negative errno value otherwise and rte_errno is set.
> + */
> +__rte_experimental int
> +rte_flow_table_update_status_pull(uint16_t port_id,
> + struct rte_flow_table_update_status *stats,
> + int size,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get PNA port identifier.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] ethdev_port_id
> + * Ethdev port identifier maps to the required PNA port.
> + * @param[out] pna_port_id
> + * Pointer stores the PNA port identifier.
> + * @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_pna_port_get(uint16_t port_id,
> + uint16_t ethdev_port_id,
> + uint32_t *hw_port_id,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get a PNA queue identifer from a ethdev Rx queue.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] ethdev_port_id
> + * Ethdev port identifier the Rx queue belongs to.
> + * @param[in] ethdev_queue_id
> + * Ethdev Rx queue index that maps to the required PNA queue identifier.
> + * @param[out] pna_queue_id
> + * Pointer stores the PNA queue identifier.
> + * @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_pna_rx_queue_get(uint16_t port_id,
> + uint16_t ethdev_port_id,
> + uint16_t ethdev_queue_id,
> + uint32_t *hw_queue_id,
> + struct rte_flow_error *error);
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this API may change without prior notice.
> + *
> + * Get a PNA queue identifer from a ethdev Tx queue.
> + *
> + * @param[in] port_id
> + * Port identifier of the Ethernet device.
> + * @param[in] ethdev_port_id
> + * Ethdev port identifier the Tx queue belongs to.
> + * @param[in] ethdev_queue_id
> + * Ethdev Tx queue index that maps to the required PNA queue identifier.
> + * @param[out] pna_queue_id
> + * Pointer stores the PNA queue identifier.
> + * @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_pna_tx_queue_get(uint16_t port_id,
> + uint16_t ethdev_port_id,
> + uint16_t ethdev_queue_id,
> + uint32_t *hw_queue_id,
> + struct rte_flow_error *error);
> +#endif
> --
> 2.31.1
>
>
next prev parent reply other threads:[~2023-06-12 15:32 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-12 11:15 Qi Zhang
2023-06-12 15:32 ` Ivan Malov [this message]
2023-06-13 3:48 ` Zhang, Qi Z
2023-06-13 6:38 ` Ivan Malov
2023-06-14 5:42 ` Zhang, Qi Z
2023-06-14 18:30 ` Ori Kam
2023-06-15 2:25 ` Zhang, Qi Z
2023-06-15 4:57 ` Jerin Jacob
2023-06-15 6:03 ` Zhang, Qi Z
2023-06-15 6:21 ` Jerin Jacob
2023-06-15 7:42 ` Zhang, Qi Z
2023-06-15 8:37 ` Jerin Jacob
2023-06-15 13:25 ` Zhang, Qi Z
2023-06-16 1:20 ` Jerin Jacob
2023-06-19 0:22 ` Zhang, Qi Z
2023-06-19 9:52 ` Jerin Jacob
2023-06-20 1:52 ` Zhang, Qi Z
2023-06-20 5:06 ` Jerin Jacob
2023-06-20 11:10 ` Ori Kam
2023-07-19 13:39 ` Dumitrescu, Cristian
2023-08-02 9:31 ` Dumitrescu, Cristian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3b4c548-bf1f-ad57-6587-ad2b427d08e@arknetworks.am \
--to=ivan.malov@arknetworks.am \
--cc=bruce.richardson@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=helin.zhang@intel.com \
--cc=jerinj@marvell.com \
--cc=john.mcnamara@intel.com \
--cc=orika@nvidia.com \
--cc=qi.z.zhang@intel.com \
--cc=techboard@dpdk.org \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).