get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/28411/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 28411,
    "url": "https://patches.dpdk.org/api/patches/28411/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1504693668-2062-6-git-send-email-bernard.iremonger@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1504693668-2062-6-git-send-email-bernard.iremonger@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1504693668-2062-6-git-send-email-bernard.iremonger@intel.com",
    "date": "2017-09-06T10:27:48",
    "name": "[dpdk-dev,v4,5/5] test: flow classify library unit tests",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7bd8af1588a69ff29a51a947e644f6e8a2bd4a4e",
    "submitter": {
        "id": 91,
        "url": "https://patches.dpdk.org/api/people/91/?format=api",
        "name": "Iremonger, Bernard",
        "email": "bernard.iremonger@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1504693668-2062-6-git-send-email-bernard.iremonger@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/28411/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/28411/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id EA97A2C02;\n\tWed,  6 Sep 2017 12:28:15 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id CB8E237A6\n\tfor <dev@dpdk.org>; Wed,  6 Sep 2017 12:28:13 +0200 (CEST)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t06 Sep 2017 03:28:13 -0700",
            "from sivswdev01.ir.intel.com (HELO localhost.localdomain)\n\t([10.237.217.45])\n\tby orsmga003.jf.intel.com with ESMTP; 06 Sep 2017 03:28:11 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos; i=\"5.41,483,1498546800\"; d=\"scan'208\";\n\ta=\"1011480251\"",
        "From": "Bernard Iremonger <bernard.iremonger@intel.com>",
        "To": "dev@dpdk.org, ferruh.yigit@intel.com, konstantin.ananyev@intel.com,\n\tcristian.dumitrescu@intel.com, adrien.mazarguil@6wind.com",
        "Cc": "Bernard Iremonger <bernard.iremonger@intel.com>",
        "Date": "Wed,  6 Sep 2017 11:27:48 +0100",
        "Message-Id": "<1504693668-2062-6-git-send-email-bernard.iremonger@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": "<1504191287-11349-1-git-send-email-bernard.iremonger@intel.com>",
        "References": "<1504191287-11349-1-git-send-email-bernard.iremonger@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v4 5/5] test: flow classify library unit tests",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add flow_classify_autotest program.\n\nSet up IPv4 ACL field definitions.\nCreate table_acl for use by librte_flow_classify API's.\nCreate an mbuf pool for use by rte_flow_classify_query.\n\nFor each of the librte_flow_classify API's:\nadd bad parameter tests\nadd bad pattern tests\nadd bad action tests\nadd good parameter tests\n\nInitialise ipv4 udp traffic for use by the test for\nrte_flow_classif_query.\n\nSigned-off-by: Bernard Iremonger <bernard.iremonger@intel.com>\n---\n test/test/Makefile             |   1 +\n test/test/test_flow_classify.c | 493 +++++++++++++++++++++++++++++++++++++++++\n test/test/test_flow_classify.h | 186 ++++++++++++++++\n 3 files changed, 680 insertions(+)\n create mode 100644 test/test/test_flow_classify.c\n create mode 100644 test/test/test_flow_classify.h",
    "diff": "diff --git a/test/test/Makefile b/test/test/Makefile\nindex 42d9a49..073e1ed 100644\n--- a/test/test/Makefile\n+++ b/test/test/Makefile\n@@ -106,6 +106,7 @@ SRCS-y += test_table_tables.c\n SRCS-y += test_table_ports.c\n SRCS-y += test_table_combined.c\n SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_table_acl.c\n+SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_flow_classify.c\n endif\n \n SRCS-y += test_rwlock.c\ndiff --git a/test/test/test_flow_classify.c b/test/test/test_flow_classify.c\nnew file mode 100644\nindex 0000000..0badf49\n--- /dev/null\n+++ b/test/test/test_flow_classify.c\n@@ -0,0 +1,493 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <string.h>\n+#include <errno.h>\n+\n+#include \"test.h\"\n+\n+#include <rte_string_fns.h>\n+#include <rte_mbuf.h>\n+#include <rte_byteorder.h>\n+#include <rte_ip.h>\n+#include <rte_acl.h>\n+#include <rte_common.h>\n+#include <rte_table_acl.h>\n+#include <rte_flow.h>\n+#include <rte_flow_classify.h>\n+\n+#include \"packet_burst_generator.h\"\n+#include \"test_flow_classify.h\"\n+\n+\n+#define FLOW_CLASSIFY_MAX_RULE_NUM 100\n+static void *table_acl;\n+static uint32_t entry_size;\n+\n+/*\n+ * test functions by passing invalid or\n+ * non-workable parameters.\n+ */\n+static int\n+test_invalid_parameters(void)\n+{\n+\tstruct rte_flow_classify *classify;\n+\tint ret;\n+\n+\tret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, NULL);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tclassify = rte_flow_classify_create(NULL, 0, NULL, NULL, NULL, NULL);\n+\tif (classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(NULL, NULL, NULL);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\" with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_query(NULL, NULL, NULL, 0, NULL, NULL);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_query\", __LINE__);\n+\t\tprintf(\" with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_validate(NULL, NULL, NULL, NULL, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tclassify = rte_flow_classify_create(NULL, 0, NULL, NULL, NULL, &error);\n+\tif (classify) {\n+\t\tprintf(\"Line %i: flow_classify_create \", __LINE__);\n+\t\tprintf(\"with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(NULL, NULL, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\"with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_query(NULL, NULL, NULL, 0, NULL, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_query\", __LINE__);\n+\t\tprintf(\" with NULL param should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+test_valid_parameters(void)\n+{\n+\tstruct rte_flow_classify *flow_classify;\n+\tint ret;\n+\n+\t/* set up parameters for rte_flow_classify_validate and\n+\t * rte_flow_classify_create and rte_flow_classify_destroy\n+\t */\n+\n+\tattr.ingress = 1;\n+\tattr.priority = 1;\n+\tpattern_udp_1[0] = eth_item;\n+\tpattern_udp_1[1] = ipv4_udp_item_1;\n+\tpattern_udp_1[2] = udp_item_1;\n+\tpattern_udp_1[3] = end_item;\n+\tactions[0] = count_action;\n+\tactions[1] = end_action;\n+\n+\tret = rte_flow_classify_validate(table_acl, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tflow_classify = rte_flow_classify_create(table_acl, entry_size, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (!flow_classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(table_acl, flow_classify, &error);\n+\tif (ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+test_invalid_patterns(void)\n+{\n+\tstruct rte_flow_classify *flow_classify;\n+\tint ret;\n+\n+\t/* set up parameters for rte_flow_classify_validate and\n+\t * rte_flow_classify_create and rte_flow_classify_destroy\n+\t */\n+\n+\tattr.ingress = 1;\n+\tattr.priority = 1;\n+\tpattern_udp_1[0] = eth_item_bad;\n+\tpattern_udp_1[1] = ipv4_udp_item_1;\n+\tpattern_udp_1[2] = udp_item_1;\n+\tpattern_udp_1[3] = end_item;\n+\tactions[0] = count_action;\n+\tactions[1] = end_action;\n+\n+\tret = rte_flow_classify_validate(table_acl, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tpattern_udp_1[0] = eth_item;\n+\tpattern_udp_1[1] = ipv4_udp_item_bad;\n+\tflow_classify = rte_flow_classify_create(table_acl, entry_size, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (flow_classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(table_acl, flow_classify, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tpattern_udp_1[1] = ipv4_udp_item_1;\n+\tpattern_udp_1[2] = udp_item_bad;\n+\tret = rte_flow_classify_validate(table_acl, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tpattern_udp_1[2] = udp_item_1;\n+\tpattern_udp_1[3] = end_item_bad;\n+\tflow_classify = rte_flow_classify_create(table_acl, entry_size, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (flow_classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(table_acl, flow_classify, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+test_invalid_actions(void)\n+{\n+\tstruct rte_flow_classify *flow_classify;\n+\tint ret;\n+\n+\t/* set up parameters for rte_flow_classify_validate and\n+\t * rte_flow_classify_create and rte_flow_classify_destroy\n+\t */\n+\n+\tattr.ingress = 1;\n+\tattr.priority = 1;\n+\tpattern_udp_1[0] = eth_item;\n+\tpattern_udp_1[1] = ipv4_udp_item_1;\n+\tpattern_udp_1[2] = udp_item_1;\n+\tpattern_udp_1[3] = end_item;\n+\tactions[0] = count_action_bad;\n+\tactions[1] = end_action;\n+\n+\tret = rte_flow_classify_validate(table_acl, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tflow_classify = rte_flow_classify_create(table_acl, entry_size, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (flow_classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(table_acl, flow_classify, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tactions[0] = count_action;\n+\tactions[1] = end_action_bad;\n+\tret = rte_flow_classify_validate(table_acl, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tflow_classify = rte_flow_classify_create(table_acl, entry_size, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (flow_classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(table_acl, flow_classify, &error);\n+\tif (!ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\"should have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+init_udp_ipv4_traffic(struct rte_mempool *mp,\n+\t     struct rte_mbuf **pkts_burst, uint32_t burst_size)\n+{\n+\tstruct ether_hdr pkt_eth_hdr;\n+\tstruct ipv4_hdr pkt_ipv4_hdr;\n+\tstruct udp_hdr pkt_udp_hdr;\n+\tuint32_t src_addr = IPV4_ADDR(2, 2, 2, 3);\n+\tuint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7);\n+\tuint16_t src_port = 32;\n+\tuint16_t dst_port = 33;\n+\tuint16_t pktlen;\n+\n+\tstatic uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };\n+\tstatic uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };\n+\n+\tinitialize_eth_header(&pkt_eth_hdr,\n+\t\t(struct ether_addr *)src_mac,\n+\t\t(struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);\n+\tpktlen = (uint16_t)(sizeof(struct ether_hdr));\n+\tprintf(\"ETH  pktlen %u\\n\", pktlen);\n+\n+\tpktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr,\n+\t\t\t\t\tpktlen);\n+\tprintf(\"ETH + IPv4 pktlen %u\\n\", pktlen);\n+\n+\tpktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port,\n+\t\t\t\t\tpktlen);\n+\tprintf(\"ETH + IPv4 + UDP pktlen %u\\n\", pktlen);\n+\n+\treturn generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr,\n+\t\t\t\t     0, &pkt_ipv4_hdr, 1,\n+\t\t\t\t     &pkt_udp_hdr, burst_size,\n+\t\t\t\t     PACKET_BURST_GEN_PKT_LEN, 1);\n+}\n+\n+static int\n+init_mbufpool(void)\n+{\n+\tint socketid;\n+\tint ret = 0;\n+\tunsigned int lcore_id;\n+\tchar s[64];\n+\n+\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n+\t\tif (rte_lcore_is_enabled(lcore_id) == 0)\n+\t\t\tcontinue;\n+\n+\t\tsocketid = rte_lcore_to_socket_id(lcore_id);\n+\t\tif (socketid >= NB_SOCKETS) {\n+\t\t\tprintf(\n+\t\t\t\t\"Socket %d of lcore %u is out of range %d\\n\",\n+\t\t\t\tsocketid, lcore_id, NB_SOCKETS);\n+\t\t\tret = -1;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (mbufpool[socketid] == NULL) {\n+\t\t\tsnprintf(s, sizeof(s), \"mbuf_pool_%d\", socketid);\n+\t\t\tmbufpool[socketid] =\n+\t\t\t\trte_pktmbuf_pool_create(s, NB_MBUF,\n+\t\t\t\t\tMEMPOOL_CACHE_SIZE, 0, MBUF_SIZE,\n+\t\t\t\t\tsocketid);\n+\t\t\tif (mbufpool[socketid]) {\n+\t\t\t\tprintf(\"Allocated mbuf pool on socket %d\\n\",\n+\t\t\t\t\tsocketid);\n+\t\t\t} else {\n+\t\t\t\tprintf(\"Cannot init mbuf pool on socket %d\\n\",\n+\t\t\t\t\tsocketid);\n+\t\t\t\tret = -ENOMEM;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn ret;\n+}\n+\n+static int\n+test_query_udp(void)\n+{\n+\tstruct rte_flow_error error;\n+\tstruct rte_flow_classify *flow_classify;\n+\tint ret;\n+\tint i;\n+\n+\tret = init_udp_ipv4_traffic(mbufpool[0], bufs, MAX_PKT_BURST);\n+\tif (ret != MAX_PKT_BURST) {\n+\t\tprintf(\"Line %i: init_udp_ipv4_traffic has failed!\\n\",\n+\t\t\t\t__LINE__);\n+\t\treturn -1;\n+\t}\n+\n+\tfor (i = 0; i < MAX_PKT_BURST; i++)\n+\t\tbufs[i]->packet_type = RTE_PTYPE_L3_IPV4;\n+\n+\t/* set up parameters for rte_flow_classify_validate and\n+\t * rte_flow_classify_create and rte_flow_classify_destroy\n+\t */\n+\n+\tattr.ingress = 1;\n+\tattr.priority = 1;\n+\tpattern_udp_1[0] = eth_item;\n+\tpattern_udp_1[1] = ipv4_udp_item_1;\n+\tpattern_udp_1[2] = udp_item_1;\n+\tpattern_udp_1[3] = end_item;\n+\tactions[0] = count_action;\n+\tactions[1] = end_action;\n+\n+\tret = rte_flow_classify_validate(table_acl, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (ret) {\n+\t\tprintf(\"Line %i: flow_classify_validate\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tflow_classify = rte_flow_classify_create(table_acl, entry_size, &attr,\n+\t\t\tpattern_udp_1, actions, &error);\n+\tif (!flow_classify) {\n+\t\tprintf(\"Line %i: flow_classify_create\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_query(table_acl, flow_classify, bufs,\n+\t\t\tMAX_PKT_BURST, &udp_classify_stats, &error);\n+\tif (ret) {\n+\t\tprintf(\"Line %i: flow_classify_query\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_flow_classify_destroy(table_acl, flow_classify, &error);\n+\tif (ret) {\n+\t\tprintf(\"Line %i: flow_classify_destroy\", __LINE__);\n+\t\tprintf(\" should not have failed!\\n\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+test_flow_classify(void)\n+{\n+\tstruct rte_table_acl_params table_acl_params;\n+\tint socket_id = 0;\n+\tint ret;\n+\n+\t/* initialise ACL table params */\n+\ttable_acl_params.n_rule_fields = RTE_DIM(ipv4_defs);\n+\ttable_acl_params.name = \"table_acl_ipv4_5tuple\";\n+\ttable_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM;\n+\tmemcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));\n+\tentry_size = RTE_ACL_RULE_SZ(RTE_DIM(ipv4_defs));\n+\n+\ttable_acl = rte_table_acl_ops.f_create(&table_acl_params, socket_id,\n+\t\t\t\t\tentry_size);\n+\tif (table_acl == NULL) {\n+\t\tprintf(\"Line %i: f_create has failed!\\n\", __LINE__);\n+\t\treturn -1;\n+\t}\n+\tprintf(\"Created table_acl for for IPv4 five tuple packets\\n\");\n+\n+\tret = init_mbufpool();\n+\tif (ret) {\n+\t\tprintf(\"Line %i: init_mbufpool has failed!\\n\", __LINE__);\n+\t\treturn -1;\n+\t}\n+\n+\tif (test_invalid_parameters() < 0)\n+\t\treturn -1;\n+\tif (test_valid_parameters() < 0)\n+\t\treturn -1;\n+\tif (test_invalid_patterns() < 0)\n+\t\treturn -1;\n+\tif (test_invalid_actions() < 0)\n+\t\treturn -1;\n+\tif (test_query_udp() < 0)\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\n+\n+REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify);\ndiff --git a/test/test/test_flow_classify.h b/test/test/test_flow_classify.h\nnew file mode 100644\nindex 0000000..af04dd3\n--- /dev/null\n+++ b/test/test/test_flow_classify.h\n@@ -0,0 +1,186 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef TEST_FLOW_CLASSIFY_H_\n+#define TEST_FLOW_CLASSIFY_H_\n+\n+#define MAX_PKT_BURST      (32)\n+#define NB_SOCKETS         (1)\n+#define MEMPOOL_CACHE_SIZE (256)\n+#define MBUF_SIZE          (512)\n+#define NB_MBUF            (512)\n+\n+/* test UDP packets */\n+static struct rte_mempool *mbufpool[NB_SOCKETS];\n+static struct rte_mbuf *bufs[MAX_PKT_BURST];\n+\n+/* ACL field definitions for IPv4 5 tuple rule */\n+\n+enum {\n+\tPROTO_FIELD_IPV4,\n+\tSRC_FIELD_IPV4,\n+\tDST_FIELD_IPV4,\n+\tSRCP_FIELD_IPV4,\n+\tDSTP_FIELD_IPV4,\n+\tNUM_FIELDS_IPV4\n+};\n+\n+enum {\n+\tPROTO_INPUT_IPV4,\n+\tSRC_INPUT_IPV4,\n+\tDST_INPUT_IPV4,\n+\tSRCP_DESTP_INPUT_IPV4\n+};\n+\n+static struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {\n+\t/* first input field - always one byte long. */\n+\t{\n+\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n+\t\t.size = sizeof(uint8_t),\n+\t\t.field_index = PROTO_FIELD_IPV4,\n+\t\t.input_index = PROTO_INPUT_IPV4,\n+\t\t.offset = sizeof(struct ether_hdr) +\n+\t\t\toffsetof(struct ipv4_hdr, next_proto_id),\n+\t},\n+\t/* next input field (IPv4 source address) - 4 consecutive bytes. */\n+\t{\n+\t\t/* rte_flow uses a bit mask for IPv4 addresses */\n+\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n+\t\t.size = sizeof(uint32_t),\n+\t\t.field_index = SRC_FIELD_IPV4,\n+\t\t.input_index = SRC_INPUT_IPV4,\n+\t\t.offset = sizeof(struct ether_hdr) +\n+\t\t\toffsetof(struct ipv4_hdr, src_addr),\n+\t},\n+\t/* next input field (IPv4 destination address) - 4 consecutive bytes. */\n+\t{\n+\t\t/* rte_flow uses a bit mask for IPv4 addresses */\n+\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n+\t\t.size = sizeof(uint32_t),\n+\t\t.field_index = DST_FIELD_IPV4,\n+\t\t.input_index = DST_INPUT_IPV4,\n+\t\t.offset = sizeof(struct ether_hdr) +\n+\t\t\toffsetof(struct ipv4_hdr, dst_addr),\n+\t},\n+\t/*\n+\t * Next 2 fields (src & dst ports) form 4 consecutive bytes.\n+\t * They share the same input index.\n+\t */\n+\t{\n+\t\t/* rte_flow uses a bit mask for protocol ports */\n+\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n+\t\t.size = sizeof(uint16_t),\n+\t\t.field_index = SRCP_FIELD_IPV4,\n+\t\t.input_index = SRCP_DESTP_INPUT_IPV4,\n+\t\t.offset = sizeof(struct ether_hdr) +\n+\t\t\tsizeof(struct ipv4_hdr) +\n+\t\t\toffsetof(struct tcp_hdr, src_port),\n+\t},\n+\t{\n+\t\t/* rte_flow uses a bit mask for protocol ports */\n+\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n+\t\t.size = sizeof(uint16_t),\n+\t\t.field_index = DSTP_FIELD_IPV4,\n+\t\t.input_index = SRCP_DESTP_INPUT_IPV4,\n+\t\t.offset = sizeof(struct ether_hdr) +\n+\t\t\tsizeof(struct ipv4_hdr) +\n+\t\t\toffsetof(struct tcp_hdr, dst_port),\n+\t},\n+};\n+\n+/* parameters for rte_flow_classify_validate and rte_flow_classify_create */\n+\n+/* first sample UDP pattern:\n+ * \"eth / ipv4 src spec 2.2.2.3 src mask 255.255.255.00 dst spec 2.2.2.7\n+ *  dst mask 255.255.255.00 / udp src is 32 dst is 33 / end\"\n+ */\n+static struct rte_flow_item_ipv4 ipv4_udp_spec_1 = {\n+\t{ 0, 0, 0, 0, 0, 0, 17, 0, IPv4(2, 2, 2, 3), IPv4(2, 2, 2, 7)}\n+};\n+static const struct rte_flow_item_ipv4 ipv4_mask_24 = {\n+\t.hdr = {\n+\t\t.next_proto_id = 0xff,\n+\t\t.src_addr = 0xffffff00,\n+\t\t.dst_addr = 0xffffff00,\n+\t},\n+};\n+static struct rte_flow_item_udp udp_spec_1 = {\n+\t{ 32, 33, 0, 0 }\n+};\n+\n+static struct rte_flow_item  eth_item = { RTE_FLOW_ITEM_TYPE_ETH,\n+\t0, 0, 0 };\n+static struct rte_flow_item  eth_item_bad = { -1, 0, 0, 0 };\n+\n+static struct rte_flow_item  ipv4_udp_item_1 = { RTE_FLOW_ITEM_TYPE_IPV4,\n+\t&ipv4_udp_spec_1, 0, &ipv4_mask_24};\n+static struct rte_flow_item  ipv4_udp_item_bad = { RTE_FLOW_ITEM_TYPE_IPV4,\n+\tNULL, 0, NULL};\n+\n+static struct rte_flow_item  udp_item_1 = { RTE_FLOW_ITEM_TYPE_UDP,\n+\t&udp_spec_1, 0, &rte_flow_item_udp_mask};\n+static struct rte_flow_item  udp_item_bad = { RTE_FLOW_ITEM_TYPE_UDP,\n+\tNULL, 0, NULL};\n+\n+static struct rte_flow_item  end_item = { RTE_FLOW_ITEM_TYPE_END,\n+\t0, 0, 0 };\n+static struct rte_flow_item  end_item_bad = { -1, 0, 0, 0 };\n+\n+static struct rte_flow_item  pattern_udp_1[4];\n+\n+/* sample actions:\n+ * \"actions count / end\"\n+ */\n+static struct rte_flow_action count_action = { RTE_FLOW_ACTION_TYPE_COUNT, 0};\n+static struct rte_flow_action count_action_bad = { -1, 0};\n+\n+static struct rte_flow_action end_action = { RTE_FLOW_ACTION_TYPE_END, 0};\n+static struct rte_flow_action end_action_bad =\t{ -1, 0};\n+\n+static struct rte_flow_action actions[2];\n+\n+/* sample attributes */\n+static struct rte_flow_attr attr;\n+\n+/* sample error */\n+static struct rte_flow_error error;\n+\n+/* flow classify data for UDP burst */\n+static struct rte_flow_classify_5tuple_stats udp_ntuple_stats;\n+static struct rte_flow_classify_stats udp_classify_stats = {\n+\t\t.available_space = MAX_PKT_BURST,\n+\t\t.used_space = 0,\n+\t\t.stats = (void **)&udp_ntuple_stats\n+};\n+\n+#endif /* TEST_FLOW_CLASSIFY_H_ */\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "5/5"
    ]
}