From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 257E323D for ; Tue, 19 Dec 2017 15:16:24 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Dec 2017 06:16:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,427,1508828400"; d="scan'208";a="3617497" Received: from silpixa00381635.ir.intel.com (HELO silpixa00381635.ger.corp.intel.com) ([10.237.222.149]) by fmsmga007.fm.intel.com with ESMTP; 19 Dec 2017 06:16:23 -0800 From: Jasvinder Singh To: dev@dpdk.org Cc: bernard.iremonger@intel.com, marko.kovacevic@intel.com Date: Tue, 19 Dec 2017 14:29:17 +0000 Message-Id: <20171219142920.140451-1-jasvinder.singh@intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20171215103924.5185-1-jasvinder.singh@intel.com> References: <20171215103924.5185-1-jasvinder.singh@intel.com> Subject: [dpdk-dev] [PATCH v4 1/4] lib/librte_flow_classify: remove table id parameter from apis X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Dec 2017 14:16:25 -0000 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 Acked-by: Bernard Iremonger --- v4: - fix typos in the description 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..689ad81 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_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]; @@ -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