* Handle to flow classifier instance
* @param params
* Parameters for flow_classify table creation
- * @param table_id
- * Table ID. Valid only within the scope of table IDs of the current
- * classifier. Only returned after a successful invocation.
* @return
* 0 on success, error code otherwise
*/
int
rte_flow_classify_table_create(struct rte_flow_classifier *cls,
- struct rte_flow_classify_table_params *params,
- uint32_t *table_id);
+ struct rte_flow_classify_table_params *params);
+
+ /**
+ * Validate the flow classify rule
+ *
+ * @param[in] cls
+ * Handle to flow classifier instance
+ * @param[in] attr
+ * Flow rule attributes
+ * @param[in] pattern
+ * Pattern specification (list terminated by the END pattern item).
+ * @param[in] actions
+ * Associated actions (list terminated by the END pattern item).
+ * @param[out] error
+ * Perform verbose error reporting if not NULL. Structure
+ * initialised in case of error only.
+ * @return
+ * 0 on success, error code otherwise
+ */
+ int
+ rte_flow_classify_validate(struct rte_flow_classifier *cls,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error);
/**
* Add a flow classify rule to the flow_classifier table.
*
* @param[in] cls
* Flow classifier handle
- * @param[in] table_id
- * id of table
* @param[in] attr
* Flow rule attributes
* @param[in] pattern
* Pattern specification (list terminated by the END pattern item).
* @param[in] actions
* Associated actions (list terminated by the END pattern item).
+ * @param[out] key_found
+ * returns 1 if rule present already, 0 otherwise.
* @param[out] error
* Perform verbose error reporting if not NULL. Structure
* initialised in case of error only.
*/
struct rte_flow_classify_rule *
rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls,
- uint32_t table_id,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
+ int *key_found;
struct rte_flow_error *error);
/**
*
* @param[in] cls
* Flow classifier handle
- * @param[in] table_id
- * id of table
* @param[in] rule
* Flow classify rule
* @return
*/
int
rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
- uint32_t table_id,
struct rte_flow_classify_rule *rule);
/**
*
* @param[in] cls
* Flow classifier handle
- * @param[in] table_id
- * id of table
* @param[in] pkts
* Pointer to packets to process
* @param[in] nb_pkts
*/
int
rte_flow_classifier_query(struct rte_flow_classifier *cls,
- uint32_t table_id,
struct rte_mbuf **pkts,
const uint16_t nb_pkts,
struct rte_flow_classify_rule *rule,
/** CPU socket ID where memory for the flow classifier and its */
/** elements (tables) should be allocated */
int socket_id;
-
- /** Table type */
- enum rte_flow_classify_table_type type;
};
The ``Classifier`` has the following internal structures:
.. code-block:: c
- struct rte_table {
+ struct rte_cls_table {
/* Input parameters */
struct rte_table_ops ops;
uint32_t entry_size;
/* Input parameters */
char name[RTE_FLOW_CLASSIFIER_MAX_NAME_SZ];
int socket_id;
- enum rte_flow_classify_table_type type;
- /* Internal tables */
- struct rte_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX];
+ /* Internal */
+ /* ntuple_filter */
+ struct rte_eth_ntuple_filter ntuple_filter;
+
+ /* classifier tables */
+ struct rte_cls_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX];
+ uint32_t table_mask;
uint32_t num_tables;
+
uint16_t nb_pkts;
struct rte_flow_classify_table_entry
*entries[RTE_PORT_IN_BURST_SIZE_MAX];
/** Opaque param to be passed to the table create operation */
void *arg_create;
- /** Memory size to be reserved per classifier object entry for */
- /** storing meta data */
- uint32_t table_metadata_size;
+ /** Classifier table type */
+ enum rte_flow_classify_table_type type;
};
To create an ACL table the ``rte_table_acl_params`` structure must be
RTE_FLOW_ITEM_TYPE_END,
};
-The internal function ``flow_classify_parse_flow`` parses the
+The API function ``rte_flow_classify_validate`` parses the
IPv4 5-tuple pattern, attributes and actions and returns the 5-tuple data in the
``rte_eth_ntuple_filter`` structure.
.. code-block:: c
static int
- flow_classify_parse_flow(
+ rte_flow_classify_validate(struct rte_flow_classifier *cls,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
The ``rte_flow_classify_table_entry_add`` API creates an
``rte_flow_classify`` object which contains the flow_classify id and type, the
action, a union of add and delete keys and a union of rules.
-It uses the ``flow_classify_parse_flow`` internal function for parsing the
+It uses the ``rte_flow_classify_validate`` API function for parsing the
flow parameters.
The 5-tuple ACL key data is obtained from the ``rte_eth_ntuple_filter``
structure populated by the ``classify_parse_ntuple_filter`` function which
struct acl_keys {
struct rte_table_acl_rule_add_params key_add; /* add key */
- struct rte_table_acl_rule_delete_params key_del; /* delete key */
+ struct rte_table_acl_rule_delete_params key_del; /* delete key */
};
struct classify_rules {
struct rte_flow_classify {
uint32_t id; /* unique ID of classify object */
- struct rte_flow_action action; /* action when match found */
- struct classify_rules rules; /* union of rules */
+ enum rte_flow_classify_table_type tbl_type; /* rule table */
+ struct classify_rules rules; /* union of rules */
union {
struct acl_keys key;
} u;
int key_found; /* rule key found in table */
- void *entry; /* pointer to buffer to hold rule meta data */
+ struct rte_flow_classify_table_entry entry; /* rule meta data */
void *entry_ptr; /* handle to the table entry for rule meta data */
};
-It then calls the ``table[table_id].ops.f_add`` API to add the rule to the ACL
+It then calls the ``table.ops.f_add`` API to add the rule to the ACL
table.
Deleting Flow Rules
~~~~~~~~~~~~~~~~~~~
The ``rte_flow_classify_table_entry_delete`` API calls the
-``table[table_id].ops.f_delete`` API to delete a rule from the ACL table.
+``table.ops.f_delete`` API to delete a rule from the ACL table.
Packet Matching
~~~~~~~~~~~~~~~
The ``rte_flow_classifier_query`` API is used to find packets which match a
given flow Flow rule in the table.
This API calls the flow_classify_run internal function which calls the
-``table[table_id].ops.f_lookup`` API to see if any packets in a burst match any
+``table.ops.f_lookup`` API to see if any packets in a burst match any
of the Flow rules in the table.
The meta data for the highest priority rule matched for each packet is returned
in the entries array in the ``rte_flow_classify`` object.
struct flow_classifier {
struct rte_flow_classifier *cls;
- uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX];
};
struct flow_classifier_acl {
cls_params.name = "flow_classifier";
cls_params.socket_id = socket_id;
- cls_params.type = RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL;
cls_app->cls = rte_flow_classifier_create(&cls_params);
if (cls_app->cls == NULL) {
/* initialise table create params */
cls_table_params.ops = &rte_table_acl_ops,
cls_table_params.arg_create = &table_acl_params,
- cls_table_params.table_metadata_size = 0;
+ cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE;
- ret = rte_flow_classify_table_create(cls_app->cls, &cls_table_params,
- &cls->table_id[0]);
+ ret = rte_flow_classify_table_create(cls_app->cls, &cls_table_params);
if (ret) {
rte_flow_classifier_free(cls_app->cls);
rte_free(cls);
if (rules[i]) {
ret = rte_flow_classifier_query(
cls_app->cls,
- cls_app->table_id[0],
bufs, nb_rx, rules[i],
&classify_stats);
if (ret)
struct flow_classifier {
struct rte_flow_classifier *cls;
- uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX];
};
struct flow_classifier_acl {
/* sample actions:
* "actions count / end"
*/
-static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, 0};
+struct rte_flow_query_count count = {
+ .reset = 1,
+ .hits_set = 1,
+ .bytes_set = 1,
+ .hits = 0,
+ .bytes = 0,
+};
+static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
+ &count};
static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};
static struct rte_flow_action actions[2];
int i = 0;
ret = rte_flow_classify_table_entry_delete(cls_app->cls,
- cls_app->table_id[0], rules[7]);
+ rules[7]);
if (ret)
printf("table_entry_delete failed [7] %d\n\n", ret);
else
port);
printf("to polling thread.\n");
printf("Performance will not be optimal.\n");
-
- printf("\nCore %u forwarding packets. ",
- rte_lcore_id());
- printf("[Ctrl+C to quit]\n");
}
+ printf("\nCore %u forwarding packets. ", rte_lcore_id());
+ printf("[Ctrl+C to quit]\n");
+
/* Run until the application is quit or killed. */
for (;;) {
/*
if (rules[i]) {
ret = rte_flow_classifier_query(
cls_app->cls,
- cls_app->table_id[0],
bufs, nb_rx, rules[i],
&classify_stats);
if (ret)
actions[0] = count_action;
actions[1] = end_action;
+ /* Validate and add rule */
+ ret = rte_flow_classify_validate(cls_app->cls, &attr,
+ pattern_ipv4_5tuple, actions, &error);
+ if (ret) {
+ printf("table entry validate failed ipv4_proto = %u\n",
+ ipv4_proto);
+ return ret;
+ }
+
rule = rte_flow_classify_table_entry_add(
- cls_app->cls, cls_app->table_id[0], &key_found,
- &attr, pattern_ipv4_5tuple, actions, &error);
+ cls_app->cls, &attr, pattern_ipv4_5tuple,
+ actions, &key_found, &error);
if (rule == NULL) {
printf("table entry add failed ipv4_proto = %u\n",
ipv4_proto);
cls_params.name = "flow_classifier";
cls_params.socket_id = socket_id;
- cls_params.type = RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL;
cls_app->cls = rte_flow_classifier_create(&cls_params);
if (cls_app->cls == NULL) {
memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
/* initialise table create params */
- cls_table_params.ops = &rte_table_acl_ops,
- cls_table_params.arg_create = &table_acl_params,
+ cls_table_params.ops = &rte_table_acl_ops;
+ cls_table_params.arg_create = &table_acl_params;
+ cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE;
- ret = rte_flow_classify_table_create(cls_app->cls, &cls_table_params,
- &cls_app->table_id[0]);
+ ret = rte_flow_classify_table_create(cls_app->cls, &cls_table_params);
if (ret) {
rte_flow_classifier_free(cls_app->cls);
rte_free(cls_app);
int librte_flow_classify_logtype;
-static struct rte_eth_ntuple_filter ntuple_filter;
static uint32_t unique_id = 1;
+enum rte_flow_classify_table_type table_type
+ = RTE_FLOW_CLASSIFY_TABLE_TYPE_NONE;
struct rte_flow_classify_table_entry {
/* meta-data for classify rule */
uint32_t rule_id;
+
+ /* Flow action */
+ struct classify_action action;
};
-struct rte_table {
+struct rte_cls_table {
/* Input parameters */
struct rte_table_ops ops;
uint32_t entry_size;
/* Input parameters */
char name[RTE_FLOW_CLASSIFIER_MAX_NAME_SZ];
int socket_id;
- enum rte_flow_classify_table_type type;
- /* Internal tables */
- struct rte_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX];
+ /* Internal */
+ /* ntuple_filter */
+ struct rte_eth_ntuple_filter ntuple_filter;
+
+ /* classifier tables */
+ struct rte_cls_table tables[RTE_FLOW_CLASSIFY_TABLE_MAX];
+ uint32_t table_mask;
uint32_t num_tables;
+
uint16_t nb_pkts;
struct rte_flow_classify_table_entry
*entries[RTE_PORT_IN_BURST_SIZE_MAX];
struct rte_flow_classify_rule {
uint32_t id; /* unique ID of classify rule */
- struct rte_flow_action action; /* action when match found */
+ enum rte_flow_classify_table_type tbl_type; /* rule table */
struct classify_rules rules; /* union of rules */
union {
struct acl_keys key;
} u;
int key_found; /* rule key found in table */
- void *entry; /* pointer to buffer to hold rule meta data */
+ struct rte_flow_classify_table_entry entry; /* rule meta data */
void *entry_ptr; /* handle to the table entry for rule meta data */
};
-static int
-flow_classify_parse_flow(
+int
+rte_flow_classify_validate(
+ struct rte_flow_classifier *cls,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
uint32_t i = 0;
int ret;
- memset(&ntuple_filter, 0, sizeof(ntuple_filter));
+ if (error == NULL)
+ return -EINVAL;
+
+ if (cls == NULL) {
+ RTE_FLOW_CLASSIFY_LOG(ERR,
+ "%s: rte_flow_classifier parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (!attr) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL, "NULL attribute.");
+ return -EINVAL;
+ }
+
+ if (!pattern) {
+ rte_flow_error_set(error,
+ EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
+ NULL, "NULL pattern.");
+ return -EINVAL;
+ }
+
+ if (!actions) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+ NULL, "NULL action.");
+ return -EINVAL;
+ }
+
+ memset(&cls->ntuple_filter, 0, sizeof(cls->ntuple_filter));
/* Get the non-void item number of pattern */
while ((pattern + i)->type != RTE_FLOW_ITEM_TYPE_END) {
return -EINVAL;
}
- ret = parse_filter(attr, items, actions, &ntuple_filter, error);
+ ret = parse_filter(attr, items, actions, &cls->ntuple_filter, error);
free(items);
return ret;
}
/* Save input parameters */
snprintf(cls->name, RTE_FLOW_CLASSIFIER_MAX_NAME_SZ, "%s",
params->name);
- cls->socket_id = params->socket_id;
- cls->type = params->type;
- /* Initialize flow classifier internal data structure */
- cls->num_tables = 0;
+ cls->socket_id = params->socket_id;
return cls;
}
static void
-rte_flow_classify_table_free(struct rte_table *table)
+rte_flow_classify_table_free(struct rte_cls_table *table)
{
if (table->ops.f_free != NULL)
table->ops.f_free(table->h_table);
/* Free tables */
for (i = 0; i < cls->num_tables; i++) {
- struct rte_table *table = &cls->tables[i];
+ struct rte_cls_table *table = &cls->tables[i];
rte_flow_classify_table_free(table);
}
static int
rte_table_check_params(struct rte_flow_classifier *cls,
- struct rte_flow_classify_table_params *params,
- uint32_t *table_id)
+ struct rte_flow_classify_table_params *params)
{
if (cls == NULL) {
RTE_FLOW_CLASSIFY_LOG(ERR,
__func__);
return -EINVAL;
}
- if (table_id == NULL) {
- RTE_FLOW_CLASSIFY_LOG(ERR, "%s: table_id parameter is NULL\n",
- __func__);
- return -EINVAL;
- }
/* ops */
if (params->ops == NULL) {
int
rte_flow_classify_table_create(struct rte_flow_classifier *cls,
- struct rte_flow_classify_table_params *params,
- uint32_t *table_id)
+ struct rte_flow_classify_table_params *params)
{
- struct rte_table *table;
+ struct rte_cls_table *table;
void *h_table;
- uint32_t entry_size, id;
+ uint32_t entry_size;
int ret;
/* Check input arguments */
- ret = rte_table_check_params(cls, params, table_id);
+ ret = rte_table_check_params(cls, params);
if (ret != 0)
return ret;
- id = cls->num_tables;
- table = &cls->tables[id];
-
/* calculate table entry size */
entry_size = sizeof(struct rte_flow_classify_table_entry);
}
/* Commit current table to the classifier */
+ table = &cls->tables[cls->num_tables];
+ table->type = params->type;
cls->num_tables++;
- *table_id = id;
/* Save input parameters */
memcpy(&table->ops, params->ops, sizeof(struct rte_table_ops));
}
static struct rte_flow_classify_rule *
-allocate_acl_ipv4_5tuple_rule(void)
+allocate_acl_ipv4_5tuple_rule(struct rte_flow_classifier *cls)
{
struct rte_flow_classify_rule *rule;
int log_level;
rule->id = unique_id++;
rule->rules.type = RTE_FLOW_CLASSIFY_RULE_TYPE_IPV4_5TUPLE;
- memcpy(&rule->action, classify_get_flow_action(),
- sizeof(struct rte_flow_action));
-
/* key add values */
- rule->u.key.key_add.priority = ntuple_filter.priority;
+ rule->u.key.key_add.priority = cls->ntuple_filter.priority;
rule->u.key.key_add.field_value[PROTO_FIELD_IPV4].mask_range.u8 =
- ntuple_filter.proto_mask;
+ cls->ntuple_filter.proto_mask;
rule->u.key.key_add.field_value[PROTO_FIELD_IPV4].value.u8 =
- ntuple_filter.proto;
- rule->rules.u.ipv4_5tuple.proto = ntuple_filter.proto;
- rule->rules.u.ipv4_5tuple.proto_mask = ntuple_filter.proto_mask;
+ cls->ntuple_filter.proto;
+ rule->rules.u.ipv4_5tuple.proto = cls->ntuple_filter.proto;
+ rule->rules.u.ipv4_5tuple.proto_mask = cls->ntuple_filter.proto_mask;
rule->u.key.key_add.field_value[SRC_FIELD_IPV4].mask_range.u32 =
- ntuple_filter.src_ip_mask;
+ cls->ntuple_filter.src_ip_mask;
rule->u.key.key_add.field_value[SRC_FIELD_IPV4].value.u32 =
- ntuple_filter.src_ip;
- rule->rules.u.ipv4_5tuple.src_ip_mask = ntuple_filter.src_ip_mask;
- rule->rules.u.ipv4_5tuple.src_ip = ntuple_filter.src_ip;
+ cls->ntuple_filter.src_ip;
+ rule->rules.u.ipv4_5tuple.src_ip_mask = cls->ntuple_filter.src_ip_mask;
+ rule->rules.u.ipv4_5tuple.src_ip = cls->ntuple_filter.src_ip;
rule->u.key.key_add.field_value[DST_FIELD_IPV4].mask_range.u32 =
- ntuple_filter.dst_ip_mask;
+ cls->ntuple_filter.dst_ip_mask;
rule->u.key.key_add.field_value[DST_FIELD_IPV4].value.u32 =
- ntuple_filter.dst_ip;
- rule->rules.u.ipv4_5tuple.dst_ip_mask = ntuple_filter.dst_ip_mask;
- rule->rules.u.ipv4_5tuple.dst_ip = ntuple_filter.dst_ip;
+ cls->ntuple_filter.dst_ip;
+ rule->rules.u.ipv4_5tuple.dst_ip_mask = cls->ntuple_filter.dst_ip_mask;
+ rule->rules.u.ipv4_5tuple.dst_ip = cls->ntuple_filter.dst_ip;
rule->u.key.key_add.field_value[SRCP_FIELD_IPV4].mask_range.u16 =
- ntuple_filter.src_port_mask;
+ cls->ntuple_filter.src_port_mask;
rule->u.key.key_add.field_value[SRCP_FIELD_IPV4].value.u16 =
- ntuple_filter.src_port;
- rule->rules.u.ipv4_5tuple.src_port_mask = ntuple_filter.src_port_mask;
- rule->rules.u.ipv4_5tuple.src_port = ntuple_filter.src_port;
+ cls->ntuple_filter.src_port;
+ rule->rules.u.ipv4_5tuple.src_port_mask =
+ cls->ntuple_filter.src_port_mask;
+ rule->rules.u.ipv4_5tuple.src_port = cls->ntuple_filter.src_port;
rule->u.key.key_add.field_value[DSTP_FIELD_IPV4].mask_range.u16 =
- ntuple_filter.dst_port_mask;
+ cls->ntuple_filter.dst_port_mask;
rule->u.key.key_add.field_value[DSTP_FIELD_IPV4].value.u16 =
- ntuple_filter.dst_port;
- rule->rules.u.ipv4_5tuple.dst_port_mask = ntuple_filter.dst_port_mask;
- rule->rules.u.ipv4_5tuple.dst_port = ntuple_filter.dst_port;
+ cls->ntuple_filter.dst_port;
+ rule->rules.u.ipv4_5tuple.dst_port_mask =
+ cls->ntuple_filter.dst_port_mask;
+ rule->rules.u.ipv4_5tuple.dst_port = cls->ntuple_filter.dst_port;
log_level = rte_log_get_level(librte_flow_classify_logtype);
struct rte_flow_classify_rule *
rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls,
- uint32_t table_id,
- int *key_found,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
+ int *key_found,
struct rte_flow_error *error)
{
struct rte_flow_classify_rule *rule;
struct rte_flow_classify_table_entry *table_entry;
+ struct classify_action *action;
+ uint32_t i;
int ret;
if (!error)
return NULL;
- if (!cls) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL, "NULL classifier.");
- return NULL;
- }
-
- if (table_id >= cls->num_tables) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL, "invalid table_id.");
- return NULL;
- }
-
if (key_found == NULL) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
return NULL;
}
- if (!pattern) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM_NUM,
- NULL, "NULL pattern.");
- return NULL;
- }
-
- if (!actions) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION_NUM,
- NULL, "NULL action.");
- return NULL;
- }
-
- if (!attr) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ATTR,
- NULL, "NULL attribute.");
- return NULL;
- }
-
/* parse attr, pattern and actions */
- ret = flow_classify_parse_flow(attr, pattern, actions, error);
+ ret = rte_flow_classify_validate(cls, attr, pattern, actions, error);
if (ret < 0)
return NULL;
- switch (cls->type) {
- case RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL:
- rule = allocate_acl_ipv4_5tuple_rule();
+ switch (table_type) {
+ case RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE:
+ rule = allocate_acl_ipv4_5tuple_rule(cls);
if (!rule)
return NULL;
+ rule->tbl_type = table_type;
+ cls->table_mask |= table_type;
break;
default:
return NULL;
}
- rule->entry = malloc(sizeof(struct rte_flow_classify_table_entry));
- if (!rule->entry) {
- free(rule);
- return NULL;
- }
-
- table_entry = rule->entry;
+ action = classify_get_flow_action();
+ table_entry = &rule->entry;
table_entry->rule_id = rule->id;
+ table_entry->action.action_mask = action->action_mask;
- if (cls->tables[table_id].ops.f_add != NULL) {
- ret = cls->tables[table_id].ops.f_add(
- cls->tables[table_id].h_table,
- &rule->u.key.key_add,
- rule->entry,
- &rule->key_found,
- &rule->entry_ptr);
- if (ret) {
- free(rule->entry);
- free(rule);
- return NULL;
+ /* Copy actions */
+ if (action->action_mask & (1LLU << RTE_FLOW_ACTION_TYPE_COUNT)) {
+ memcpy(&table_entry->action.act.counter, &action->act.counter,
+ sizeof(table_entry->action.act.counter));
+ }
+ if (action->action_mask & (1LLU << RTE_FLOW_ACTION_TYPE_MARK)) {
+ memcpy(&table_entry->action.act.mark, &action->act.mark,
+ sizeof(table_entry->action.act.mark));
+ }
+
+ for (i = 0; i < cls->num_tables; i++) {
+ struct rte_cls_table *table = &cls->tables[i];
+
+ if (table->type == table_type) {
+ if (table->ops.f_add != NULL) {
+ ret = table->ops.f_add(
+ table->h_table,
+ &rule->u.key.key_add,
+ &rule->entry,
+ &rule->key_found,
+ &rule->entry_ptr);
+ if (ret) {
+ free(rule);
+ return NULL;
+ }
+
+ *key_found = rule->key_found;
+ }
+
+ return rule;
}
- *key_found = rule->key_found;
}
- return rule;
+ return NULL;
}
int
rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
- uint32_t table_id,
struct rte_flow_classify_rule *rule)
{
+ uint32_t i;
int ret = -EINVAL;
- if (!cls || !rule || table_id >= cls->num_tables)
+ if (!cls || !rule)
return ret;
+ enum rte_flow_classify_table_type tbl_type = rule->tbl_type;
+
+ for (i = 0; i < cls->num_tables; i++) {
+ struct rte_cls_table *table = &cls->tables[i];
- if (cls->tables[table_id].ops.f_delete != NULL)
- ret = cls->tables[table_id].ops.f_delete(
- cls->tables[table_id].h_table,
- &rule->u.key.key_del,
- &rule->key_found,
- &rule->entry);
+ if (table->type == tbl_type) {
+ if (table->ops.f_delete != NULL) {
+ ret = table->ops.f_delete(table->h_table,
+ &rule->u.key.key_del,
+ &rule->key_found,
+ &rule->entry);
+ return ret;
+ }
+ }
+ }
+ free(rule);
return ret;
}
static int
flow_classifier_lookup(struct rte_flow_classifier *cls,
- uint32_t table_id,
+ struct rte_cls_table *table,
struct rte_mbuf **pkts,
const uint16_t nb_pkts)
{
uint64_t lookup_hit_mask;
pkts_mask = RTE_LEN2MASK(nb_pkts, uint64_t);
- ret = cls->tables[table_id].ops.f_lookup(
- cls->tables[table_id].h_table,
+ ret = table->ops.f_lookup(table->h_table,
pkts, pkts_mask, &lookup_hit_mask,
(void **)cls->entries);
struct rte_flow_classify_stats *stats)
{
struct rte_flow_classify_ipv4_5tuple_stats *ntuple_stats;
+ struct rte_flow_classify_table_entry *entry = &rule->entry;
uint64_t count = 0;
- int i;
- int ret = -EINVAL;
+ uint32_t action_mask = entry->action.action_mask;
+ int i, ret = -EINVAL;
- switch (rule->action.type) {
- case RTE_FLOW_ACTION_TYPE_COUNT:
+ if (action_mask & (1LLU << RTE_FLOW_ACTION_TYPE_COUNT)) {
for (i = 0; i < cls->nb_pkts; i++) {
if (rule->id == cls->entries[i]->rule_id)
count++;
ntuple_stats->counter1 = count;
ntuple_stats->ipv4_5tuple = rule->rules.u.ipv4_5tuple;
}
- break;
- default:
- ret = -ENOTSUP;
- break;
}
-
return ret;
}
int
rte_flow_classifier_query(struct rte_flow_classifier *cls,
- uint32_t table_id,
struct rte_mbuf **pkts,
const uint16_t nb_pkts,
struct rte_flow_classify_rule *rule,
struct rte_flow_classify_stats *stats)
{
+ enum rte_flow_classify_table_type tbl_type;
+ uint32_t i;
int ret = -EINVAL;
- if (!cls || !rule || !stats || !pkts || nb_pkts == 0 ||
- table_id >= cls->num_tables)
+ if (!cls || !rule || !stats || !pkts || nb_pkts == 0)
return ret;
- ret = flow_classifier_lookup(cls, table_id, pkts, nb_pkts);
- if (!ret)
- ret = action_apply(cls, rule, stats);
+ tbl_type = rule->tbl_type;
+ for (i = 0; i < cls->num_tables; i++) {
+ struct rte_cls_table *table = &cls->tables[i];
+
+ if (table->type == tbl_type) {
+ ret = flow_classifier_lookup(cls, table,
+ pkts, nb_pkts);
+ if (!ret) {
+ ret = action_apply(cls, rule, stats);
+ return ret;
+ }
+ }
+ }
return ret;
}
rte_log(RTE_LOG_ ## level, librte_flow_classify_logtype, "%s(): " fmt, \
__func__, ## args)
+#ifndef RTE_FLOW_CLASSIFY_TABLE_MAX
+#define RTE_FLOW_CLASSIFY_TABLE_MAX 32
+#endif
+
/** Opaque data type for flow classifier */
struct rte_flow_classifier;
/** Flow classify table type */
enum rte_flow_classify_table_type {
- /** no type */
- RTE_FLOW_CLASSIFY_TABLE_TYPE_NONE,
- /** ACL type */
- RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL,
-};
+ /** No type */
+ RTE_FLOW_CLASSIFY_TABLE_TYPE_NONE = 1 << 0,
+ /** ACL IP4 5TUPLE */
+ RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE = 1 << 1,
+ /** ACL VLAN IP4 5TUPLE */
+ RTE_FLOW_CLASSIFY_TABLE_ACL_VLAN_IP4_5TUPLE = 1 << 2,
+ /** ACL QinQ IP4 5TUPLE */
+ RTE_FLOW_CLASSIFY_TABLE_ACL_QINQ_IP4_5TUPLE = 1 << 3,
-/**
- * Maximum number of tables allowed for any Flow Classifier instance.
- * The value of this parameter cannot be changed.
- */
-#define RTE_FLOW_CLASSIFY_TABLE_MAX 64
+};
/** Parameters for flow classifier creation */
struct rte_flow_classifier_params {
/** CPU socket ID where memory for the flow classifier and its */
/** elements (tables) should be allocated */
int socket_id;
-
- /** Table type */
- enum rte_flow_classify_table_type type;
};
/** Parameters for table creation */
/** Opaque param to be passed to the table create operation */
void *arg_create;
+
+ /** Classifier table type */
+ enum rte_flow_classify_table_type type;
};
/** IPv4 5-tuple data */
* Handle to flow classifier instance
* @param params
* Parameters for flow_classify table creation
- * @param table_id
- * Table ID. Valid only within the scope of table IDs of the current
- * classifier. Only returned after a successful invocation.
* @return
* 0 on success, error code otherwise
*/
int
rte_flow_classify_table_create(struct rte_flow_classifier *cls,
- struct rte_flow_classify_table_params *params,
- uint32_t *table_id);
+ struct rte_flow_classify_table_params *params);
+
+/**
+ * Flow classify validate
+ *
+ * @param cls
+ * Handle to flow classifier instance
+ * @param[in] attr
+ * Flow rule attributes
+ * @param[in] pattern
+ * Pattern specification (list terminated by the END pattern item).
+ * @param[in] actions
+ * Associated actions (list terminated by the END pattern item).
+ * @param[out] error
+ * Perform verbose error reporting if not NULL. Structure
+ * initialised in case of error only.
+ * @return
+ * 0 on success, error code otherwise
+ */
+int
+rte_flow_classify_validate(struct rte_flow_classifier *cls,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error);
/**
* Add a flow classify rule to the flow_classifer table.
*
* @param[in] cls
* Flow classifier handle
- * @param[in] table_id
- * id of table
- * @param[out] key_found
- * returns 1 if key present already, 0 otherwise.
* @param[in] attr
* Flow rule attributes
* @param[in] pattern
* Pattern specification (list terminated by the END pattern item).
* @param[in] actions
* Associated actions (list terminated by the END pattern item).
+ * @param[out] key_found
+ * returns 1 if rule present already, 0 otherwise.
* @param[out] error
* Perform verbose error reporting if not NULL. Structure
* initialised in case of error only.
*/
struct rte_flow_classify_rule *
rte_flow_classify_table_entry_add(struct rte_flow_classifier *cls,
- uint32_t table_id,
- int *key_found,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
+ int *key_found,
struct rte_flow_error *error);
/**
*
* @param[in] cls
* Flow classifier handle
- * @param[in] table_id
- * id of table
* @param[in] rule
* Flow classify rule
* @return
*/
int
rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
- uint32_t table_id,
struct rte_flow_classify_rule *rule);
/**
*
* @param[in] cls
* Flow classifier handle
- * @param[in] table_id
- * id of table
* @param[in] pkts
* Pointer to packets to process
* @param[in] nb_pkts
*/
int
rte_flow_classifier_query(struct rte_flow_classifier *cls,
- uint32_t table_id,
struct rte_mbuf **pkts,
const uint16_t nb_pkts,
struct rte_flow_classify_rule *rule,
parse_filter_t parse_filter;
};
-static struct rte_flow_action action;
+static struct classify_action action;
/* Pattern for IPv4 5-tuple UDP filter */
static enum rte_flow_item_type pattern_ntuple_1[] = {
{ pattern_ntuple_3, classify_parse_ntuple_filter },
};
-struct rte_flow_action *
+struct classify_action *
classify_get_flow_action(void)
{
return &action;
const struct rte_flow_item_udp *udp_mask;
const struct rte_flow_item_sctp *sctp_spec;
const struct rte_flow_item_sctp *sctp_mask;
+ const struct rte_flow_action_count *count;
+ const struct rte_flow_action_mark *mark_spec;
uint32_t index;
- if (!pattern) {
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
- NULL, "NULL pattern.");
- return -EINVAL;
- }
-
- if (!actions) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION_NUM,
- NULL, "NULL action.");
- return -EINVAL;
- }
- if (!attr) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ATTR,
- NULL, "NULL attribute.");
- return -EINVAL;
- }
-
/* parse pattern */
index = 0;
return -EINVAL;
}
- /* parse action */
- index = 0;
-
- /**
- * n-tuple only supports count,
- * check if the first not void action is COUNT.
- */
- memset(&action, 0, sizeof(action));
- NEXT_ITEM_OF_ACTION(act, actions, index);
- if (act->type != RTE_FLOW_ACTION_TYPE_COUNT) {
- memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- item, "Not supported action.");
- return -EINVAL;
- }
- action.type = RTE_FLOW_ACTION_TYPE_COUNT;
-
- /* check if the next not void item is END */
- index++;
- NEXT_ITEM_OF_ACTION(act, actions, index);
- if (act->type != RTE_FLOW_ACTION_TYPE_END) {
- memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Not supported action.");
- return -EINVAL;
- }
+ table_type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE;
/* parse attr */
/* must be input direction */
if (attr->priority > FLOW_RULE_MIN_PRIORITY)
filter->priority = FLOW_RULE_MAX_PRIORITY;
+ /* parse action */
+ index = 0;
+
+ /**
+ * n-tuple only supports count and Mark,
+ * check if the first not void action is COUNT or MARK.
+ */
+ memset(&action, 0, sizeof(action));
+ NEXT_ITEM_OF_ACTION(act, actions, index);
+ switch (act->type) {
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_COUNT;
+ count = (const struct rte_flow_action_count *)act->conf;
+ memcpy(&action.act.counter, count, sizeof(action.act.counter));
+ break;
+ case RTE_FLOW_ACTION_TYPE_MARK:
+ action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_MARK;
+ mark_spec = (const struct rte_flow_action_mark *)act->conf;
+ memcpy(&action.act.mark, mark_spec, sizeof(action.act.mark));
+ break;
+ default:
+ memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, act,
+ "Invalid action.");
+ return -EINVAL;
+ }
+
+ /* check if the next not void item is MARK or COUNT or END */
+ index++;
+ NEXT_ITEM_OF_ACTION(act, actions, index);
+ switch (act->type) {
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_COUNT;
+ count = (const struct rte_flow_action_count *)act->conf;
+ memcpy(&action.act.counter, count, sizeof(action.act.counter));
+ break;
+ case RTE_FLOW_ACTION_TYPE_MARK:
+ action.action_mask |= 1LLU << RTE_FLOW_ACTION_TYPE_MARK;
+ mark_spec = (const struct rte_flow_action_mark *)act->conf;
+ memcpy(&action.act.mark, mark_spec, sizeof(action.act.mark));
+ break;
+ case RTE_FLOW_ACTION_TYPE_END:
+ return 0;
+ default:
+ memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, act,
+ "Invalid action.");
+ return -EINVAL;
+ }
+
+ /* check if the next not void item is END */
+ index++;
+ NEXT_ITEM_OF_ACTION(act, actions, index);
+ if (act->type != RTE_FLOW_ACTION_TYPE_END) {
+ memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, act,
+ "Invalid action.");
+ return -EINVAL;
+ }
+
return 0;
}
extern "C" {
#endif
+extern enum rte_flow_classify_table_type table_type;
+
+struct classify_action {
+ /* Flow action mask */
+ uint64_t action_mask;
+
+ struct action {
+ /** Integer value to return with packets */
+ struct rte_flow_action_mark mark;
+ /** Flow rule counter */
+ struct rte_flow_query_count counter;
+ } act;
+};
+
typedef int (*parse_filter_t)(const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
classify_find_parse_filter_func(struct rte_flow_item *pattern);
/* get action data */
-struct rte_flow_action *
+struct classify_action *
classify_get_flow_action(void);
#ifdef __cplusplus
rte_flow_classify_table_create;
rte_flow_classify_table_entry_add;
rte_flow_classify_table_entry_delete;
+ rte_flow_classify_validate;
local: *;
};
#define FLOW_CLASSIFY_MAX_RULE_NUM 100
-struct flow_classifier *cls;
-
-struct flow_classifier {
- struct rte_flow_classifier *cls;
- uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX];
- uint32_t n_tables;
-};
+struct flow_classifier_acl *cls;
struct flow_classifier_acl {
- struct flow_classifier cls;
+ struct rte_flow_classifier *cls;
} __rte_cache_aligned;
/*
struct rte_flow_classify_rule *rule;
int ret;
- rule = rte_flow_classify_table_entry_add(NULL, 1, NULL, NULL, NULL,
+ ret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL);
+ if (!ret) {
+ printf("Line %i: rte_flow_classify_validate",
+ __LINE__);
+ printf(" with NULL param should have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL,
NULL, NULL);
if (rule) {
printf("Line %i: flow_classifier_table_entry_add", __LINE__);
return -1;
}
- ret = rte_flow_classify_table_entry_delete(NULL, 1, NULL);
+ ret = rte_flow_classify_table_entry_delete(NULL, NULL);
if (!ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
return -1;
}
- ret = rte_flow_classifier_query(NULL, 1, NULL, 0, NULL, NULL);
+ ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL);
if (!ret) {
printf("Line %i: flow_classifier_query", __LINE__);
printf(" with NULL param should have failed!\n");
return -1;
}
- rule = rte_flow_classify_table_entry_add(NULL, 1, NULL, NULL, NULL,
+ rule = rte_flow_classify_table_entry_add(NULL, NULL, NULL, NULL,
NULL, &error);
if (rule) {
printf("Line %i: flow_classify_table_entry_add ", __LINE__);
return -1;
}
- ret = rte_flow_classify_table_entry_delete(NULL, 1, NULL);
+ ret = rte_flow_classify_table_entry_delete(NULL, NULL);
if (!ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
return -1;
}
- ret = rte_flow_classifier_query(NULL, 1, NULL, 0, NULL, NULL);
+ ret = rte_flow_classifier_query(NULL, NULL, 0, NULL, NULL);
if (!ret) {
printf("Line %i: flow_classifier_query", __LINE__);
printf(" with NULL param should have failed!\n");
int key_found;
/*
- * set up parameters for rte_flow_classify_table_entry_add and
+ * set up parameters for rte_flow_classify_validate,
+ * rte_flow_classify_table_entry_add and
* rte_flow_classify_table_entry_delete
*/
actions[0] = count_action;
actions[1] = end_action;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (ret) {
+ printf("Line %i: rte_flow_classify_validate",
+ __LINE__);
+ printf(" should not have failed!\n");
+ return -1;
+ }
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
+
if (!rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should not have failed!\n");
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
int key_found;
/*
- * set up parameters for rte_flow_classify_table_entry_add and
+ * set up parameters for rte_flow_classify_validate,
+ * rte_flow_classify_table_entry_add and
* rte_flow_classify_table_entry_delete
*/
pattern[0] = eth_item;
pattern[1] = ipv4_udp_item_bad;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (!ret) {
+ printf("Line %i: rte_flow_classify_validate", __LINE__);
+ printf(" should have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should have failed!\n");
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (!ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
pattern[1] = ipv4_udp_item_1;
pattern[2] = udp_item_bad;
pattern[3] = end_item_bad;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (!ret) {
+ printf("Line %i: rte_flow_classify_validate", __LINE__);
+ printf(" should have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should have failed!\n");
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (!ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
int key_found;
/*
- * set up parameters for rte_flow_classify_table_entry_add and
+ * set up parameters for rte_flow_classify_validate,
+ * rte_flow_classify_table_entry_add and
* rte_flow_classify_table_entry_delete
*/
actions[0] = count_action_bad;
actions[1] = end_action;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (!ret) {
+ printf("Line %i: rte_flow_classify_validate", __LINE__);
+ printf(" should have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should have failed!\n");
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (!ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
actions[0] = count_action;
actions[1] = end_action_bad;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (!ret) {
+ printf("Line %i: rte_flow_classify_validate", __LINE__);
+ printf(" should have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should have failed!\n");
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (!ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
/*
- * set up parameters for rte_flow_classify_table_entry_add and
+ * set up parameters for rte_flow_classify_validate,
+ * rte_flow_classify_table_entry_add and
* rte_flow_classify_table_entry_delete
*/
actions[0] = count_action;
actions[1] = end_action;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (ret) {
+ printf("Line %i: rte_flow_classify_validate", __LINE__);
+ printf(" should not have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (!rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should not have failed!\n");
return -1;
}
- ret = rte_flow_classifier_query(cls->cls, 0, bufs, MAX_PKT_BURST,
+ ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
rule, &udp_classify_stats);
if (ret) {
printf("Line %i: flow_classifier_query", __LINE__);
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
/*
- * set up parameters for rte_flow_classify_table_entry_add and
+ * set up parameters for rte_flow_classify_validate,
+ * rte_flow_classify_table_entry_add and
* rte_flow_classify_table_entry_delete
*/
actions[0] = count_action;
actions[1] = end_action;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (ret) {
+ printf("Line %i: flow_classifier_query", __LINE__);
+ printf(" should not have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (!rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should not have failed!\n");
return -1;
}
- ret = rte_flow_classifier_query(cls->cls, 0, bufs, MAX_PKT_BURST,
+ ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
rule, &tcp_classify_stats);
if (ret) {
printf("Line %i: flow_classifier_query", __LINE__);
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
/*
- * set up parameters rte_flow_classify_table_entry_add and
+ * set up parameters rte_flow_classify_validate,
+ * rte_flow_classify_table_entry_add and
* rte_flow_classify_table_entry_delete
*/
actions[0] = count_action;
actions[1] = end_action;
- rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
- &attr, pattern, actions, &error);
+ ret = rte_flow_classify_validate(cls->cls, &attr, pattern,
+ actions, &error);
+ if (ret) {
+ printf("Line %i: flow_classifier_query", __LINE__);
+ printf(" should not have failed!\n");
+ return -1;
+ }
+
+ rule = rte_flow_classify_table_entry_add(cls->cls, &attr, pattern,
+ actions, &key_found, &error);
if (!rule) {
printf("Line %i: flow_classify_table_entry_add", __LINE__);
printf(" should not have failed!\n");
return -1;
}
- ret = rte_flow_classifier_query(cls->cls, 0, bufs, MAX_PKT_BURST,
+ ret = rte_flow_classifier_query(cls->cls, bufs, MAX_PKT_BURST,
rule, &sctp_classify_stats);
if (ret) {
printf("Line %i: flow_classifier_query", __LINE__);
return -1;
}
- ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
+ ret = rte_flow_classify_table_entry_delete(cls->cls, rule);
if (ret) {
printf("Line %i: rte_flow_classify_table_entry_delete",
__LINE__);
cls_params.name = "flow_classifier";
cls_params.socket_id = socket_id;
- cls_params.type = RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL;
cls->cls = rte_flow_classifier_create(&cls_params);
/* initialise ACL table params */
memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
/* initialise table create params */
- cls_table_params.ops = &rte_table_acl_ops,
- cls_table_params.arg_create = &table_acl_params,
+ cls_table_params.ops = &rte_table_acl_ops;
+ cls_table_params.arg_create = &table_acl_params;
+ cls_table_params.type = RTE_FLOW_CLASSIFY_TABLE_ACL_IP4_5TUPLE;
- ret = rte_flow_classify_table_create(cls->cls, &cls_table_params,
- &cls->table_id[0]);
+ ret = rte_flow_classify_table_create(cls->cls, &cls_table_params);
if (ret) {
printf("Line %i: f_create has failed!\n", __LINE__);
rte_flow_classifier_free(cls->cls);
/* test actions:
* "actions count / end"
*/
-static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, 0};
+struct rte_flow_query_count count = {
+ .reset = 1,
+ .hits_set = 1,
+ .bytes_set = 1,
+ .hits = 0,
+ .bytes = 0,
+};
+static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT,
+ &count};
static struct rte_flow_action count_action_bad = { -1, 0};
static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};