+port_flow_pattern_template_create(portid_t port_id, uint32_t id,
+ const struct rte_flow_pattern_template_attr *attr,
+ const struct rte_flow_item *pattern)
+{
+ struct rte_port *port;
+ struct port_template *pit;
+ int ret;
+ struct rte_flow_error error;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ ret = template_alloc(id, &pit, &port->pattern_templ_list);
+ if (ret)
+ return ret;
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x22, sizeof(error));
+ pit->template.pattern_template = rte_flow_pattern_template_create(port_id,
+ attr, pattern, &error);
+ if (!pit->template.pattern_template) {
+ uint32_t destroy_id = pit->id;
+ port_flow_pattern_template_destroy(port_id, 1, &destroy_id);
+ return port_flow_complain(&error);
+ }
+ printf("Pattern template #%u created\n", pit->id);
+ return 0;
+}
+
+/** Destroy pattern template */
+int
+port_flow_pattern_template_destroy(portid_t port_id, uint32_t n,
+ const uint32_t *template)
+{
+ struct rte_port *port;
+ struct port_template **tmp;
+ uint32_t c = 0;
+ int ret = 0;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ tmp = &port->pattern_templ_list;
+ while (*tmp) {
+ uint32_t i;
+
+ for (i = 0; i != n; ++i) {
+ struct rte_flow_error error;
+ struct port_template *pit = *tmp;
+
+ if (template[i] != pit->id)
+ continue;
+ /*
+ * Poisoning to make sure PMDs update it in case
+ * of error.
+ */
+ memset(&error, 0x33, sizeof(error));
+
+ if (pit->template.pattern_template &&
+ rte_flow_pattern_template_destroy(port_id,
+ pit->template.pattern_template,
+ &error)) {
+ ret = port_flow_complain(&error);
+ continue;
+ }
+ *tmp = pit->next;
+ printf("Pattern template #%u destroyed\n", pit->id);
+ free(pit);
+ break;
+ }
+ if (i == n)
+ tmp = &(*tmp)->next;
+ ++c;
+ }
+ return ret;
+}
+
+/** Create actions template */
+int
+port_flow_actions_template_create(portid_t port_id, uint32_t id,
+ const struct rte_flow_actions_template_attr *attr,
+ const struct rte_flow_action *actions,
+ const struct rte_flow_action *masks)
+{
+ struct rte_port *port;
+ struct port_template *pat;
+ int ret;
+ struct rte_flow_error error;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ ret = template_alloc(id, &pat, &port->actions_templ_list);
+ if (ret)
+ return ret;
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x22, sizeof(error));
+ pat->template.actions_template = rte_flow_actions_template_create(port_id,
+ attr, actions, masks, &error);
+ if (!pat->template.actions_template) {
+ uint32_t destroy_id = pat->id;
+ port_flow_actions_template_destroy(port_id, 1, &destroy_id);
+ return port_flow_complain(&error);
+ }
+ printf("Actions template #%u created\n", pat->id);
+ return 0;
+}
+
+/** Destroy actions template */
+int
+port_flow_actions_template_destroy(portid_t port_id, uint32_t n,
+ const uint32_t *template)
+{
+ struct rte_port *port;
+ struct port_template **tmp;
+ uint32_t c = 0;
+ int ret = 0;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ tmp = &port->actions_templ_list;
+ while (*tmp) {
+ uint32_t i;
+
+ for (i = 0; i != n; ++i) {
+ struct rte_flow_error error;
+ struct port_template *pat = *tmp;
+
+ if (template[i] != pat->id)
+ continue;
+ /*
+ * Poisoning to make sure PMDs update it in case
+ * of error.
+ */
+ memset(&error, 0x33, sizeof(error));
+
+ if (pat->template.actions_template &&
+ rte_flow_actions_template_destroy(port_id,
+ pat->template.actions_template, &error)) {
+ ret = port_flow_complain(&error);
+ continue;
+ }
+ *tmp = pat->next;
+ printf("Actions template #%u destroyed\n", pat->id);
+ free(pat);
+ break;
+ }
+ if (i == n)
+ tmp = &(*tmp)->next;
+ ++c;
+ }
+ return ret;
+}
+
+/** Create table */
+int
+port_flow_template_table_create(portid_t port_id, uint32_t id,
+ const struct rte_flow_template_table_attr *table_attr,
+ uint32_t nb_pattern_templates, uint32_t *pattern_templates,
+ uint32_t nb_actions_templates, uint32_t *actions_templates)