[dpdk-dev] [PATCH v3 1/4] lib/librte_flow_classify: remove table id parameter from apis
Iremonger, Bernard
bernard.iremonger at intel.com
Tue Dec 19 13:03:47 CET 2017
Hi Jasvinder,
> -----Original Message-----
> From: Singh, Jasvinder
> Sent: Friday, December 15, 2017 10:39 AM
> To: dev at dpdk.org
> Cc: Iremonger, Bernard <bernard.iremonger at intel.com>
> Subject: [PATCH v3 1/4] lib/librte_flow_classify: remove table id parameter from
> apis
>
> This patch removes table id parameter from all the flow classify apis to reduce
> the complexity alongwith some code cleanup.
>
> The validate api is exposed as public api to allow user to validate the flow before
> adding it to the classifier.
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh at intel.com>
> ---
> v2:
> - break the patche into multiple
> - fix the error checks
>
> lib/librte_flow_classify/rte_flow_classify.c | 313 +++++++++++----------
> lib/librte_flow_classify/rte_flow_classify.h | 74 +++--
> lib/librte_flow_classify/rte_flow_classify_parse.c | 118 ++++----
> lib/librte_flow_classify/rte_flow_classify_parse.h | 16 +-
> .../rte_flow_classify_version.map | 1 +
> 5 files changed, 296 insertions(+), 226 deletions(-)
>
> diff --git a/lib/librte_flow_classify/rte_flow_classify.c
> b/lib/librte_flow_classify/rte_flow_classify.c
> index e6f4486..c2200df 100644
> --- a/lib/librte_flow_classify/rte_flow_classify.c
> +++ b/lib/librte_flow_classify/rte_flow_classify.c
> @@ -39,16 +39,20 @@
>
> 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;
> @@ -64,11 +68,16 @@ struct rte_flow_classifier {
> /* 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_fliter */
Typo, fliter should be filter
> + struct rte_eth_ntuple_filter ntuple_filter;
> +
> + /* clasifier tables */
Typo, classifier should be classifier.
> + 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];
> @@ -97,18 +106,19 @@ struct classify_rules {
>
> 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[], @@ -120,7 +130,38
> @@ flow_classify_parse_flow(
> 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) { @@ -150,7
> +191,7 @@ flow_classify_parse_flow(
> 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;
> }
> @@ -275,17 +316,14 @@ rte_flow_classifier_create(struct
> rte_flow_classifier_params *params)
> /* 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);
> @@ -306,7 +344,7 @@ rte_flow_classifier_free(struct rte_flow_classifier *cls)
>
> /* 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);
> }
> @@ -319,8 +357,7 @@ rte_flow_classifier_free(struct rte_flow_classifier *cls)
>
> 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,
> @@ -333,11 +370,6 @@ rte_table_check_params(struct rte_flow_classifier
> *cls,
> __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) {
> @@ -371,22 +403,18 @@ rte_table_check_params(struct rte_flow_classifier
> *cls,
>
> 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);
>
> @@ -400,8 +428,9 @@ rte_flow_classify_table_create(struct
> rte_flow_classifier *cls,
> }
>
> /* 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)); @@ -
> 414,7 +443,7 @@ rte_flow_classify_table_create(struct rte_flow_classifier *cls,
> }
>
> 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;
> @@ -427,45 +456,44 @@ allocate_acl_ipv4_5tuple_rule(void)
> 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);
>
> @@ -485,34 +513,21 @@ allocate_acl_ipv4_5tuple_rule(void)
>
> 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,
> @@ -520,91 +535,95 @@ rte_flow_classify_table_entry_add(struct
> rte_flow_classifier *cls,
> 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)
> {
> @@ -613,8 +632,7 @@ flow_classifier_lookup(struct rte_flow_classifier *cls,
> 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);
>
> @@ -632,12 +650,12 @@ action_apply(struct rte_flow_classifier *cls,
> 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++;
> @@ -650,32 +668,37 @@ action_apply(struct rte_flow_classifier *cls,
> 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;
> }
>
> diff --git a/lib/librte_flow_classify/rte_flow_classify.h
> b/lib/librte_flow_classify/rte_flow_classify.h
> index 1211873..b9b669f 100644
> --- a/lib/librte_flow_classify/rte_flow_classify.h
> +++ b/lib/librte_flow_classify/rte_flow_classify.h
> @@ -86,6 +86,10 @@ extern int librte_flow_classify_logtype;
> 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;
>
> @@ -102,17 +106,16 @@ enum rte_flow_classify_rule_type {
>
> /** 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
> { @@ -122,9 +125,6 @@ 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 */
> @@ -134,6 +134,9 @@ struct rte_flow_classify_table_params {
>
> /** 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 */
> @@ -197,32 +200,50 @@ rte_flow_classifier_free(struct rte_flow_classifier
> *cls);
> * 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.
> @@ -231,11 +252,10 @@ rte_flow_classify_table_create(struct
> rte_flow_classifier *cls,
> */
> 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);
>
> /**
> @@ -243,8 +263,6 @@ rte_flow_classify_table_entry_add(struct
> rte_flow_classifier *cls,
> *
> * @param[in] cls
> * Flow classifier handle
> - * @param[in] table_id
> - * id of table
> * @param[in] rule
> * Flow classify rule
> * @return
> @@ -252,7 +270,6 @@ rte_flow_classify_table_entry_add(struct
> rte_flow_classifier *cls,
> */
> int
> rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
> - uint32_t table_id,
> struct rte_flow_classify_rule *rule);
>
> /**
> @@ -260,8 +277,6 @@ rte_flow_classify_table_entry_delete(struct
> rte_flow_classifier *cls,
> *
> * @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
> @@ -276,7 +291,6 @@ rte_flow_classify_table_entry_delete(struct
> rte_flow_classifier *cls,
> */
> 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,
> diff --git a/lib/librte_flow_classify/rte_flow_classify_parse.c
> b/lib/librte_flow_classify/rte_flow_classify_parse.c
> index dbfa111..9fb3e51 100644
> --- a/lib/librte_flow_classify/rte_flow_classify_parse.c
> +++ b/lib/librte_flow_classify/rte_flow_classify_parse.c
> @@ -40,7 +40,7 @@ struct classify_valid_pattern {
> 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[] = { @@ -80,7 +80,7 @@ static struct classify_valid_pattern
> classify_supported_patterns[] = {
> { pattern_ntuple_3, classify_parse_ntuple_filter }, };
>
> -struct rte_flow_action *
> +struct classify_action *
> classify_get_flow_action(void)
> {
> return &action;
> @@ -244,28 +244,10 @@ classify_parse_ntuple_filter(const struct
> rte_flow_attr *attr,
> 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;
>
> @@ -483,34 +465,7 @@ classify_parse_ntuple_filter(const struct rte_flow_attr
> *attr,
> 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 */
> @@ -542,5 +497,68 @@ classify_parse_ntuple_filter(const struct rte_flow_attr
> *attr,
> 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;
> }
> diff --git a/lib/librte_flow_classify/rte_flow_classify_parse.h
> b/lib/librte_flow_classify/rte_flow_classify_parse.h
> index 1d4708a..9c1de72 100644
> --- a/lib/librte_flow_classify/rte_flow_classify_parse.h
> +++ b/lib/librte_flow_classify/rte_flow_classify_parse.h
> @@ -43,6 +43,20 @@
> 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[], @@ -64,7
> +78,7 @@ parse_filter_t 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
> diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map
> b/lib/librte_flow_classify/rte_flow_classify_version.map
> index f7695cb..49bc25c 100644
> --- a/lib/librte_flow_classify/rte_flow_classify_version.map
> +++ b/lib/librte_flow_classify/rte_flow_classify_version.map
> @@ -7,6 +7,7 @@ EXPERIMENTAL {
> rte_flow_classify_table_create;
> rte_flow_classify_table_entry_add;
> rte_flow_classify_table_entry_delete;
> + rte_flow_classify_validate;
>
> local: *;
> };
> --
> 2.9.3
Can you fix the typos in the the v4, other wise ack.
Acked-by: Bernard Iremonger<Bernard.iremonger at intel.com>
More information about the dev
mailing list