+ [1] = {.type = RTE_FLOW_ACTION_TYPE_QUEUE},
+ [2] = {.type = RTE_FLOW_ACTION_TYPE_END,},
+ };
+ struct rte_flow_error err;
+
+ struct rte_flow_actions_template *actions_template =
+ rte_flow_actions_template_create(port, &attr, &act, &msk, &err);
+
+The concrete value for Queue Index will be provided at the rule creation.
[snip]
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index ffd48e40d5..e9f684eedb 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1461,3 +1461,255 @@ rte_flow_configure(uint16_t port_id,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOTSUP));
}
+
+struct rte_flow_pattern_template *
+rte_flow_pattern_template_create(uint16_t port_id,
+ const struct rte_flow_pattern_template_attr *template_attr,
+ const struct rte_flow_item pattern[],
+ 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);
+ struct rte_flow_pattern_template *template;
+
+ if (template_attr == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" template attr is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (pattern == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" pattern is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (dev->data->flow_configured == 0) {
+ RTE_FLOW_LOG(INFO,
+ "Flow engine on port_id=%"PRIu16" is not configured.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_STATE,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (unlikely(!ops))
+ return NULL;
See notes about order of checks in previous patch review notes.
+ if (likely(!!ops->pattern_template_create)) {
+ template = ops->pattern_template_create(dev, template_attr,
+ pattern, error);
+ if (template == NULL)
+ flow_err(port_id, -rte_errno, error);
+ return template;
+ }
+ rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+ return NULL;
+}
+
+int
+rte_flow_pattern_template_destroy(uint16_t port_id,
+ struct rte_flow_pattern_template *pattern_template,
+ 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(pattern_template == NULL))
+ return 0;
+ if (unlikely(!ops))
+ return -rte_errno;
Same here. I'm afraid it is really important here as well,
since request should not return OK if port_id is invalid.
+ if (likely(!!ops->pattern_template_destroy)) {
+ return flow_err(port_id,
+ ops->pattern_template_destroy(dev,
+ pattern_template,
+ error),
+ error);
+ }
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
+
+struct rte_flow_actions_template *
+rte_flow_actions_template_create(uint16_t port_id,
+ const struct rte_flow_actions_template_attr
*template_attr,
+ const struct rte_flow_action actions[],
+ const struct rte_flow_action masks[],
+ 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);
+ struct rte_flow_actions_template *template;
+
+ if (template_attr == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" template attr is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (actions == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" actions is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (masks == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" masks is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+
+ }
+ if (dev->data->flow_configured == 0) {
+ RTE_FLOW_LOG(INFO,
+ "Flow engine on port_id=%"PRIu16" is not configured.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_STATE,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (unlikely(!ops))
+ return NULL;
same here
+ if (likely(!!ops->actions_template_create)) {
+ template = ops->actions_template_create(dev, template_attr,
+ actions, masks, error);
+ if (template == NULL)
+ flow_err(port_id, -rte_errno, error);
+ return template;
+ }
+ rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+ return NULL;
+}
+
+int
+rte_flow_actions_template_destroy(uint16_t port_id,
+ struct rte_flow_actions_template *actions_template,
+ 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(actions_template == NULL))
+ return 0;
+ if (unlikely(!ops))
+ return -rte_errno;
same here
+ if (likely(!!ops->actions_template_destroy)) {
+ return flow_err(port_id,
+ ops->actions_template_destroy(dev,
+ actions_template,
+ error),
+ error);
+ }
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
+
+struct rte_flow_template_table *
+rte_flow_template_table_create(uint16_t port_id,
+ const struct rte_flow_template_table_attr *table_attr,
+ struct rte_flow_pattern_template *pattern_templates[],
+ uint8_t nb_pattern_templates,
+ struct rte_flow_actions_template *actions_templates[],
+ uint8_t nb_actions_templates,
+ 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);
+ struct rte_flow_template_table *table;
+
+ if (table_attr == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" table attr is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (pattern_templates == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" pattern templates is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (actions_templates == NULL) {
+ RTE_FLOW_LOG(ERR,
+ "Port %"PRIu16" actions templates is NULL.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (dev->data->flow_configured == 0) {
+ RTE_FLOW_LOG(INFO,
+ "Flow engine on port_id=%"PRIu16" is not configured.\n",
+ port_id);
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_STATE,
+ NULL, rte_strerror(EINVAL));
+ return NULL;
+ }
+ if (unlikely(!ops))
+ return NULL;
Order of checks
+ if (likely(!!ops->template_table_create)) {
+ table = ops->template_table_create(dev, table_attr,
+ pattern_templates, nb_pattern_templates,
+ actions_templates, nb_actions_templates,
+ error);
+ if (table == NULL)
+ flow_err(port_id, -rte_errno, error);
+ return table;
+ }
+ rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+ return NULL;
+}
+
+int
+rte_flow_template_table_destroy(uint16_t port_id,
+ struct rte_flow_template_table *template_table,
+ 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(template_table == NULL))
+ return 0;
+ if (unlikely(!ops))
+ return -rte_errno;
+ if (likely(!!ops->template_table_destroy)) {
+ return flow_err(port_id,
+ ops->template_table_destroy(dev,
+ template_table,
+ error),
+ error);
+ }
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index cdb7b2be68..776e8ccc11 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -4983,6 +4983,280 @@ rte_flow_configure(uint16_t port_id,
const struct rte_flow_port_attr *port_attr,
struct rte_flow_error *error);
+/**
+ * Opaque type returned after successful creation of pattern template.
+ * This handle can be used to manage the created pattern template.
+ */
+struct rte_flow_pattern_template;
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Flow pattern template attributes.
Would it be useful to mentioned that at least one direction
bit must be set? Otherwise request does not make sense.