flow_classify: remove table id parameter from API
authorJasvinder Singh <jasvinder.singh@intel.com>
Tue, 19 Dec 2017 14:29:17 +0000 (14:29 +0000)
committerThomas Monjalon <thomas@monjalon.net>
Thu, 11 Jan 2018 18:15:26 +0000 (19:15 +0100)
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@intel.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
doc/guides/prog_guide/flow_classify_lib.rst
doc/guides/sample_app_ug/flow_classify.rst
examples/flow_classify/flow_classify.c
lib/librte_flow_classify/rte_flow_classify.c
lib/librte_flow_classify/rte_flow_classify.h
lib/librte_flow_classify/rte_flow_classify_parse.c
lib/librte_flow_classify/rte_flow_classify_parse.h
lib/librte_flow_classify/rte_flow_classify_version.map
test/test/test_flow_classify.c
test/test/test_flow_classify.h

index 820dc72..3edb154 100644 (file)
@@ -101,30 +101,50 @@ The library has the following API's
      *   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.
@@ -133,10 +153,10 @@ The library has the following API's
      */
     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);
 
     /**
@@ -144,8 +164,6 @@ The library has the following API's
      *
      * @param[in] cls
      *   Flow classifier handle
-     * @param[in] table_id
-     *   id of table
      * @param[in] rule
      *   Flow classify rule
      * @return
@@ -153,7 +171,6 @@ The library has the following API's
      */
     int
     rte_flow_classify_table_entry_delete(struct rte_flow_classifier *cls,
-            uint32_t table_id,
             struct rte_flow_classify_rule *rule);
 
     /**
@@ -161,8 +178,6 @@ The library has the following API's
      *
      * @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
@@ -177,7 +192,6 @@ The library has the following API's
      */
     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,
@@ -200,16 +214,13 @@ application before calling the API.
         /** 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;
@@ -225,11 +236,16 @@ The ``Classifier`` has the following internal structures:
         /* 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];
@@ -252,9 +268,8 @@ application before calling the API.
         /** 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
@@ -314,14 +329,14 @@ and SCTP.
         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[],
@@ -333,7 +348,7 @@ Adding Flow Rules
 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
@@ -343,7 +358,7 @@ parses the Flow rule.
 
     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 {
@@ -355,24 +370,24 @@ parses the Flow rule.
 
     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
 ~~~~~~~~~~~~~~~
@@ -380,7 +395,7 @@ 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.
index bc12b87..427fded 100644 (file)
@@ -228,7 +228,6 @@ table`` to the flow classifier.
 
     struct flow_classifier {
         struct rte_flow_classifier *cls;
-        uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX];
     };
 
     struct flow_classifier_acl {
@@ -243,7 +242,6 @@ table`` to the flow classifier.
 
     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) {
@@ -260,10 +258,9 @@ table`` to the flow classifier.
     /* 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);
@@ -495,7 +492,6 @@ following:
                     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)
index 45b3c1b..61cda86 100644 (file)
@@ -65,7 +65,6 @@ static const struct rte_eth_conf port_conf_default = {
 
 struct flow_classifier {
        struct rte_flow_classifier *cls;
-       uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX];
 };
 
 struct flow_classifier_acl {
@@ -166,7 +165,15 @@ static struct rte_flow_item  end_item = { RTE_FLOW_ITEM_TYPE_END,
 /* 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];
 
@@ -245,7 +252,7 @@ lcore_main(struct flow_classifier *cls_app)
        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
@@ -263,11 +270,10 @@ lcore_main(struct flow_classifier *cls_app)
                               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 (;;) {
                /*
@@ -288,7 +294,6 @@ lcore_main(struct flow_classifier *cls_app)
                                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)
@@ -605,9 +610,18 @@ add_classify_rule(struct rte_eth_ntuple_filter *ntuple_filter,
        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);
@@ -780,7 +794,6 @@ main(int argc, char *argv[])
 
        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) {
@@ -795,11 +808,11 @@ main(int argc, char *argv[])
        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);
index 65d0a75..0407ac0 100644 (file)
 
 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;
@@ -35,11 +39,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];
@@ -68,18 +77,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[],
@@ -91,7 +101,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) {
@@ -121,7 +162,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;
 }
@@ -246,17 +287,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);
@@ -277,7 +315,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);
        }
@@ -290,8 +328,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,
@@ -304,11 +341,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) {
@@ -342,22 +374,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);
 
@@ -371,8 +399,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));
@@ -385,7 +414,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;
@@ -398,45 +427,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);
 
@@ -456,34 +484,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,
@@ -491,91 +506,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)
 {
@@ -584,8 +603,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);
 
@@ -603,12 +621,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++;
@@ -621,32 +639,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;
 }
 
index e5f3e61..b1016d3 100644 (file)
@@ -57,6 +57,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;
 
@@ -73,17 +77,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 {
@@ -93,9 +96,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 */
@@ -105,6 +105,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 */
@@ -168,32 +171,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.
@@ -202,11 +223,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);
 
 /**
@@ -214,8 +234,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
@@ -223,7 +241,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);
 
 /**
@@ -231,8 +248,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
@@ -247,7 +262,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,
index 9625fb8..10eaf04 100644 (file)
@@ -11,7 +11,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[] = {
@@ -51,7 +51,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;
@@ -215,28 +215,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;
 
@@ -454,34 +436,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 */
@@ -513,5 +468,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;
 }
index 6f2c2b0..365a07b 100644 (file)
 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[],
@@ -35,7 +49,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
index f7695cb..49bc25c 100644 (file)
@@ -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: *;
 };
index 11dfee2..e707627 100644 (file)
 
 
 #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;
 
 /*
@@ -44,7 +38,15 @@ test_invalid_parameters(void)
        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__);
@@ -52,7 +54,7 @@ test_invalid_parameters(void)
                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__);
@@ -60,14 +62,14 @@ test_invalid_parameters(void)
                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__);
@@ -75,7 +77,7 @@ test_invalid_parameters(void)
                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__);
@@ -83,7 +85,7 @@ test_invalid_parameters(void)
                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");
@@ -100,7 +102,8 @@ test_valid_parameters(void)
        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
         */
 
@@ -113,15 +116,24 @@ test_valid_parameters(void)
        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__);
@@ -139,7 +151,8 @@ test_invalid_patterns(void)
        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
         */
 
@@ -154,15 +167,24 @@ test_invalid_patterns(void)
 
        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__);
@@ -173,15 +195,24 @@ test_invalid_patterns(void)
        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__);
@@ -199,7 +230,8 @@ test_invalid_actions(void)
        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
         */
 
@@ -212,15 +244,23 @@ test_invalid_actions(void)
        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__);
@@ -231,15 +271,23 @@ test_invalid_actions(void)
        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__);
@@ -420,7 +468,8 @@ test_query_udp(void)
                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
         */
 
@@ -433,15 +482,23 @@ test_query_udp(void)
        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__);
@@ -449,7 +506,7 @@ test_query_udp(void)
                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__);
@@ -478,7 +535,8 @@ test_query_tcp(void)
                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
         */
 
@@ -491,15 +549,23 @@ test_query_tcp(void)
        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__);
@@ -507,7 +573,7 @@ test_query_tcp(void)
                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__);
@@ -536,7 +602,8 @@ test_query_sctp(void)
                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
         */
 
@@ -549,15 +616,23 @@ test_query_sctp(void)
        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__);
@@ -565,7 +640,7 @@ test_query_sctp(void)
                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__);
@@ -593,7 +668,6 @@ test_flow_classify(void)
 
        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 */
@@ -603,11 +677,11 @@ test_flow_classify(void)
        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);
index ec10527..ce1f08a 100644 (file)
@@ -168,7 +168,15 @@ static struct rte_flow_item  sctp_item_1 = { RTE_FLOW_ITEM_TYPE_SCTP,
 /* 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};