From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E341B42C99; Mon, 12 Jun 2023 17:32:45 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7385F41138; Mon, 12 Jun 2023 17:32:45 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 67CB740698; Mon, 12 Jun 2023 17:32:43 +0200 (CEST) Received: from debian (unknown [78.109.68.125]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id 04528E11FD; Mon, 12 Jun 2023 19:32:41 +0400 (+04) Date: Mon, 12 Jun 2023 19:32:32 +0400 (+04) From: Ivan Malov To: Qi Zhang 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 In-Reply-To: <20230612111539.462084-1-qi.z.zhang@intel.com> Message-ID: <3b4c548-bf1f-ad57-6587-ad2b427d08e@arknetworks.am> References: <20230612111539.462084-1-qi.z.zhang@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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 > --- > 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 > +#include > + > +/** > + * 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 > >