- 0 on success, a negative errno value otherwise and ``rte_errno`` is set.
+Flow engine configuration
+-------------------------
+
+Configure flow API management.
+
+An application may provide some parameters at the initialization phase about
+rules engine configuration and/or expected flow rules characteristics.
+These parameters may be used by PMD to preallocate resources and configure NIC.
+
+Configuration
+~~~~~~~~~~~~~
+
+This function performs the flow API engine configuration and allocates
+requested resources beforehand to avoid costly allocations later.
+Expected number of resources in an application allows PMD to prepare
+and optimize NIC hardware configuration and memory layout in advance.
+``rte_flow_configure()`` must be called before any flow rule is created,
+but after an Ethernet device is configured.
+
+.. code-block:: c
+
+ int
+ rte_flow_configure(uint16_t port_id,
+ const struct rte_flow_port_attr *port_attr,
+ struct rte_flow_error *error);
+
+Information about the number of available resources can be retrieved via
+``rte_flow_info_get()`` API.
+
+.. code-block:: c
+
+ int
+ rte_flow_info_get(uint16_t port_id,
+ struct rte_flow_port_info *port_info,
+ struct rte_flow_error *error);
+
.. _flow_isolated_mode:
Flow isolated mode
- ``rte_ipv6_udptcp_cksum_mbuf()``
- ``rte_ipv6_udptcp_cksum_mbuf_verify()``
+* **Added functions to configure flow engine.**
+
+ * Added ``rte_flow_configure`` API to configure flow management
+ engine, allowing to pre-allocate some resources for better performance.
+ Added ``rte_flow_info_get`` API to retrieve available resources.
+
* **Added rte_flow support for matching GRE optional fields.**
Added ``gre_option`` item in rte_flow to support checksum/key/sequence
* Indicates whether the device is configured:
* CONFIGURED(1) / NOT CONFIGURED(0)
*/
- dev_configured : 1;
+ dev_configured : 1,
+ /**
+ * Indicates whether the flow engine is configured:
+ * CONFIGURED(1) / NOT CONFIGURED(0)
+ */
+ flow_configured : 1;
/** Queues state: HAIRPIN(2) / STARTED(1) / STOPPED(0) */
uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
ret = ops->flex_item_release(dev, handle, error);
return flow_err(port_id, ret, error);
}
+
+int
+rte_flow_info_get(uint16_t port_id,
+ struct rte_flow_port_info *port_info,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+ if (unlikely(!ops))
+ return -rte_errno;
+ if (dev->data->dev_configured == 0) {
+ RTE_FLOW_LOG(INFO,
+ "Device with port_id=%"PRIu16" is not configured.\n",
+ port_id);
+ return -EINVAL;
+ }
+ if (port_info == NULL) {
+ RTE_FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.\n", port_id);
+ return -EINVAL;
+ }
+ if (likely(!!ops->info_get)) {
+ return flow_err(port_id,
+ ops->info_get(dev, port_info, error),
+ error);
+ }
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
+
+int
+rte_flow_configure(uint16_t port_id,
+ const struct rte_flow_port_attr *port_attr,
+ struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+ int ret;
+
+ if (unlikely(!ops))
+ return -rte_errno;
+ if (dev->data->dev_configured == 0) {
+ RTE_FLOW_LOG(INFO,
+ "Device with port_id=%"PRIu16" is not configured.\n",
+ port_id);
+ return -EINVAL;
+ }
+ if (dev->data->dev_started != 0) {
+ RTE_FLOW_LOG(INFO,
+ "Device with port_id=%"PRIu16" already started.\n",
+ port_id);
+ return -EINVAL;
+ }
+ if (port_attr == NULL) {
+ RTE_FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.\n", port_id);
+ return -EINVAL;
+ }
+ if (likely(!!ops->configure)) {
+ ret = ops->configure(dev, port_attr, error);
+ if (ret == 0)
+ dev->data->flow_configured = 1;
+ return flow_err(port_id, ret, error);
+ }
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
extern "C" {
#endif
+#define RTE_FLOW_LOG(level, ...) \
+ rte_log(RTE_LOG_ ## level, rte_eth_dev_logtype, "" __VA_ARGS__)
+
/**
* Flow rule attributes.
*
const struct rte_flow_item_flex_handle *handle,
struct rte_flow_error *error);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Information about flow engine resources.
+ * The zero value means a resource is not supported.
+ *
+ */
+struct rte_flow_port_info {
+ /**
+ * Maximum number of counters.
+ * @see RTE_FLOW_ACTION_TYPE_COUNT
+ */
+ uint32_t max_nb_counters;
+ /**
+ * Maximum number of aging objects.
+ * @see RTE_FLOW_ACTION_TYPE_AGE
+ */
+ uint32_t max_nb_aging_objects;
+ /**
+ * Maximum number traffic meters.
+ * @see RTE_FLOW_ACTION_TYPE_METER
+ */
+ uint32_t max_nb_meters;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Get information about flow engine resources.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param[out] port_info
+ * A pointer to a structure of type *rte_flow_port_info*
+ * to be filled with the resources information of the port.
+ * @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_info_get(uint16_t port_id,
+ struct rte_flow_port_info *port_info,
+ struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Flow engine resources settings.
+ * The zero value means on demand resource allocations only.
+ *
+ */
+struct rte_flow_port_attr {
+ /**
+ * Number of counters to configure.
+ * @see RTE_FLOW_ACTION_TYPE_COUNT
+ */
+ uint32_t nb_counters;
+ /**
+ * Number of aging objects to configure.
+ * @see RTE_FLOW_ACTION_TYPE_AGE
+ */
+ uint32_t nb_aging_objects;
+ /**
+ * Number of traffic meters to configure.
+ * @see RTE_FLOW_ACTION_TYPE_METER
+ */
+ uint32_t nb_meters;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Configure the port's flow API engine.
+ *
+ * This API can only be invoked before the application
+ * starts using the rest of the flow library functions.
+ *
+ * The API can be invoked multiple times to change the settings.
+ * The port, however, may reject changes and keep the old config.
+ *
+ * Parameters in configuration attributes must not exceed
+ * numbers of resources returned by the rte_flow_info_get API.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param[in] port_attr
+ * Port configuration attributes.
+ * @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_configure(uint16_t port_id,
+ const struct rte_flow_port_attr *port_attr,
+ struct rte_flow_error *error);
+
#ifdef __cplusplus
}
#endif
(struct rte_eth_dev *dev,
const struct rte_flow_item_flex_handle *handle,
struct rte_flow_error *error);
+ /** See rte_flow_info_get() */
+ int (*info_get)
+ (struct rte_eth_dev *dev,
+ struct rte_flow_port_info *port_info,
+ struct rte_flow_error *err);
+ /** See rte_flow_configure() */
+ int (*configure)
+ (struct rte_eth_dev *dev,
+ const struct rte_flow_port_attr *port_attr,
+ struct rte_flow_error *err);
};
/**
rte_eth_ip_reassembly_capability_get;
rte_eth_ip_reassembly_conf_get;
rte_eth_ip_reassembly_conf_set;
+ rte_flow_info_get;
+ rte_flow_configure;
};
INTERNAL {