get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 4998,
    "url": "https://patches.dpdk.org/api/patches/4998/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1432914198-11812-12-git-send-email-maciejx.t.gajdzica@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": "<1432914198-11812-12-git-send-email-maciejx.t.gajdzica@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1432914198-11812-12-git-send-email-maciejx.t.gajdzica@intel.com",
    "date": "2015-05-29T15:43:18",
    "name": "[dpdk-dev,11/11] ip_pipeline: added new implementation of flow classification pipeline",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b80a13297f144e327a0b311559780eaa794a2acd",
    "submitter": {
        "id": 18,
        "url": "https://patches.dpdk.org/api/people/18/?format=api",
        "name": "Maciej Gajdzica",
        "email": "maciejx.t.gajdzica@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1432914198-11812-12-git-send-email-maciejx.t.gajdzica@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/4998/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/4998/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 D54E79A8A;\n\tFri, 29 May 2015 18:24:47 +0200 (CEST)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id CB34E5A96\n\tfor <dev@dpdk.org>; Fri, 29 May 2015 18:24:44 +0200 (CEST)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby fmsmga103.fm.intel.com with ESMTP; 29 May 2015 09:24:43 -0700",
            "from unknown (HELO stargo) ([10.217.248.233])\n\tby orsmga001.jf.intel.com with SMTP; 29 May 2015 09:24:42 -0700",
            "by stargo (sSMTP sendmail emulation);\n\tFri, 29 May 2015 18:25:15 +0200"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.13,517,1427785200\"; d=\"scan'208\";a=\"702191750\"",
        "From": "Maciej Gajdzica <maciejx.t.gajdzica@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 29 May 2015 17:43:18 +0200",
        "Message-Id": "<1432914198-11812-12-git-send-email-maciejx.t.gajdzica@intel.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1432914198-11812-1-git-send-email-maciejx.t.gajdzica@intel.com>",
        "References": "<1432914198-11812-1-git-send-email-maciejx.t.gajdzica@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 11/11] ip_pipeline: added new implementation of\n\tflow classification pipeline",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <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": "Flow classification pipeline implementation is split to two files.\npipeline_flow_classification.c file handles front-end functions (cli\ncommands parsing) pipeline_flow_classification_ops.c contains\nimplementation of functions done by pipeline (back-end).\n\nSigned-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>\n---\n examples/ip_pipeline/Makefile                      |    3 +-\n examples/ip_pipeline/init.c                        |    2 +\n .../pipeline/pipeline_flow_classification.c        | 1761 +++++++++++++++++---\n .../pipeline/pipeline_flow_classification.h        |   41 +\n .../pipeline/pipeline_flow_classification_ops.c    |  559 +++++++\n .../pipeline/pipeline_flow_classification_ops.h    |  150 ++\n 6 files changed, 2292 insertions(+), 224 deletions(-)\n create mode 100644 examples/ip_pipeline/pipeline/pipeline_flow_classification.h\n create mode 100644 examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.c\n create mode 100644 examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.h",
    "diff": "diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile\nindex f8c7c5f..4a1d970 100644\n--- a/examples/ip_pipeline/Makefile\n+++ b/examples/ip_pipeline/Makefile\n@@ -65,7 +65,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_firewall_ops.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_firewall.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_routing_ops.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_routing.c\n-#SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_classification.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_classification.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_classification_ops.c\n \n CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/pipeline\n CFLAGS += -O3\ndiff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c\nindex 29caae8..a8d2f67 100644\n--- a/examples/ip_pipeline/init.c\n+++ b/examples/ip_pipeline/init.c\n@@ -47,6 +47,7 @@\n #include \"pipeline_passthrough.h\"\n #include \"pipeline_firewall.h\"\n #include \"pipeline_routing.h\"\n+#include \"pipeline_flow_classification.h\"\n \n #define APP_NAME_SIZE\t32\n \n@@ -1150,6 +1151,7 @@ int app_init(struct app_params *app)\n \tapp_pipeline_type_register(app, &pipeline_passthrough);\n \tapp_pipeline_type_register(app, &pipeline_firewall);\n \tapp_pipeline_type_register(app, &pipeline_routing);\n+\tapp_pipeline_type_register(app, &pipeline_flow_classification);\n \n \tapp_init_pipelines(app);\n \tapp_init_threads(app);\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c\nindex cc0cbf1..928e2ab 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c\n@@ -1,7 +1,7 @@\n /*-\n  *   BSD LICENSE\n  *\n- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n  *   All rights reserved.\n  *\n  *   Redistribution and use in source and binary forms, with or without\n@@ -32,275 +32,1590 @@\n  */\n \n #include <stdio.h>\n-#include <stdlib.h>\n-#include <stdint.h>\n+#include <string.h>\n+#include <sys/queue.h>\n+#include <netinet/in.h>\n \n+#include <rte_common.h>\n #include <rte_malloc.h>\n-#include <rte_log.h>\n-#include <rte_ethdev.h>\n-#include <rte_ether.h>\n-#include <rte_ip.h>\n-#include <rte_byteorder.h>\n+#include <cmdline_rdline.h>\n+#include <cmdline_parse.h>\n+#include <cmdline_parse_num.h>\n+#include <cmdline_parse_string.h>\n+#include <cmdline_parse_ipaddr.h>\n+#include <cmdline_parse_etheraddr.h>\n \n-#include <rte_port_ring.h>\n-#include <rte_table_hash.h>\n-#include <rte_pipeline.h>\n+#include \"app.h\"\n+#include \"pipeline_flow_classification_ops.h\"\n+#include \"pipeline_flow_classification.h\"\n+#include \"pipeline_common.h\"\n \n-#include \"main.h\"\n+#define MSG_TIMEOUT 1000\n \n-struct app_core_fc_message_handle_params {\n-\tstruct rte_ring *ring_req;\n-\tstruct rte_ring *ring_resp;\n+struct app_pipeline_fc_flow {\n+\tstruct pipeline_fc_key key;\n+\tuint32_t port_id;\n+\tvoid *entry_ptr;\n \n-\tstruct rte_pipeline *p;\n-\tuint32_t *port_out_id;\n-\tuint32_t table_id;\n+\tTAILQ_ENTRY(app_pipeline_fc_flow) node;\n };\n \n+struct app_pipeline_fc {\n+\tTAILQ_HEAD(, app_pipeline_fc_flow) flows;\n+\n+\tuint32_t n_flows;\n+};\n+\n+static struct app_pipeline_fc_flow *\n+app_pipeline_fc_flow_find(struct app_pipeline_fc *p,\n+\tstruct pipeline_fc_key *key)\n+{\n+\tstruct app_pipeline_fc_flow *f;\n+\n+\tTAILQ_FOREACH(f, &p->flows, node)\n+\t\tif (memcmp(key, &f->key, sizeof(struct pipeline_fc_key)) == 0)\n+\t\t\treturn f;\n+\n+\treturn NULL;\n+}\n+\n+static void\n+print_fc_qinq_flow(struct app_pipeline_fc_flow *flow)\n+{\n+\tprintf(\"svlan = %u, \"\n+\t\t   \"cvlan = %u \"\n+\t\t   \"=> Port = %u \"\n+\t\t   \"(entry_ptr = %p)\\n\",\n+\n+\t\t   flow->key.key.qinq.svlan,\n+\t\t   flow->key.key.qinq.cvlan,\n+\t\t   flow->port_id,\n+\t\t   flow->entry_ptr);\n+}\n+\n static void\n-app_message_handle(struct app_core_fc_message_handle_params *params);\n+print_fc_ipv4_5tuple_flow(struct app_pipeline_fc_flow *flow)\n+{\n+\tprintf(\"SA = %u.%u.%u.%u \"\n+\t\t   \"DA = %u.%u.%u.%u \"\n+\t\t   \"SP = %u \"\n+\t\t   \"DP = %u \"\n+\t\t   \"Proto = %u \"\n+\t\t   \"=> Port = %u \"\n+\t\t   \"(entry_ptr = %p)\\n\",\n+\n+\t\t   (flow->key.key.ipv4_5tuple.ip_src >> 24) & 0xFF,\n+\t\t   (flow->key.key.ipv4_5tuple.ip_src >> 16) & 0xFF,\n+\t\t   (flow->key.key.ipv4_5tuple.ip_src >> 8) & 0xFF,\n+\t\t   flow->key.key.ipv4_5tuple.ip_src & 0xFF,\n+\n+\t\t   (flow->key.key.ipv4_5tuple.ip_dst >> 24) & 0xFF,\n+\t\t   (flow->key.key.ipv4_5tuple.ip_dst >> 16) & 0xFF,\n+\t\t   (flow->key.key.ipv4_5tuple.ip_dst >> 8) & 0xFF,\n+\t\t   flow->key.key.ipv4_5tuple.ip_dst & 0xFF,\n+\n+\t\t   flow->key.key.ipv4_5tuple.port_src,\n+\t\t   flow->key.key.ipv4_5tuple.port_dst,\n+\n+\t\t   flow->key.key.ipv4_5tuple.proto,\n+\n+\t\t   flow->port_id,\n+\t\t   flow->entry_ptr);\n+}\n+\n+static void\n+print_fc_ipv6_5tuple_flow(struct app_pipeline_fc_flow *flow)\n+{\n+\tprintf(\"SA = %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \"\n+\t\t   \"DA = %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \"\n+\t\t   \"SP = %u \"\n+\t\t   \"DP = %u \"\n+\t\t   \"Proto = %u \"\n+\t\t   \"=> Port = %u \"\n+\t\t   \"(entry_ptr = %p)\\n\",\n+\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[0],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[1],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[2],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[3],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[4],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[5],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[6],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[7],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[8],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[9],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[10],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[11],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[12],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[13],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[14],\n+\t\t   flow->key.key.ipv6_5tuple.ip_src[15],\n+\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[0],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[1],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[2],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[3],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[4],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[5],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[6],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[7],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[8],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[9],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[10],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[11],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[12],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[13],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[14],\n+\t\t   flow->key.key.ipv6_5tuple.ip_dst[15],\n \n-static int app_flow_classification_table_init(\n-\tstruct rte_pipeline *p,\n-\tuint32_t *port_out_id,\n-\tuint32_t table_id)\n+\t\t   flow->key.key.ipv6_5tuple.port_src,\n+\t\t   flow->key.key.ipv6_5tuple.port_dst,\n+\n+\t\t   flow->key.key.ipv6_5tuple.proto,\n+\n+\t\t   flow->port_id,\n+\t\t   flow->entry_ptr);\n+}\n+\n+static void\n+print_fc_flow(struct app_pipeline_fc_flow *flow)\n {\n-\tstruct app_flow_key flow_key;\n-\tuint32_t i;\n-\n-\t/* Add entries to tables */\n-\tfor (i = 0; i < (1 << 24); i++) {\n-\t\tstruct rte_pipeline_table_entry entry = {\n-\t\t\t.action = RTE_PIPELINE_ACTION_PORT,\n-\t\t\t{.port_id = port_out_id[i & (app.n_ports - 1)]},\n-\t\t};\n-\t\tstruct rte_pipeline_table_entry *entry_ptr;\n-\t\tint key_found, status;\n-\n-\t\tflow_key.ttl = 0;\n-\t\tflow_key.proto = 6; /* TCP */\n-\t\tflow_key.header_checksum = 0;\n-\t\tflow_key.ip_src = 0;\n-\t\tflow_key.ip_dst = rte_bswap32(i);\n-\t\tflow_key.port_src = 0;\n-\t\tflow_key.port_dst = 0;\n-\n-\t\tstatus = rte_pipeline_table_entry_add(p, table_id,\n-\t\t\t(void *) &flow_key, &entry, &key_found, &entry_ptr);\n-\t\tif (status < 0)\n-\t\t\trte_panic(\"Unable to add entry to table %u (%d)\\n\",\n-\t\t\t\ttable_id, status);\n+\tswitch(flow->key.type) {\n+\tcase FLOW_KEY_QINQ:\n+\t\tprint_fc_qinq_flow(flow);\n+\t\tbreak;\n+\tcase FLOW_KEY_IPV4_5TUPLE:\n+\t\tprint_fc_ipv4_5tuple_flow(flow);\n+\t\tbreak;\n+\tcase FLOW_KEY_IPV6_5TUPLE:\n+\t\tprint_fc_ipv6_5tuple_flow(flow);\n+\t\tbreak;\n \t}\n+}\n \n-\treturn 0;\n+static void\n+app_pipeline_fc_qinq_default_set(struct pipeline_fc_key *default_key)\n+{\n+\tdefault_key->key.qinq.svlan = 0xFFFF;\n+\tdefault_key->key.qinq.cvlan = 0xFFFF;\n }\n \n-void\n-app_main_loop_pipeline_flow_classification(void) {\n-\tstruct rte_pipeline_params pipeline_params = {\n-\t\t.name = \"pipeline\",\n-\t\t.socket_id = rte_socket_id(),\n-\t};\n+static void\n+app_pipeline_fc_ipv4_5tuple_default_set(struct pipeline_fc_key *default_key)\n+{\n+\tdefault_key->key.ipv4_5tuple.ip_src = 0;\n+\tdefault_key->key.ipv4_5tuple.ip_dst = 0;\n+\tdefault_key->key.ipv4_5tuple.port_src = 0;\n+\tdefault_key->key.ipv4_5tuple.port_dst = 0;\n+\tdefault_key->key.ipv4_5tuple.proto = 0xFF;\n+}\n+\n+static void\n+app_pipeline_fc_ipv6_5tuple_default_set(struct pipeline_fc_key *default_key)\n+{\n+\tmemset(default_key->key.ipv6_5tuple.ip_src, 0, 16);\n+\tmemset(default_key->key.ipv6_5tuple.ip_dst, 0, 16);\n+\tdefault_key->key.ipv6_5tuple.port_src = 0;\n+\tdefault_key->key.ipv6_5tuple.port_dst = 0;\n+\tdefault_key->key.ipv6_5tuple.proto = 0xFF;\n+}\n \n-\tstruct rte_pipeline *p;\n-\tuint32_t port_in_id[APP_MAX_PORTS];\n-\tuint32_t port_out_id[APP_MAX_PORTS];\n-\tuint32_t table_id;\n-\tuint32_t i;\n+static void*\n+app_pipeline_fc_init(struct pipeline_params *params,\n+\t__rte_unused void *arg)\n+{\n+\tstruct app_pipeline_fc *p;\n+\tuint32_t size;\n+\n+\t/* Check input arguments */\n+\tif ((params == NULL))\n+\t\treturn NULL;\n+\n+\t/* Memory allocation */\n+\tsize = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_fc));\n+\tp = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);\n+\tif (p == NULL)\n+\t\treturn NULL;\n \n-\tuint32_t core_id = rte_lcore_id();\n-\tstruct app_core_params *core_params = app_get_core_params(core_id);\n-\tstruct app_core_fc_message_handle_params mh_params;\n+\t/* Initialization */\n+\tTAILQ_INIT(&p->flows);\n+\tp->n_flows = 0;\n \n-\tif ((core_params == NULL) || (core_params->core_type != APP_CORE_FC))\n-\t\trte_panic(\"Core %u misconfiguration\\n\", core_id);\n+\treturn (void *) p;\n+}\n \n-\tRTE_LOG(INFO, USER1, \"Core %u is doing flow classification \"\n-\t\t\"(pipeline with hash table, 16-byte key, LRU)\\n\", core_id);\n+static int\n+app_pipeline_fc_free(void *pipeline)\n+{\n+\tstruct app_pipeline_fc *p = pipeline;\n+\tstruct app_pipeline_fc_flow *flow;\n \n-\t/* Pipeline configuration */\n-\tp = rte_pipeline_create(&pipeline_params);\n+\t/* Check input arguments */\n \tif (p == NULL)\n-\t\trte_panic(\"Unable to configure the pipeline\\n\");\n-\n-\t/* Input port configuration */\n-\tfor (i = 0; i < app.n_ports; i++) {\n-\t\tstruct rte_port_ring_reader_params port_ring_params = {\n-\t\t\t.ring = app.rings[core_params->swq_in[i]],\n-\t\t};\n-\n-\t\tstruct rte_pipeline_port_in_params port_params = {\n-\t\t\t.ops = &rte_port_ring_reader_ops,\n-\t\t\t.arg_create = (void *) &port_ring_params,\n-\t\t\t.f_action = NULL,\n-\t\t\t.arg_ah = NULL,\n-\t\t\t.burst_size = app.bsz_swq_rd,\n-\t\t};\n-\n-\t\tif (rte_pipeline_port_in_create(p, &port_params,\n-\t\t\t&port_in_id[i]))\n-\t\t\trte_panic(\"Unable to configure input port for \"\n-\t\t\t\t\"ring %d\\n\", i);\n+\t\treturn -1;\n+\n+\t/* Free resources */\n+\tTAILQ_FOREACH(flow, &p->flows, node) {\n+\t\tTAILQ_REMOVE(&p->flows, flow, node);\n+\t\trte_free(flow);\n \t}\n \n-\t/* Output port configuration */\n-\tfor (i = 0; i < app.n_ports; i++) {\n-\t\tstruct rte_port_ring_writer_params port_ring_params = {\n-\t\t\t.ring = app.rings[core_params->swq_out[i]],\n-\t\t\t.tx_burst_sz = app.bsz_swq_wr,\n-\t\t};\n-\n-\t\tstruct rte_pipeline_port_out_params port_params = {\n-\t\t\t.ops = &rte_port_ring_writer_ops,\n-\t\t\t.arg_create = (void *) &port_ring_params,\n-\t\t\t.f_action = NULL,\n-\t\t\t.f_action_bulk = NULL,\n-\t\t\t.arg_ah = NULL,\n-\t\t};\n-\n-\t\tif (rte_pipeline_port_out_create(p, &port_params,\n-\t\t\t&port_out_id[i]))\n-\t\t\trte_panic(\"Unable to configure output port for \"\n-\t\t\t\t\"ring %d\\n\", i);\n+\trte_free(p);\n+\treturn 0;\n+}\n+\n+static int\n+app_pipeline_fc_add(struct app_params *app,\n+\t\tuint32_t pipeline_id,\n+\t\tstruct pipeline_fc_key *key,\n+\t\tuint32_t port_id)\n+{\n+\tstruct app_pipeline_params *params;\n+\tstruct app_pipeline_data *data;\n+\tstruct app_pipeline_fc *p;\n+\tstruct app_pipeline_fc_flow *flow;\n+\n+\tstruct pipeline_fc_add_msg_req *req;\n+\tstruct pipeline_fc_add_msg_rsp *rsp;\n+\n+\tint new_flow;\n+\n+\t/* Check input arguments */\n+\tif ((app == NULL) ||\n+\t\t(key == NULL))\n+\t\treturn -1;\n+\n+\tAPP_PARAM_FIND_BY_ID(app->pipeline_params, \"PIPELINE\", pipeline_id, params);\n+\tif ((params == NULL))\n+\t\treturn -1;\n+\n+\tdata = &app->pipeline_data[params - app->pipeline_params];\n+\tp = data->fe;\n+\n+\t/* Find existing flow or allocate new flow */\n+\tflow = app_pipeline_fc_flow_find(p, key);\n+\tnew_flow = (flow == NULL);\n+\tif (flow == NULL) {\n+\t\tflow = rte_malloc(NULL, sizeof(*flow), RTE_CACHE_LINE_SIZE);\n+\n+\t\tif (flow == NULL)\n+\t\t\treturn -1;\n \t}\n \n-\t/* Table configuration */\n-\t{\n-\t\tstruct rte_table_hash_key16_lru_params table_hash_params = {\n-\t\t\t.n_entries = 1 << 24,\n-\t\t\t.signature_offset = __builtin_offsetof(\n-\t\t\t\tstruct app_pkt_metadata, signature),\n-\t\t\t.key_offset = __builtin_offsetof(\n-\t\t\t\tstruct app_pkt_metadata, flow_key),\n-\t\t\t.f_hash = test_hash,\n-\t\t\t.seed = 0,\n-\t\t};\n-\n-\t\tstruct rte_pipeline_table_params table_params = {\n-\t\t\t.ops = &rte_table_hash_key16_lru_ops,\n-\t\t\t.arg_create = &table_hash_params,\n-\t\t\t.f_action_hit = NULL,\n-\t\t\t.f_action_miss = NULL,\n-\t\t\t.arg_ah = NULL,\n-\t\t\t.action_data_size = 0,\n-\t\t};\n-\n-\t\tif (rte_pipeline_table_create(p, &table_params, &table_id))\n-\t\t\trte_panic(\"Unable to configure the hash table\\n\");\n+\t/* Allocate and write request */\n+\treq = app_msg_alloc(app);\n+\tif (req == NULL)\n+\t\treturn -1;\n+\n+\treq->type = PIPELINE_MSG_REQ_CUSTOM;\n+\treq->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD;\n+\tmemcpy(&req->key, key, sizeof(*key));\n+\treq->port_id = port_id;\n+\n+\t/* Send request and wait for response */\n+\trsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT);\n+\tif (rsp == NULL) {\n+\t\tif (new_flow)\n+\t\t\trte_free(flow);\n+\t\treturn -1;\n \t}\n \n-\t/* Interconnecting ports and tables */\n-\tfor (i = 0; i < app.n_ports; i++)\n-\t\tif (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],\n-\t\t\ttable_id))\n-\t\t\trte_panic(\"Unable to connect input port %u to \"\n-\t\t\t\t\"table %u\\n\", port_in_id[i],  table_id);\n-\n-\t/* Enable input ports */\n-\tfor (i = 0; i < app.n_ports; i++)\n-\t\tif (rte_pipeline_port_in_enable(p, port_in_id[i]))\n-\t\t\trte_panic(\"Unable to enable input port %u\\n\",\n-\t\t\t\tport_in_id[i]);\n-\n-\t/* Check pipeline consistency */\n-\tif (rte_pipeline_check(p) < 0)\n-\t\trte_panic(\"Pipeline consistency check failed\\n\");\n-\n-\t/* Message handling */\n-\tmh_params.ring_req = app_get_ring_req(\n-\t\tapp_get_first_core_id(APP_CORE_FC));\n-\tmh_params.ring_resp = app_get_ring_resp(\n-\t\tapp_get_first_core_id(APP_CORE_FC));\n-\tmh_params.p = p;\n-\tmh_params.port_out_id = port_out_id;\n-\tmh_params.table_id = table_id;\n-\n-\t/* Run-time */\n-\tfor (i = 0; ; i++) {\n-\t\trte_pipeline_run(p);\n-\n-\t\tif ((i & APP_FLUSH) == 0) {\n-\t\t\trte_pipeline_flush(p);\n-\t\t\tapp_message_handle(&mh_params);\n-\t\t}\n+\t/* Read response and write flow */\n+\tif (rsp->status || (rsp->entry_ptr == NULL)){\n+\t\tapp_msg_free(app, rsp);\n+\t\tif (new_flow)\n+\t\t\trte_free(flow);\n+\t\treturn -1;\n+\t}\n+\n+\tmemcpy(&flow->key, key, sizeof(*key));\n+\tflow->port_id = port_id;\n+\tflow->entry_ptr = rsp->entry_ptr;\n+\n+\t/* Commit rule */\n+\tif (new_flow) {\n+\t\tTAILQ_INSERT_TAIL(&p->flows, flow, node);\n+\t\tp->n_flows++;\n \t}\n+\n+\tprint_fc_flow(flow);\n+\n+\t/* Free response */\n+\tapp_msg_free(app, rsp);\n+\n+\treturn 0;\n }\n \n-void\n-app_message_handle(struct app_core_fc_message_handle_params *params)\n+static int\n+app_pipeline_fc_del(struct app_params *app,\n+\t\tuint32_t pipeline_id,\n+\t\tstruct pipeline_fc_key *key)\n {\n-\tstruct rte_ring *ring_req = params->ring_req;\n-\tstruct rte_ring *ring_resp;\n-\tvoid *msg;\n-\tstruct app_msg_req *req;\n-\tstruct app_msg_resp *resp;\n-\tstruct rte_pipeline *p;\n-\tuint32_t *port_out_id;\n-\tuint32_t table_id;\n-\tint result;\n-\n-\t/* Read request message */\n-\tresult = rte_ring_sc_dequeue(ring_req, &msg);\n-\tif (result != 0)\n-\t\treturn;\n+\tstruct app_pipeline_params *params;\n+\tstruct app_pipeline_data *data;\n+\tstruct app_pipeline_fc *p;\n+\tstruct app_pipeline_fc_flow *flow;\n \n-\tring_resp = params->ring_resp;\n-\tp = params->p;\n-\tport_out_id = params->port_out_id;\n-\ttable_id = params->table_id;\n-\n-\t/* Handle request */\n-\treq = (struct app_msg_req *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);\n-\tswitch (req->type) {\n-\tcase APP_MSG_REQ_PING:\n-\t{\n-\t\tresult = 0;\n-\t\tbreak;\n+\tstruct pipeline_fc_del_msg_req *req;\n+\tstruct pipeline_fc_del_msg_rsp *rsp;\n+\n+\t/* Check input arguments */\n+\tif ((app == NULL) ||\n+\t\t(key == NULL))\n+\t\treturn -1;\n+\n+\tAPP_PARAM_FIND_BY_ID(app->pipeline_params, \"PIPELINE\", pipeline_id, params);\n+\tif (params == NULL)\n+\t\treturn -1;\n+\n+\tdata = &app->pipeline_data[params - app->pipeline_params];\n+\tp = data->fe;\n+\n+\t/* Find rule */\n+\tflow = app_pipeline_fc_flow_find(p, key);\n+\tif (flow == NULL)\n+\t\treturn 0;\n+\n+\t/* Allocate and write request */\n+\treq = app_msg_alloc(app);\n+\tif (req == NULL)\n+\t\treturn -1;\n+\n+\treq->type = PIPELINE_MSG_REQ_CUSTOM;\n+\treq->subtype = PIPELINE_FC_MSG_REQ_FLOW_DEL;\n+\tmemcpy(&req->key, key, sizeof(*key));\n+\n+\t/* Send request and wait for response */\n+\trsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT);\n+\tif (rsp == NULL)\n+\t\treturn -1;\n+\n+\t/* Read response */\n+\tif (rsp->status) {\n+\t\tapp_msg_free(app, rsp);\n+\t\treturn -1;\n \t}\n \n-\tcase APP_MSG_REQ_FC_ADD_ALL:\n-\t{\n-\t\tresult = app_flow_classification_table_init(p, port_out_id,\n-\t\t\ttable_id);\n+\t/* Remove rule */\n+\tTAILQ_REMOVE(&p->flows, flow, node);\n+\tp->n_flows--;\n+\n+\t/* Free response */\n+\tapp_msg_free(app, rsp);\n+\n+\treturn 0;\n+}\n+\n+static int\n+app_pipeline_fc_add_default(struct app_params *app,\n+\t\tuint32_t pipeline_id,\n+\t\tenum flow_key_type type,\n+\t\tuint32_t port_id)\n+{\n+\tstruct app_pipeline_params *params;\n+\tstruct app_pipeline_data *data;\n+\tstruct app_pipeline_fc *p;\n+\tstruct app_pipeline_fc_flow *flow;\n+\tstruct pipeline_fc_key *default_key;\n+\n+\tstruct pipeline_fc_add_default_msg_req *req;\n+\tstruct pipeline_fc_add_default_msg_rsp *rsp;\n+\n+\tint new_flow;\n+\n+\t/* Check input arguments */\n+\tif (app == NULL)\n+\t\treturn -1;\n+\n+\tAPP_PARAM_FIND_BY_ID(app->pipeline_params, \"PIPELINE\", pipeline_id, params);\n+\tif ((params == NULL))\n+\t\treturn -1;\n+\n+\tdata = &app->pipeline_data[params - app->pipeline_params];\n+\tp = data->fe;\n+\n+\t/* Set default flow settings */\n+\tdefault_key = rte_malloc(NULL, sizeof(*default_key), RTE_CACHE_LINE_SIZE);\n+\tif (default_key == NULL)\n+\t\treturn -1;\n+\n+\tswitch (type) {\n+\tcase FLOW_KEY_QINQ:\n+\t\tapp_pipeline_fc_qinq_default_set(default_key);\n+\t\tbreak;\n+\tcase FLOW_KEY_IPV4_5TUPLE:\n+\t\tapp_pipeline_fc_ipv4_5tuple_default_set(default_key);\n+\t\tbreak;\n+\tcase FLOW_KEY_IPV6_5TUPLE:\n+\t\tapp_pipeline_fc_ipv6_5tuple_default_set(default_key);\n \t\tbreak;\n \t}\n \n-\tcase APP_MSG_REQ_FC_ADD:\n-\t{\n-\t\tstruct rte_pipeline_table_entry entry = {\n-\t\t\t.action = RTE_PIPELINE_ACTION_PORT,\n-\t\t\t{.port_id = port_out_id[req->flow_classif_add.port]},\n-\t\t};\n+\t/* Find existing flow or allocate new flow */\n+\tflow = app_pipeline_fc_flow_find(p, default_key);\n+\tnew_flow = (flow == NULL);\n+\tif (flow == NULL) {\n+\t\tflow = rte_malloc(NULL, sizeof(*flow), RTE_CACHE_LINE_SIZE);\n+\n+\t\tif (flow == NULL) {\n+\t\t\trte_free(default_key);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/* Allocate and write request */\n+\treq = app_msg_alloc(app);\n+\tif (req == NULL) {\n+\t\trte_free(default_key);\n+\t\treturn -1;\n+\t}\n \n-\t\tstruct rte_pipeline_table_entry *entry_ptr;\n+\treq->type = PIPELINE_MSG_REQ_CUSTOM;\n+\treq->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT;\n+\treq->port_id = port_id;\n \n-\t\tint key_found;\n+\t/* Send request and wait for response */\n+\trsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT);\n+\tif (rsp == NULL) {\n+\t\tif (new_flow) {\n+\t\t\trte_free(flow);\n+\t\t\trte_free(default_key);\n+\t\t}\n+\t\treturn -1;\n+\t}\n \n-\t\tresult = rte_pipeline_table_entry_add(p, table_id,\n-\t\t\treq->flow_classif_add.key_raw, &entry, &key_found,\n-\t\t\t&entry_ptr);\n-\t\tbreak;\n+\t/* Read response and write flow */\n+\tif (rsp->status || (rsp->default_entry_ptr == NULL)){\n+\t\tapp_msg_free(app, rsp);\n+\t\tif (new_flow) {\n+\t\t\trte_free(flow);\n+\t\t\trte_free(default_key);\n+\t\t}\n+\t\treturn -1;\n \t}\n \n-\tcase APP_MSG_REQ_FC_DEL:\n-\t{\n-\t\tint key_found;\n+\tmemcpy(&flow->key, default_key, sizeof(*default_key));\n+\tflow->port_id = port_id;\n+\tflow->entry_ptr = rsp->default_entry_ptr;\n \n-\t\tresult = rte_pipeline_table_entry_delete(p, table_id,\n-\t\t\treq->flow_classif_add.key_raw, &key_found, NULL);\n+\t/* Commit rule */\n+\tif (new_flow) {\n+\t\tTAILQ_INSERT_TAIL(&p->flows, flow, node);\n+\t\tp->n_flows++;\n+\t}\n+\n+\t/* Free response */\n+\tapp_msg_free(app, rsp);\n+\trte_free(default_key);\n+\n+\treturn 0;\n+}\n+\n+static int\n+app_pipeline_fc_del_default(struct app_params *app,\n+\t\tenum flow_key_type type,\n+\t\tuint32_t pipeline_id)\n+{\n+\tstruct app_pipeline_params *params;\n+\tstruct app_pipeline_data *data;\n+\tstruct app_pipeline_fc *p;\n+\tstruct app_pipeline_fc_flow *flow;\n+\tstruct pipeline_fc_key *default_key;\n+\n+\tstruct pipeline_fc_del_default_msg_req *req;\n+\tstruct pipeline_fc_del_default_msg_rsp *rsp;\n+\n+\t/* Check input arguments */\n+\tif (app == NULL)\n+\t\treturn -1;\n+\n+\tAPP_PARAM_FIND_BY_ID(app->pipeline_params, \"PIPELINE\", pipeline_id, params);\n+\tif ((params == NULL))\n+\t\treturn -1;\n+\n+\tdata = &app->pipeline_data[params - app->pipeline_params];\n+\tp = data->fe;\n+\n+\t/* Set default flow settings */\n+\tdefault_key = rte_malloc(NULL, sizeof(*default_key), RTE_CACHE_LINE_SIZE);\n+\tif (default_key == NULL)\n+\t\treturn -1;\n+\n+\tswitch (type) {\n+\tcase FLOW_KEY_QINQ:\n+\t\tapp_pipeline_fc_qinq_default_set(default_key);\n \t\tbreak;\n+\tcase FLOW_KEY_IPV4_5TUPLE:\n+\t\tapp_pipeline_fc_ipv4_5tuple_default_set(default_key);\n+\t\tbreak;\n+\tcase FLOW_KEY_IPV6_5TUPLE:\n+\t\tapp_pipeline_fc_ipv6_5tuple_default_set(default_key);\n+\t\tbreak;\n+\t}\n+\n+\t/* Find rule */\n+\tflow = app_pipeline_fc_flow_find(p, default_key);\n+\tif (flow == NULL) {\n+\t\trte_free(default_key);\n+\t\treturn 0;\n+\t}\n+\n+\t/* Allocate and write request */\n+\treq = app_msg_alloc(app);\n+\tif (req == NULL) {\n+\t\trte_free(default_key);\n+\t\treturn -1;\n \t}\n \n-\tdefault:\n-\t\trte_panic(\"FC Unrecognized message type (%u)\\n\", req->type);\n+\treq->type = PIPELINE_MSG_REQ_CUSTOM;\n+\treq->subtype = PIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT;\n+\n+\t/* Send request and wait for response */\n+\trsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT);\n+\tif (rsp == NULL) {\n+\t\trte_free(default_key);\n+\t\treturn -1;\n+\t}\n+\n+\t/* Read response */\n+\tif (rsp->status) {\n+\t\tapp_msg_free(app, rsp);\n+\t\trte_free(default_key);\n+\t\treturn -1;\n \t}\n \n-\t/* Fill in response message */\n-\tresp = (struct app_msg_resp *)rte_ctrlmbuf_data((struct rte_mbuf *)msg);\n-\tresp->result = result;\n+\t/* Remove rule */\n+\tTAILQ_REMOVE(&p->flows, flow, node);\n+\tp->n_flows--;\n+\n+\t/* Free response */\n+\tapp_msg_free(app, rsp);\n+\trte_free(default_key);\n+\n+\treturn 0;\n+}\n+\n+static void\n+app_pipeline_fc_ls(struct app_params *app,\n+\t\tuint32_t pipeline_id)\n+{\n+\tstruct app_pipeline_params *pipeline_params;\n+\tstruct app_pipeline_data *pipeline_data;\n+\tstruct app_pipeline_fc *p;\n+\tstruct app_pipeline_fc_flow *flow;\n+\n+\t/* Check input arguments */\n+\tif (app == NULL)\n+\t\treturn;\n+\n+\tAPP_PARAM_FIND_BY_ID(app->pipeline_params, \"PIPELINE\", pipeline_id, pipeline_params);\n+\tif (pipeline_params == NULL)\n+\t\treturn;\n+\n+\tpipeline_data = &app->pipeline_data[pipeline_params - app->pipeline_params];\n+\tp = pipeline_data->fe;\n+\n+\tTAILQ_FOREACH(flow, &p->flows, node) {\n+\t\tprint_fc_flow(flow);\n+\t}\n+}\n+\n+struct cmd_fc_add_qinq_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t add_string;\n+\tcmdline_fixed_string_t qinq_string;\n+\tuint16_t svlan;\n+\tuint16_t cvlan;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_add_qinq_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_add_qinq_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tstruct pipeline_fc_key key;\n+\tint status;\n+\n+\tmemset(&key, 0, sizeof(key));\n+\tkey.type = FLOW_KEY_QINQ;\n+\tkey.key.qinq.svlan = params->svlan;\n+\tkey.key.qinq.cvlan = params->cvlan;\n+\tstatus = app_pipeline_fc_add(app, params->pipeline_id, &key, params->port);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_add_qinq_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_qinq_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_add_qinq_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_qinq_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, add_string, \"add\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_qinq_qinq_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_qinq_result, add_string, \"qinq\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_qinq_svlan =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, svlan, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_add_qinq_cvlan =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, cvlan, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_add_qinq_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_qinq_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_add_qinq = {\n+\t.f = cmd_fc_add_qinq_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow add qinq <svlan> <cvlan> <port>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_qinq_p_string,\n+\t\t(void *) &cmd_fc_add_qinq_pipeline_id,\n+\t\t(void *) &cmd_fc_add_qinq_flow_string,\n+\t\t(void *) &cmd_fc_add_qinq_add_string,\n+\t\t(void *) &cmd_fc_add_qinq_qinq_string,\n+\t\t(void *) &cmd_fc_add_qinq_svlan,\n+\t\t(void *) &cmd_fc_add_qinq_cvlan,\n+\t\t(void *) &cmd_fc_add_qinq_port,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow add ipv4_5tuple\n+ */\n+\n+struct cmd_fc_add_ipv4_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t add_string;\n+\tcmdline_fixed_string_t ipv4_5tuple_string;\n+\tcmdline_ipaddr_t ip_src;\n+\tcmdline_ipaddr_t ip_dst;\n+\tuint16_t port_src;\n+\tuint16_t port_dst;\n+\tuint32_t proto;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_add_ipv4_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_add_ipv4_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tstruct pipeline_fc_key key;\n+\tint status;\n+\n+\tmemset(&key, 0, sizeof(key));\n+\tkey.type = FLOW_KEY_IPV4_5TUPLE;\n+\tkey.key.ipv4_5tuple.ip_src = params->ip_src.addr.ipv4.s_addr;\n+\tkey.key.ipv4_5tuple.ip_dst = params->ip_dst.addr.ipv4.s_addr;\n+\tkey.key.ipv4_5tuple.port_src = params->port_src;\n+\tkey.key.ipv4_5tuple.port_dst = params->port_dst;\n+\tkey.key.ipv4_5tuple.proto = params->proto;\n+\tstatus = app_pipeline_fc_add(app, params->pipeline_id, &key, params->port);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, add_string, \"add\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv4_5tuple_ipv4_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, ipv4_5tuple_string, \"ipv4_5tuple\");\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_add_ipv4_5tuple_ip_src =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, ip_src);\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_add_ipv4_5tuple_ip_dst =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, ip_dst);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port_src =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port_src, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port_dst =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port_dst, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_proto =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, proto, UINT32);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv4_5tuple_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv4_5tuple_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_add_ipv4_5tuple = {\n+\t.f = cmd_fc_add_ipv4_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow add ipv4_5tuple <ip_src> <ip_dst> <port_src> <port_dst> <proto> <port>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_p_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_add_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_ipv4_5tuple_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_ip_src,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_ip_dst,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_port_src,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_port_dst,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_proto,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_port,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow add ipv6_5tuple\n+ */\n+\n+struct cmd_fc_add_ipv6_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t add_string;\n+\tcmdline_fixed_string_t ipv6_5tuple_string;\n+\tcmdline_ipaddr_t ip_src;\n+\tcmdline_ipaddr_t ip_dst;\n+\tuint16_t port_src;\n+\tuint16_t port_dst;\n+\tuint32_t proto;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_add_ipv6_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_add_ipv6_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tstruct pipeline_fc_key key;\n+\tint status;\n+\n+\tmemset(&key, 0, sizeof(key));\n+\tkey.type = FLOW_KEY_IPV6_5TUPLE;\n+\tmemcpy(key.key.ipv6_5tuple.ip_src, params->ip_src.addr.ipv6.s6_addr, 16);\n+\tmemcpy(key.key.ipv6_5tuple.ip_dst, params->ip_dst.addr.ipv6.s6_addr, 16);\n+\tkey.key.ipv6_5tuple.port_src = params->port_src;\n+\tkey.key.ipv6_5tuple.port_dst = params->port_dst;\n+\tkey.key.ipv6_5tuple.proto = params->proto;\n+\tstatus = app_pipeline_fc_add(app, params->pipeline_id, &key, params->port);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, add_string, \"add\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_ipv6_5tuple_ipv6_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, ipv6_5tuple_string, \"ipv6_5tuple\");\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_add_ipv6_5tuple_ip_src =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, ip_src);\n \n-\t/* Send response */\n-\tdo {\n-\t\tresult = rte_ring_sp_enqueue(ring_resp, msg);\n-\t} while (result == -ENOBUFS);\n+cmdline_parse_token_ipaddr_t cmd_fc_add_ipv6_5tuple_ip_dst =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, ip_dst);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port_src =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port_src, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port_dst =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port_dst, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_proto =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, proto, UINT32);\n+\n+cmdline_parse_token_num_t cmd_fc_add_ipv6_5tuple_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_ipv6_5tuple_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_add_ipv6_5tuple = {\n+\t.f = cmd_fc_add_ipv6_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow add ipv6_5tuple <ip_src> <ip_dst> <port_src> <port_dst> <proto> <port>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_p_string,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_add_string,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_ipv6_5tuple_string,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_ip_src,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_ip_dst,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_port_src,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_port_dst,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_proto,\n+\t\t(void *) &cmd_fc_add_ipv6_5tuple_port,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow del qinq\n+ */\n+struct cmd_fc_del_qinq_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t del_string;\n+\tcmdline_fixed_string_t qinq_string;\n+\tuint16_t svlan;\n+\tuint16_t cvlan;\n+};\n+\n+static void\n+cmd_fc_del_qinq_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_del_qinq_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tstruct pipeline_fc_key key;\n+\tint status;\n+\n+\tmemset(&key, 0, sizeof(key));\n+\tkey.type = FLOW_KEY_QINQ;\n+\tkey.key.qinq.svlan = params->svlan;\n+\tkey.key.qinq.cvlan = params->cvlan;\n+\tstatus = app_pipeline_fc_del(app, params->pipeline_id, &key);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_del_qinq_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_qinq_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_qinq_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_del_qinq_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_qinq_del_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, del_string, \"del\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_qinq_qinq_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_qinq_result, qinq_string, \"qinq\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_qinq_svlan =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_qinq_result, svlan, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_del_qinq_cvlan =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_qinq_result, cvlan, UINT16);\n+\n+cmdline_parse_inst_t cmd_fc_del_qinq = {\n+\t.f = cmd_fc_del_qinq_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow del qinq <svlan> <cvlan>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_del_qinq_p_string,\n+\t\t(void *) &cmd_fc_del_qinq_pipeline_id,\n+\t\t(void *) &cmd_fc_del_qinq_flow_string,\n+\t\t(void *) &cmd_fc_del_qinq_del_string,\n+\t\t(void *) &cmd_fc_del_qinq_qinq_string,\n+\t\t(void *) &cmd_fc_del_qinq_svlan,\n+\t\t(void *) &cmd_fc_del_qinq_cvlan,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow del ipv4_5tuple\n+ */\n+\n+struct cmd_fc_del_ipv4_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t del_string;\n+\tcmdline_fixed_string_t ipv4_5tuple_string;\n+\tcmdline_ipaddr_t ip_src;\n+\tcmdline_ipaddr_t ip_dst;\n+\tuint16_t port_src;\n+\tuint16_t port_dst;\n+\tuint32_t proto;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_del_ipv4_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_del_ipv4_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tstruct pipeline_fc_key key;\n+\tint status;\n+\n+\tmemset(&key, 0, sizeof(key));\n+\tkey.type = FLOW_KEY_IPV4_5TUPLE;\n+\tkey.key.ipv4_5tuple.ip_src = params->ip_src.addr.ipv4.s_addr;\n+\tkey.key.ipv4_5tuple.ip_dst = params->ip_dst.addr.ipv4.s_addr;\n+\tkey.key.ipv4_5tuple.port_src = params->port_src;\n+\tkey.key.ipv4_5tuple.port_dst = params->port_dst;\n+\tkey.key.ipv4_5tuple.proto = params->proto;\n+\tstatus = app_pipeline_fc_del(app, params->pipeline_id, &key);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_del_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, del_string, \"del\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv4_5tuple_ipv4_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, ipv4_5tuple_string, \"ipv4_5tuple\");\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_del_ipv4_5tuple_ip_src =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, ip_src);\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_del_ipv4_5tuple_ip_dst =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, ip_dst);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_port_src =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, port_src, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_port_dst =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, port_dst, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv4_5tuple_proto =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv4_5tuple_result, proto, UINT32);\n+\n+cmdline_parse_inst_t cmd_fc_del_ipv4_5tuple = {\n+\t.f = cmd_fc_del_ipv4_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow del ipv4_5tuple <ip_src> <ip_dst> <port_src> <port_dst> <proto>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_p_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_add_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_ipv4_5tuple_string,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_ip_src,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_ip_dst,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_port_src,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_port_dst,\n+\t\t(void *) &cmd_fc_add_ipv4_5tuple_proto,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow del ipv6_5tuple\n+ */\n+\n+struct cmd_fc_del_ipv6_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t del_string;\n+\tcmdline_fixed_string_t ipv6_5tuple_string;\n+\tcmdline_ipaddr_t ip_src;\n+\tcmdline_ipaddr_t ip_dst;\n+\tuint16_t port_src;\n+\tuint16_t port_dst;\n+\tuint32_t proto;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_del_ipv6_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_del_ipv6_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tstruct pipeline_fc_key key;\n+\tint status;\n+\n+\tmemset(&key, 0, sizeof(key));\n+\tkey.type = FLOW_KEY_IPV6_5TUPLE;\n+\tmemcpy(key.key.ipv6_5tuple.ip_src, params->ip_src.addr.ipv6.s6_addr, 16);\n+\tmemcpy(key.key.ipv6_5tuple.ip_dst, params->ip_dst.addr.ipv6.s6_addr, 16);\n+\tkey.key.ipv6_5tuple.port_src = params->port_src;\n+\tkey.key.ipv6_5tuple.port_dst = params->port_dst;\n+\tkey.key.ipv6_5tuple.proto = params->proto;\n+\tstatus = app_pipeline_fc_del(app, params->pipeline_id, &key);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, del_string, \"del\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_ipv6_5tuple_ipv6_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, ipv6_5tuple_string, \"ipv6_5tuple\");\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_del_ipv6_5tuple_ip_src =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, ip_src);\n+\n+cmdline_parse_token_ipaddr_t cmd_fc_del_ipv6_5tuple_ip_dst =\n+\tTOKEN_IPADDR_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, ip_dst);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_port_src =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, port_src, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_port_dst =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, port_dst, UINT16);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_proto =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, proto, UINT32);\n+\n+cmdline_parse_token_num_t cmd_fc_del_ipv6_5tuple_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_ipv6_5tuple_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_del_ipv6_5tuple = {\n+\t.f = cmd_fc_del_ipv6_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow del ipv6_5tuple <ip_src> <ip_dst> <port_src> <port_dst> <proto>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_p_string,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_add_string,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_ipv6_5tuple_string,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_ip_src,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_ip_dst,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_port_src,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_port_dst,\n+\t\t(void *) &cmd_fc_del_ipv6_5tuple_proto,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow add default qinq\n+ */\n+\n+struct cmd_fc_add_default_qinq_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t add_string;\n+\tcmdline_fixed_string_t default_string;\n+\tcmdline_fixed_string_t qinq_string;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_add_default_qinq_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_add_default_qinq_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tenum flow_key_type type;\n+\tint status;\n+\n+\ttype = FLOW_KEY_QINQ;\n+\tstatus = app_pipeline_fc_add_default(app, params->pipeline_id, type,\n+\t\tparams->port);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_qinq_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_qinq_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_default_qinq_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_qinq_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_qinq_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_qinq_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_qinq_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_qinq_result, add_string, \"add\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_qinq_default_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_qinq_result, default_string, \"default\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_qinq_qinq_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_qinq_result, qinq_string, \"qinq\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_default_qinq_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_qinq_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_add_default_qinq = {\n+\t.f = cmd_fc_add_default_qinq_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow add default qinq <port>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_default_qinq_p_string,\n+\t\t(void *) &cmd_fc_add_default_qinq_pipeline_id,\n+\t\t(void *) &cmd_fc_add_default_qinq_flow_string,\n+\t\t(void *) &cmd_fc_add_default_qinq_add_string,\n+\t\t(void *) &cmd_fc_add_default_qinq_default_string,\n+\t\t(void *) &cmd_fc_add_default_qinq_qinq_string,\n+\t\t(void *) &cmd_fc_add_default_qinq_port,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow add default ipv4_5tuple\n+ */\n+\n+struct cmd_fc_add_default_ipv4_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t add_string;\n+\tcmdline_fixed_string_t default_string;\n+\tcmdline_fixed_string_t ipv4_5tuple_string;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_add_default_ipv4_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_add_default_ipv4_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tenum flow_key_type type;\n+\tint status;\n+\n+\ttype = FLOW_KEY_IPV4_5TUPLE;\n+\tstatus = app_pipeline_fc_add_default(app, params->pipeline_id, type,\n+\t\tparams->port);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv4_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_default_ipv4_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv4_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv4_5tuple_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, add_string, \"add\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv4_5tuple_default_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, default_string, \"default\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv4_5tuple_ipv4_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, ipv4_5tuple_string, \"ipv4_5tuple\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_default_ipv4_5tuple_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_ipv4_5tuple_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_add_default_ipv4_5tuple = {\n+\t.f = cmd_fc_add_default_ipv4_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow add default ipv4_5tuple <port>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_p_string,\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_add_string,\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_default_string,\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_ipv4_5tuple_string,\n+\t\t(void *) &cmd_fc_add_default_ipv4_5tuple_port,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow add default ipv6_5tuple\n+ */\n+\n+struct cmd_fc_add_default_ipv6_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t add_string;\n+\tcmdline_fixed_string_t default_string;\n+\tcmdline_fixed_string_t ipv6_5tuple_string;\n+\tuint8_t port;\n+};\n+\n+static void\n+cmd_fc_add_default_ipv6_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_add_default_ipv6_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tenum flow_key_type type;\n+\tint status;\n+\n+\ttype = FLOW_KEY_IPV6_5TUPLE;\n+\tstatus = app_pipeline_fc_add_default(app, params->pipeline_id, type,\n+\t\tparams->port);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv6_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_default_ipv6_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv6_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv6_5tuple_add_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, add_string, \"add\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv6_5tuple_default_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, default_string, \"default\");\n+\n+cmdline_parse_token_string_t cmd_fc_add_default_ipv6_5tuple_ipv6_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, ipv6_5tuple_string, \"ipv6_5tuple\");\n+\n+cmdline_parse_token_num_t cmd_fc_add_default_ipv6_5tuple_port =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_add_default_ipv6_5tuple_result, port, UINT8);\n+\n+cmdline_parse_inst_t cmd_fc_add_default_ipv6_5tuple = {\n+\t.f = cmd_fc_add_default_ipv6_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow add default ipv6_5tuple <port>\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_p_string,\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_add_string,\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_default_string,\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_ipv6_5tuple_string,\n+\t\t(void *) &cmd_fc_add_default_ipv6_5tuple_port,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow del default qinq\n+ */\n+\n+struct cmd_fc_del_default_qinq_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t del_string;\n+\tcmdline_fixed_string_t default_string;\n+\tcmdline_fixed_string_t qinq_string;\n+};\n+\n+static void\n+cmd_fc_del_default_qinq_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_del_default_qinq_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tenum flow_key_type type;\n+\tint status;\n+\n+\ttype = FLOW_KEY_QINQ;\n+\tstatus = app_pipeline_fc_del_default(app, params->pipeline_id, type);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_qinq_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_qinq_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_default_qinq_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_default_qinq_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_qinq_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_qinq_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_qinq_del_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_qinq_result, del_string, \"del\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_qinq_default_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_qinq_result, default_string, \"default\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_qinq_qinq_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_qinq_result, qinq_string, \"qinq\");\n+\n+cmdline_parse_inst_t cmd_fc_del_default_qinq = {\n+\t.f = cmd_fc_del_default_qinq_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow del default qinq\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_del_default_qinq_p_string,\n+\t\t(void *) &cmd_fc_del_default_qinq_pipeline_id,\n+\t\t(void *) &cmd_fc_del_default_qinq_flow_string,\n+\t\t(void *) &cmd_fc_del_default_qinq_del_string,\n+\t\t(void *) &cmd_fc_del_default_qinq_default_string,\n+\t\t(void *) &cmd_fc_del_default_qinq_qinq_string,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow del default ipv4_5tuple\n+ */\n+\n+struct cmd_fc_del_default_ipv4_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t del_string;\n+\tcmdline_fixed_string_t default_string;\n+\tcmdline_fixed_string_t ipv4_5tuple_string;\n+};\n+\n+static void\n+cmd_fc_del_default_ipv4_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_del_default_ipv4_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tenum flow_key_type type;\n+\tint status;\n+\n+\ttype = FLOW_KEY_IPV4_5TUPLE;\n+\tstatus = app_pipeline_fc_del_default(app, params->pipeline_id, type);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv4_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv4_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_default_ipv4_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_default_ipv4_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv4_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv4_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv4_5tuple_del_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv4_5tuple_result, del_string, \"del\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv4_5tuple_default_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv4_5tuple_result, default_string, \"default\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv4_5tuple_ipv4_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv4_5tuple_result, ipv4_5tuple_string, \"ipv4_5tuple\");\n+\n+cmdline_parse_inst_t cmd_fc_del_default_ipv4_5tuple = {\n+\t.f = cmd_fc_del_default_ipv4_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow del default ipv4_5tuple\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_del_default_ipv4_5tuple_p_string,\n+\t\t(void *) &cmd_fc_del_default_ipv4_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_del_default_ipv4_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_del_default_ipv4_5tuple_del_string,\n+\t\t(void *) &cmd_fc_del_default_ipv4_5tuple_default_string,\n+\t\t(void *) &cmd_fc_del_default_ipv4_5tuple_ipv4_5tuple_string,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow del default ipv6_5tuple\n+ */\n+\n+struct cmd_fc_del_default_ipv6_5tuple_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t del_string;\n+\tcmdline_fixed_string_t default_string;\n+\tcmdline_fixed_string_t ipv6_5tuple_string;\n+};\n+\n+static void\n+cmd_fc_del_default_ipv6_5tuple_parsed(\n+\tvoid *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_del_default_ipv6_5tuple_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\tenum flow_key_type type;\n+\tint status;\n+\n+\ttype = FLOW_KEY_IPV6_5TUPLE;\n+\tstatus = app_pipeline_fc_del_default(app, params->pipeline_id, type);\n+\n+\tif(status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv6_5tuple_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv6_5tuple_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_del_default_ipv6_5tuple_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_del_default_ipv6_5tuple_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv6_5tuple_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv6_5tuple_result, flow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv6_5tuple_del_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv6_5tuple_result, del_string, \"del\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv6_5tuple_default_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv6_5tuple_result, default_string, \"default\");\n+\n+cmdline_parse_token_string_t cmd_fc_del_default_ipv6_5tuple_ipv6_5tuple_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_del_default_ipv6_5tuple_result, ipv6_5tuple_string, \"ipv6_5tuple\");\n+\n+cmdline_parse_inst_t cmd_fc_del_default_ipv6_5tuple = {\n+\t.f = cmd_fc_del_default_ipv6_5tuple_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow del default ipv6_5tuple\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_del_default_ipv6_5tuple_p_string,\n+\t\t(void *) &cmd_fc_del_default_ipv6_5tuple_pipeline_id,\n+\t\t(void *) &cmd_fc_del_default_ipv6_5tuple_flow_string,\n+\t\t(void *) &cmd_fc_del_default_ipv6_5tuple_del_string,\n+\t\t(void *) &cmd_fc_del_default_ipv6_5tuple_default_string,\n+\t\t(void *) &cmd_fc_del_default_ipv6_5tuple_ipv6_5tuple_string,\n+\t\tNULL,\n+\t},\n+};\n+\n+/*\n+ * flow ls\n+ */\n+\n+struct cmd_fc_ls_result {\n+\tcmdline_fixed_string_t p_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t flow_string;\n+\tcmdline_fixed_string_t ls_string;\n+};\n+\n+static void\n+cmd_fc_ls_parsed(\n+\tvoid *parsed_result,\n+\t__attribute__((unused)) struct cmdline *cl,\n+\tvoid *data)\n+{\n+\tstruct cmd_fc_ls_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\n+\tapp_pipeline_fc_ls(app, params->pipeline_id);\n }\n+\n+cmdline_parse_token_string_t cmd_fc_ls_p_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_ls_result, p_string, \"p\");\n+\n+cmdline_parse_token_num_t cmd_fc_ls_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_fc_ls_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_fc_ls_flow_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_ls_result,\n+\tflow_string, \"flow\");\n+\n+cmdline_parse_token_string_t cmd_fc_ls_ls_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_fc_ls_result, ls_string,\n+\t\"ls\");\n+\n+cmdline_parse_inst_t cmd_fc_ls = {\n+\t.f = cmd_fc_ls_parsed,\n+\t.data = NULL,\n+\t.help_str = \"p <pipeline_id> flow ls\",\n+\t.tokens = {\n+\t\t(void *) &cmd_fc_ls_p_string,\n+\t\t(void *) &cmd_fc_ls_pipeline_id,\n+\t\t(void *) &cmd_fc_ls_flow_string,\n+\t\t(void *) &cmd_fc_ls_ls_string,\n+\t\tNULL,\n+\t},\n+};\n+\n+static cmdline_parse_ctx_t pipeline_cmds[] = {\n+\t(cmdline_parse_inst_t *) &cmd_fc_add_qinq,\n+\t(cmdline_parse_inst_t *) &cmd_fc_add_ipv4_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_add_ipv6_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_del_qinq,\n+\t(cmdline_parse_inst_t *) &cmd_fc_del_ipv4_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_del_ipv6_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_add_default_qinq,\n+\t(cmdline_parse_inst_t *) &cmd_fc_add_default_ipv4_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_add_default_ipv6_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_del_default_qinq,\n+\t(cmdline_parse_inst_t *) &cmd_fc_del_default_ipv4_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_del_default_ipv6_5tuple,\n+\t(cmdline_parse_inst_t *) &cmd_fc_ls,\n+\tNULL,\n+};\n+\n+static struct pipeline_fe_ops pipeline_flow_classification_fe_ops = {\n+\t.f_init = app_pipeline_fc_init,\n+\t.f_free = app_pipeline_fc_free,\n+\t.cmds = pipeline_cmds,\n+};\n+\n+struct pipeline_type pipeline_flow_classification = {\n+\t.name = \"FLOW_CLASSIF\",\n+\t.ops = &pipeline_flow_classification_ops,\n+\t.fe_ops = &pipeline_flow_classification_fe_ops,\n+};\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.h b/examples/ip_pipeline/pipeline/pipeline_flow_classification.h\nnew file mode 100644\nindex 0000000..3f0b2aa\n--- /dev/null\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.h\n@@ -0,0 +1,41 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 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 __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_H__\n+#define __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_H__\n+\n+#include \"pipeline.h\"\n+\n+extern struct pipeline_type pipeline_flow_classification;\n+\n+#endif\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.c\nnew file mode 100644\nindex 0000000..213894e\n--- /dev/null\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.c\n@@ -0,0 +1,559 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 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+\n+#include <rte_common.h>\n+#include <rte_malloc.h>\n+#include <rte_table_hash.h>\n+#include <rte_byteorder.h>\n+\n+#include \"pipeline_common_ops.h\"\n+#include \"pipeline_flow_classification_ops.h\"\n+\n+enum flow_meter_type {\n+\tMETER_TYPE_SRTCM,\n+\tMETER_TYPE_TRTCM,\n+};\n+\n+struct pipeline_flow_classification {\n+\tstruct pipeline p;\n+\tpipeline_msg_req_handler custom_handlers[PIPELINE_FC_MSG_REQS];\n+\n+\tuint32_t n_flows;\n+\tuint32_t key_offset;\n+\tuint32_t key_size;\n+\tuint32_t hash_offset;\n+\tuint32_t flow_id_offset;\n+\tuint32_t flow_stats;\n+\tuint32_t color_offset;\n+\tuint32_t input_color_offset;\n+\tenum flow_meter_type meter_type;\n+} __rte_cache_aligned;\n+\n+static void *\n+pipeline_fc_msg_req_custom_handler(struct pipeline *p, void *msg);\n+\n+static pipeline_msg_req_handler handlers[] = {\n+\t[PIPELINE_MSG_REQ_PING] = pipeline_msg_req_ping_handler,\n+\t[PIPELINE_MSG_REQ_STATS_PORT_IN] = pipeline_msg_req_stats_port_in_handler,\n+\t[PIPELINE_MSG_REQ_STATS_PORT_OUT] = pipeline_msg_req_stats_port_out_handler,\n+\t[PIPELINE_MSG_REQ_STATS_TABLE] = pipeline_msg_req_stats_table_handler,\n+\t[PIPELINE_MSG_REQ_PORT_IN_ENABLE] = pipeline_msg_req_port_in_enable_handler,\n+\t[PIPELINE_MSG_REQ_PORT_IN_DISABLE] = pipeline_msg_req_port_in_disable_handler,\n+\t[PIPELINE_MSG_REQ_CUSTOM] = pipeline_fc_msg_req_custom_handler,\n+};\n+\n+static void *\n+pipeline_fc_msg_req_add_handler(struct pipeline *p, void *msg);\n+\n+static void *\n+pipeline_fc_msg_req_del_handler(struct pipeline *p, void *msg);\n+\n+static void *\n+pipeline_fc_msg_req_add_default_handler(struct pipeline *p, void *msg);\n+\n+static void *\n+pipeline_fc_msg_req_del_default_handler(struct pipeline *p, void *msg);\n+\n+static void *\n+pipeline_fc_msg_req_add_all_handler(struct pipeline *p, void *msg);\n+\n+static void *\n+pipeline_fc_msg_req_meter_handler(struct pipeline *p, void *msg);\n+\n+static void *\n+pipeline_fc_msg_req_ls_handler(struct pipeline *p, void *msg);\n+\n+static pipeline_msg_req_handler custom_handlers[] = {\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_ADD] = pipeline_fc_msg_req_add_handler,\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_DEL] = pipeline_fc_msg_req_del_handler,\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT] = pipeline_fc_msg_req_add_default_handler,\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT] = pipeline_fc_msg_req_del_default_handler,\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_ADD_ALL] = pipeline_fc_msg_req_add_all_handler,\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_METER] = pipeline_fc_msg_req_meter_handler,\n+\t\t[PIPELINE_FC_MSG_REQ_FLOW_LS] = pipeline_fc_msg_req_ls_handler,\n+};\n+\n+static uint64_t\n+test_hash(\n+\tvoid *key,\n+\t__attribute__((unused)) uint32_t key_size,\n+\t__attribute__((unused)) uint64_t seed)\n+{\n+\tuint32_t *k32 = (uint32_t *) key;\n+\tuint32_t ip_dst = rte_be_to_cpu_32(k32[0]);\n+\tuint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);\n+\n+\treturn signature;\n+}\n+\n+static int\n+pipeline_fc_parse_args(struct pipeline_flow_classification *p,\n+\tstruct pipeline_params *params)\n+{\n+\tuint32_t n_flows_present = 0;\n+\tuint32_t key_offset_present = 0;\n+\tuint32_t key_size_present = 0;\n+\tuint32_t hash_offset_present = 0;\n+\tuint32_t flow_id_offset_present = 0;\n+\tuint32_t flow_stats_present = 0;\n+\tuint32_t color_offset_present = 0;\n+\tuint32_t input_color_offset_present = 0;\n+\tuint32_t meter_type_present = 0;\n+\n+\tuint32_t i;\n+\n+\tfor (i = 0; i < params->n_args; i++) {\n+\t\tchar *arg_name = params->args_name[i];\n+\t\tchar *arg_value = params->args_value[i];\n+\n+\t\tif (strcmp(arg_name, \"n_flows\") == 0) {\n+\t\t\tif (n_flows_present)\n+\t\t\t\treturn -1;\n+\t\t\tn_flows_present = 1;\n+\n+\t\t\tp->n_flows = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"key_offset\") == 0) {\n+\t\t\tif (key_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\tkey_offset_present = 1;\n+\n+\t\t\tp->key_offset = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"key_size\") == 0) {\n+\t\t\tif (key_size_present)\n+\t\t\t\treturn -1;\n+\t\t\tkey_size_present = 1;\n+\n+\t\t\tp->key_size = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"hash_offset\") == 0) {\n+\t\t\tif (hash_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\thash_offset_present = 1;\n+\n+\t\t\tp->hash_offset = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"flow_id_offset\") == 0) {\n+\t\t\tif (flow_id_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\tflow_id_offset_present = 1;\n+\n+\t\t\tp->flow_id_offset = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"flow_stats\") == 0) {\n+\t\t\tif (flow_stats_present)\n+\t\t\t\treturn -1;\n+\t\t\tflow_stats_present = 1;\n+\n+\t\t\tif (strcmp(arg_value, \"off\") == 0)\n+\t\t\t\tp->flow_stats = 0;\n+\t\t\telse if (strcmp(arg_value, \"on\") == 0)\n+\t\t\t\tp->flow_stats = 1;\n+\t\t\telse\n+\t\t\t\treturn -1;\n+\t\t} else if (strcmp(arg_name, \"color_offset\") == 0) {\n+\t\t\tif (color_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\tcolor_offset_present = 1;\n+\n+\t\t\tp->color_offset = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"input_color_offset\") == 0) {\n+\t\t\tif (input_color_offset_present)\n+\t\t\t\treturn -1;\n+\t\t\tinput_color_offset_present = 1;\n+\n+\t\t\tp->input_color_offset = atoi(arg_value);\n+\t\t} else if (strcmp(arg_name, \"meter_type\") == 0) {\n+\t\t\tif (meter_type_present)\n+\t\t\t\treturn -1;\n+\t\t\tmeter_type_present = 1;\n+\n+\t\t\tif (strcmp(arg_value, \"srtcm\") == 0)\n+\t\t\t\tp->meter_type = METER_TYPE_SRTCM;\n+\t\t\telse if (strcmp(arg_value, \"trtcm\") == 0)\n+\t\t\t\tp->meter_type = METER_TYPE_TRTCM;\n+\t\t\telse\n+\t\t\t\treturn -1;\n+\t\t} else {\n+\t\t\t/* Unknown command */\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void * pipeline_init(struct pipeline_params *params,\n+\t__rte_unused void *arg)\n+{\n+\tstruct pipeline *p;\n+\tstruct pipeline_flow_classification *p_fc;\n+\tuint32_t size, i;\n+\n+\t/* Check input arguments */\n+\tif (params == NULL)\n+\t\treturn NULL;\n+\n+\t/* Memory allocation */\n+\tsize = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_flow_classification));\n+\tp_fc = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);\n+\tif (p_fc == NULL)\n+\t\treturn NULL;\n+\tp = &p_fc->p;\n+\n+\tstrcpy(p->name, params->name);\n+\n+\t/* Parse arguments */\n+\tif (pipeline_fc_parse_args(p_fc, params))\n+\t\treturn NULL;\n+\n+\t/* Pipeline */\n+\t{\n+\t\tstruct rte_pipeline_params pipeline_params = {\n+\t\t\t.name = \"FLOW_CLASSIF\",\n+\t\t\t.socket_id = params->socket_id,\n+\t\t\t.offset_port_id = 0,\n+\t\t};\n+\n+\t\tp->p = rte_pipeline_create(&pipeline_params);\n+\t\tif (p->p == NULL) {\n+\t\t\trte_free(p);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\t/* Input ports */\n+\tp->n_ports_in = params->n_ports_in;\n+\tfor (i = 0; i < p->n_ports_in; i++) {\n+\t\tstruct rte_pipeline_port_in_params port_params = {\n+\t\t\t.ops = pipeline_port_in_params_get_ops(&params->port_in[i]),\n+\t\t\t.arg_create = pipeline_port_in_params_convert(&params->port_in[i]),\n+\t\t\t.f_action = NULL,\n+\t\t\t.arg_ah = NULL,\n+\t\t\t.burst_size = params->port_in[i].burst_size,\n+\t\t};\n+\n+\t\tint status = rte_pipeline_port_in_create(p->p,\n+\t\t\t&port_params,\n+\t\t\t&p->port_in_id[i]);\n+\n+\t\tif (status) {\n+\t\t\trte_pipeline_free(p->p);\n+\t\t\trte_free(p);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\t/* Output ports */\n+\tp->n_ports_out = params->n_ports_out;\n+\tfor (i = 0; i < p->n_ports_out; i++) {\n+\t\tstruct rte_pipeline_port_out_params port_params = {\n+\t\t\t.ops = pipeline_port_out_params_get_ops(&params->port_out[i]),\n+\t\t\t.arg_create = pipeline_port_out_params_convert(&params->port_out[i]),\n+\t\t\t.f_action = NULL,\n+\t\t\t.f_action_bulk = NULL,\n+\t\t\t.arg_ah = NULL,\n+\t\t};\n+\n+\t\tint status = rte_pipeline_port_out_create(p->p,\n+\t\t\t&port_params,\n+\t\t\t&p->port_out_id[i]);\n+\n+\t\tif (status) {\n+\t\t\trte_pipeline_free(p->p);\n+\t\t\trte_free(p);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\t/* Tables */\n+\t{\n+\t\tp->n_tables = 1;\n+\t\tstruct rte_table_hash_key8_ext_params table_hash_params = {\n+\t\t\t\t.n_entries = p_fc->n_flows,\n+\t\t\t\t.n_entries_ext = 1,\n+\t\t\t\t.signature_offset = 0,\n+\t\t\t\t.key_offset = p_fc->key_offset,\n+\t\t\t\t.f_hash = &test_hash,\n+\t\t\t\t.seed = 0,\n+\t\t};\n+\n+\t\tstruct rte_pipeline_table_params table_params = {\n+\t\t\t.ops = &rte_table_hash_key8_ext_ops,\n+\t\t\t.arg_create = &table_hash_params,\n+\t\t\t.f_action_hit = NULL,\n+\t\t\t.f_action_miss = NULL,\n+\t\t\t.arg_ah = NULL,\n+\t\t\t.action_data_size = 0,\n+\t\t};\n+\n+\t\tint status = rte_pipeline_table_create(p->p,\n+\t\t\t&table_params,\n+\t\t\t&p->table_id[0]);\n+\n+\n+\t\tif (status) {\n+\t\t\trte_pipeline_free(p->p);\n+\t\t\trte_free(p);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\t/* Connecting input ports to tables */\n+\tfor (i = 0; i < p->n_ports_in; i++) {\n+\t\tint status = rte_pipeline_port_in_connect_to_table(p->p,\n+\t\t\tp->port_in_id[i],\n+\t\t\tp->table_id[0]);\n+\n+\t\tif (status) {\n+\t\t\trte_pipeline_free(p->p);\n+\t\t\trte_free(p);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\t/* Enable input ports */\n+\tfor (i = 0; i < p->n_ports_in; i++) {\n+\t\tint status = rte_pipeline_port_in_enable(p->p,\n+\t\t\tp->port_in_id[i]);\n+\n+\t\tif (status) {\n+\t\t\trte_pipeline_free(p->p);\n+\t\t\trte_free(p);\n+\t\t\treturn NULL;\n+\t\t}\n+\t}\n+\n+\t/* Check pipeline consistency */\n+\tif (rte_pipeline_check(p->p) < 0) {\n+\t\trte_pipeline_free(p->p);\n+\t\trte_free(p);\n+\t\treturn NULL;\n+\t}\n+\n+\t/* Message queues */\n+\tp->n_msgq = params->n_msgq;\n+\tfor (i = 0; i < p->n_msgq; i++)\n+\t\tp->msgq_in[i] = params->msgq_in[i];\n+\tfor (i = 0; i < p->n_msgq; i++)\n+\t\tp->msgq_out[i] = params->msgq_out[i];\n+\n+\t/* Message handlers */\n+\tmemcpy(p->handlers, handlers, sizeof(p->handlers));\n+\tmemcpy(p_fc->custom_handlers,\n+\t\tcustom_handlers,\n+\t\tsizeof(p_fc->custom_handlers));\n+\n+\treturn p;\n+}\n+\n+static int\n+pipeline_free(void *pipeline)\n+{\n+\tstruct pipeline *p = (struct pipeline *) pipeline;\n+\n+\t/* Check input arguments */\n+\tif (p == NULL)\n+\t\treturn -1;\n+\n+\t/* Free resources */\n+\trte_pipeline_free(p->p);\n+\trte_free(p);\n+\treturn 0;\n+}\n+\n+static int\n+pipeline_timer(void *pipeline)\n+{\n+\tstruct pipeline *p = (struct pipeline *) pipeline;\n+\n+\tpipeline_msg_req_handle(p);\n+\trte_pipeline_flush(p->p);\n+\n+\treturn 0;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_custom_handler(struct pipeline *p, void *msg)\n+{\n+\tstruct pipeline_flow_classification *p_fc =\n+\t\t\t(struct pipeline_flow_classification *) p;\n+\tstruct pipeline_custom_msg_req *req = msg;\n+\tpipeline_msg_req_handler f_handle;\n+\n+\tf_handle = (req->subtype < PIPELINE_FC_MSG_REQS)?\n+\t\tp_fc->custom_handlers[req->subtype] :\n+\t\tpipeline_msg_req_invalid_handler;\n+\n+\tif (f_handle == NULL)\n+\t\tf_handle = pipeline_msg_req_invalid_handler;\n+\n+\treturn f_handle(p, req);\n+}\n+\n+static void *\n+pipeline_fc_msg_req_add_handler(struct pipeline *p, void *msg)\n+{\n+\tstruct pipeline_fc_add_msg_req *req = msg;\n+\tstruct pipeline_fc_add_msg_rsp *rsp = msg;\n+\n+\tstruct rte_pipeline_table_entry entry = {\n+\t\t.action = RTE_PIPELINE_ACTION_PORT,\n+\t\t{.port_id = p->port_out_id[req->port_id]},\n+\t};\n+\n+\tswitch (req->key.type) {\n+\t\tcase FLOW_KEY_QINQ: {\n+\t\t\tuint64_t svlan = req->key.key.qinq.svlan;\n+\t\t\tuint64_t cvlan = req->key.key.qinq.cvlan;\n+\t\t\tuint64_t key = rte_bswap64((svlan << 48) | (cvlan << 16));\n+\n+\t\trsp->status = rte_pipeline_table_entry_add(p->p, p->table_id[0], &key,\n+\t\t\t\t&entry, &rsp->key_found,\n+\t\t\t\t(struct rte_pipeline_table_entry **) &rsp->entry_ptr);\n+\t\tbreak;\n+\t\t}\n+\t\tcase FLOW_KEY_IPV4_5TUPLE: {\n+\t\trsp->status = rte_pipeline_table_entry_add(p->p, p->table_id[0],\n+\t\t\t\treq->key.key.raw, &entry, &rsp->key_found,\n+\t\t\t\t(struct rte_pipeline_table_entry **) &rsp->entry_ptr);\n+\t\tbreak;\n+\t\t}\n+\t\tcase FLOW_KEY_IPV6_5TUPLE: {\n+\t\trsp->status = rte_pipeline_table_entry_add(p->p, p->table_id[0],\n+\t\t\t\treq->key.key.raw, &entry, &rsp->key_found,\n+\t\t\t\t(struct rte_pipeline_table_entry **) &rsp->entry_ptr);\n+\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tRTE_LOG(INFO, USER1, \"%s Back-End: Key %s\\n\",\n+\t\tp->name,\n+\t\t(rsp->key_found)? \"found\" : \"not found\");\n+\n+\treturn rsp;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_del_handler(struct pipeline *p, void *msg)\n+{\n+\tstruct pipeline_fc_del_msg_req *req = msg;\n+\tstruct pipeline_fc_del_msg_rsp *rsp = msg;\n+\n+\tswitch (req->key.type) {\n+\t\tcase FLOW_KEY_QINQ: {\n+\t\t\tuint64_t svlan = req->key.key.qinq.svlan;\n+\t\t\tuint64_t cvlan = req->key.key.qinq.cvlan;\n+\t\t\tuint64_t key = rte_bswap64((svlan << 48) | (cvlan << 16));\n+\n+\t\t\trsp->status = rte_pipeline_table_entry_delete(p->p, p->table_id[0],\n+\t\t\t\t\t&key, &rsp->key_found, NULL);\n+\t\t\tbreak;\n+\t\t}\n+\t\tcase FLOW_KEY_IPV4_5TUPLE: {\n+\t\t\trsp->status = rte_pipeline_table_entry_delete(p->p, p->table_id[0],\n+\t\t\t\treq->key.key.raw, &rsp->key_found, NULL);\n+\t\t\tbreak;\n+\t\t}\n+\t\tcase FLOW_KEY_IPV6_5TUPLE: {\n+\t\t\trsp->status = rte_pipeline_table_entry_delete(p->p, p->table_id[0],\n+\t\t\t\treq->key.key.raw, &rsp->key_found, NULL);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tRTE_LOG(INFO, USER1, \"%s Back-End: Key %s\\n\",\n+\t\tp->name,\n+\t\t(rsp->key_found)? \"found\" : \"not found\");\n+\n+\treturn rsp;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_add_default_handler(struct pipeline *p, void *msg)\n+{\n+\tstruct pipeline_fc_add_default_msg_req *req = msg;\n+\tstruct pipeline_fc_add_default_msg_rsp *rsp = msg;\n+\n+\tstruct rte_pipeline_table_entry default_entry = {\n+\t\t.action = RTE_PIPELINE_ACTION_PORT,\n+\t\t{.port_id = p->port_out_id[req->port_id]},\n+\t};\n+\n+\trsp->status = rte_pipeline_table_default_entry_add(p->p, p->table_id[0],\n+\t\t\t&default_entry,\n+\t\t\t(struct rte_pipeline_table_entry **) &rsp->default_entry_ptr);\n+\n+\treturn rsp;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_del_default_handler(struct pipeline *p, void *msg)\n+{\n+\tstruct pipeline_fc_del_default_msg_rsp *rsp = msg;\n+\n+\trsp->status = rte_pipeline_table_default_entry_delete(p->p,\n+\t\tp->table_id[0], NULL);\n+\n+\treturn rsp;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_add_all_handler(struct pipeline *p, void *msg)\n+{\n+\t(void) p;\n+\t(void) msg;\n+\treturn NULL;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_meter_handler(struct pipeline *p, void *msg)\n+{\n+\t(void) p;\n+\t(void) msg;\n+\treturn NULL;\n+}\n+\n+static void *\n+pipeline_fc_msg_req_ls_handler(struct pipeline *p, void *msg)\n+{\n+\t(void) p;\n+\t(void) msg;\n+\treturn NULL;\n+}\n+\n+struct pipeline_ops pipeline_flow_classification_ops = {\n+\t\t.f_init = pipeline_init,\n+\t\t.f_free = pipeline_free,\n+\t\t.f_run = NULL,\n+\t\t.f_timer = pipeline_timer,\n+\t\t.f_track = NULL,\n+};\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.h b/examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.h\nnew file mode 100644\nindex 0000000..a3f9b00\n--- /dev/null\n+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_ops.h\n@@ -0,0 +1,150 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 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 __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_OPS_H__\n+#define __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_OPS_H__\n+\n+#include \"pipeline.h\"\n+#include \"pipeline_common.h\"\n+\n+enum pipeline_fc_msg_req_type {\n+\tPIPELINE_FC_MSG_REQ_FLOW_ADD = 0,\n+\tPIPELINE_FC_MSG_REQ_FLOW_DEL,\n+\tPIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT,\n+\tPIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT,\n+\tPIPELINE_FC_MSG_REQ_FLOW_ADD_ALL,\n+\tPIPELINE_FC_MSG_REQ_FLOW_METER,\n+\tPIPELINE_FC_MSG_REQ_FLOW_LS,\n+\tPIPELINE_FC_MSG_REQS,\n+};\n+\n+enum flow_key_type {\n+\tFLOW_KEY_QINQ,\n+\tFLOW_KEY_IPV4_5TUPLE,\n+\tFLOW_KEY_IPV6_5TUPLE,\n+};\n+\n+struct flow_key_qinq {\n+\tuint16_t svlan;\n+\tuint16_t cvlan;\n+};\n+\n+struct flow_key_ipv4_5tuple {\n+\tuint32_t ip_src;\n+\tuint32_t ip_dst;\n+\tuint16_t port_src;\n+\tuint16_t port_dst;\n+\tuint32_t proto;\n+};\n+\n+struct flow_key_ipv6_5tuple {\n+\tuint8_t ip_src[16];\n+\tuint8_t ip_dst[16];\n+\tuint16_t port_src;\n+\tuint16_t port_dst;\n+\tuint32_t proto;\n+};\n+\n+struct pipeline_fc_key {\n+\tenum flow_key_type type;\n+\tunion {\n+\t\tstruct flow_key_qinq qinq;\n+\t\tstruct flow_key_ipv4_5tuple ipv4_5tuple;\n+\t\tstruct flow_key_ipv6_5tuple ipv6_5tuple;\n+\t\tuint8_t raw[40];\n+\t} key;\n+};\n+\n+/*\n+ * MSG ADD\n+ */\n+struct pipeline_fc_add_msg_req {\n+\tenum pipeline_msg_req_type type;\n+\tenum pipeline_fc_msg_req_type subtype;\n+\n+\tstruct pipeline_fc_key key;\n+\n+\tuint32_t port_id;\n+};\n+\n+struct pipeline_fc_add_msg_rsp {\n+\tint status;\n+\tint key_found;\n+\tvoid *entry_ptr;\n+};\n+\n+/*\n+ * MSG DEL\n+ */\n+struct pipeline_fc_del_msg_req {\n+\tenum pipeline_msg_req_type type;\n+\tenum pipeline_fc_msg_req_type subtype;\n+\n+\tstruct pipeline_fc_key key;\n+};\n+\n+struct pipeline_fc_del_msg_rsp {\n+\tint status;\n+\tint key_found;\n+};\n+\n+/*\n+ * MSG ADD DEFAULT\n+ */\n+struct pipeline_fc_add_default_msg_req {\n+\tenum pipeline_msg_req_type type;\n+\tenum pipeline_fc_msg_req_type subtype;\n+\n+\tuint32_t port_id;\n+};\n+\n+struct pipeline_fc_add_default_msg_rsp {\n+\tint status;\n+\tvoid *default_entry_ptr;\n+};\n+\n+/*\n+ * MSG DEL DEFAULT\n+ */\n+struct pipeline_fc_del_default_msg_req {\n+\tenum pipeline_msg_req_type type;\n+\tenum pipeline_fc_msg_req_type subtype;\n+};\n+\n+struct pipeline_fc_del_default_msg_rsp {\n+\tint status;\n+};\n+\n+extern struct pipeline_ops pipeline_flow_classification_ops;\n+\n+#endif\n",
    "prefixes": [
        "dpdk-dev",
        "11/11"
    ]
}