From patchwork Mon Jun 12 11:15:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 128501 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 54D9E42C91; Mon, 12 Jun 2023 04:56:25 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CFEBD42D84; Mon, 12 Jun 2023 04:56:24 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id D163A42D62; Mon, 12 Jun 2023 04:56:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1686538583; x=1718074583; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=2U/CdYHh2aUQLJenGq/f1FrYLGrfOBVNigfvIkTOJ94=; b=Swp13+oYtHLqrVNn+aR/cbdvmD++jLkVX6KZ1FCgF8q5LXzI02XpLGhq kRZSNry+VuvhtRQVUbjLrNsxqZD0oVKZH8t583NCltwT8MwAProc2Zxfy qA50m2XwqUOcwpqfpjFaGldM0VjAgwfsRYI98E7pCPwUrzKs/zaJuPVBs iAR7+ppE+gNNZe1TRNausd7bUjXp/4gAJKg5uUIhW7LPkSS8Jg8zrGhZY S3Z0Plfhp0SyDbOTvYrDUwyWLT0MqKYj7rqDTYeihMfYfwzS3twgyHf8T qfWbhfygvtmSfVMzaOnIbBLh1gG4fDsoO3YvghjyNOFfUvX3u9ntJvCfp Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10738"; a="357927145" X-IronPort-AV: E=Sophos;i="6.00,235,1681196400"; d="scan'208";a="357927145" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2023 19:56:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10738"; a="800858800" X-IronPort-AV: E=Sophos;i="6.00,235,1681196400"; d="scan'208";a="800858800" Received: from dpdk-qzhan15-test02.sh.intel.com ([10.67.115.37]) by FMSMGA003.fm.intel.com with ESMTP; 11 Jun 2023 19:56:18 -0700 From: Qi Zhang To: thomas@monjalon.net, orika@nvidia.com, david.marchand@redhat.com, bruce.richardson@intel.com, jerinj@marvell.com, ferruh.yigit@amd.com Cc: john.mcnamara@intel.com, helin.zhang@intel.com, techboard@dpdk.org, dev@dpdk.org, Qi Zhang Subject: [RFC] lib/ethdev: introduce table driven APIs Date: Mon, 12 Jun 2023 07:15:39 -0400 Message-Id: <20230612111539.462084-1-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 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 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