get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 115732,
    "url": "http://patchwork.dpdk.org/api/patches/115732/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20220901142041.2628537-8-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20220901142041.2628537-8-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220901142041.2628537-8-cristian.dumitrescu@intel.com",
    "date": "2022-09-01T14:20:27",
    "name": "[V3,07/21] net/softnic: replace the legacy pipeline with the SWX pipeline",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "130db59de3bb4ec8d99b3c78576d8e63c1c97b40",
    "submitter": {
        "id": 19,
        "url": "http://patchwork.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20220901142041.2628537-8-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 24503,
            "url": "http://patchwork.dpdk.org/api/series/24503/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=24503",
            "date": "2022-09-01T14:20:20",
            "name": "net/softnic: replace the legacy pipeline with SWX pipeline",
            "version": 3,
            "mbox": "http://patchwork.dpdk.org/series/24503/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/115732/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/115732/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B3AAEA0032;\n\tThu,  1 Sep 2022 16:22:00 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 5012C42B88;\n\tThu,  1 Sep 2022 16:21:12 +0200 (CEST)",
            "from mga06.intel.com (mga06b.intel.com [134.134.136.31])\n by mails.dpdk.org (Postfix) with ESMTP id F0A5A4280B\n for <dev@dpdk.org>; Thu,  1 Sep 2022 16:21:06 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 01 Sep 2022 07:20:50 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com.) ([10.237.223.157])\n by fmsmga004.fm.intel.com with ESMTP; 01 Sep 2022 07:20:49 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1662042067; x=1693578067;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=aSGoQDo0ZaSICL8ssWK4ejiXpJSJjBRJMT0Tiwv2XJk=;\n b=TSctw3LlQic6MB8Slp+/H3awUpg7U/2sEfyUYcmYPFgZFgukUzfYyW10\n k3sGBeMXfLrxrD1QmGmSazsXBYoxQsD7raqDh0IZLFUyrF2sFFlVwq9SV\n B62E6k0vJvpO51taqOifun1v8+AfGXb02mZq0zR3vJoiLPxDxjK4KCcmn\n nDOPJ5SNHFgLGf8R2tOfpXP7pKsCP5SFVbXyPBsk0OSXuk4kGzNUWwAhl\n jekjwCZ5gbBw6MfnZpSHv+2IkyIF8Gxewh48kANk+vhXY+2Pc0jDHaRlt\n /r6wG27MrCgrsvWh2sfcTzH0VYgEb3HpWxKwJhsUPDkxmQxsIelL8RxKc A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10457\"; a=\"357444039\"",
            "E=Sophos;i=\"5.93,281,1654585200\"; d=\"scan'208\";a=\"357444039\"",
            "E=Sophos;i=\"5.93,281,1654585200\"; d=\"scan'208\";a=\"680870180\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Yogesh Jangra <yogesh.jangra@intel.com>",
        "Subject": "[PATCH V3 07/21] net/softnic: replace the legacy pipeline with the\n SWX pipeline",
        "Date": "Thu,  1 Sep 2022 14:20:27 +0000",
        "Message-Id": "<20220901142041.2628537-8-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20220901142041.2628537-1-cristian.dumitrescu@intel.com>",
        "References": "<20220804165839.1074817-1-cristian.dumitrescu@intel.com>\n <20220901142041.2628537-1-cristian.dumitrescu@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Replace the legacy pipeline support with support for the SWX pipeline.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\nSigned-off-by: Yogesh Jangra <yogesh.jangra@intel.com>\n---\n drivers/net/softnic/meson.build               |    1 -\n drivers/net/softnic/rte_eth_softnic.c         |    6 -\n drivers/net/softnic/rte_eth_softnic_action.c  |  423 ---\n drivers/net/softnic/rte_eth_softnic_cli.c     |   16 +-\n .../net/softnic/rte_eth_softnic_internals.h   |  502 +---\n .../net/softnic/rte_eth_softnic_pipeline.c    |  988 +------\n drivers/net/softnic/rte_eth_softnic_thread.c  | 2594 +----------------\n 7 files changed, 216 insertions(+), 4314 deletions(-)\n delete mode 100644 drivers/net/softnic/rte_eth_softnic_action.c",
    "diff": "diff --git a/drivers/net/softnic/meson.build b/drivers/net/softnic/meson.build\nindex 91f1f3220f..f0cfc6dc17 100644\n--- a/drivers/net/softnic/meson.build\n+++ b/drivers/net/softnic/meson.build\n@@ -10,7 +10,6 @@ sources = files(\n         'conn.c',\n         'parser.c',\n         'rte_eth_softnic.c',\n-        'rte_eth_softnic_action.c',\n         'rte_eth_softnic_cli.c',\n         'rte_eth_softnic_link.c',\n         'rte_eth_softnic_mempool.c',\ndiff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c\nindex eb97ae7185..a940952c7a 100644\n--- a/drivers/net/softnic/rte_eth_softnic.c\n+++ b/drivers/net/softnic/rte_eth_softnic.c\n@@ -160,8 +160,6 @@ pmd_dev_stop(struct rte_eth_dev *dev)\n \t/* Firmware */\n \tsoftnic_pipeline_disable_all(p);\n \tsoftnic_pipeline_free(p);\n-\tsoftnic_table_action_profile_free(p);\n-\tsoftnic_port_in_action_profile_free(p);\n \tsoftnic_link_free(p);\n \tsoftnic_softnic_swq_free_keep_rxq_txq(p);\n \tsoftnic_mempool_free(p);\n@@ -180,8 +178,6 @@ pmd_free(struct pmd_internals *p)\n \n \tsoftnic_thread_free(p);\n \tsoftnic_pipeline_free(p);\n-\tsoftnic_table_action_profile_free(p);\n-\tsoftnic_port_in_action_profile_free(p);\n \tsoftnic_link_free(p);\n \tsoftnic_swq_free(p);\n \tsoftnic_mempool_free(p);\n@@ -261,8 +257,6 @@ pmd_init(struct pmd_params *params)\n \tsoftnic_mempool_init(p);\n \tsoftnic_swq_init(p);\n \tsoftnic_link_init(p);\n-\tsoftnic_port_in_action_profile_init(p);\n-\tsoftnic_table_action_profile_init(p);\n \tsoftnic_pipeline_init(p);\n \n \tstatus = softnic_thread_init(p);\ndiff --git a/drivers/net/softnic/rte_eth_softnic_action.c b/drivers/net/softnic/rte_eth_softnic_action.c\ndeleted file mode 100644\nindex 33be9552a6..0000000000\n--- a/drivers/net/softnic/rte_eth_softnic_action.c\n+++ /dev/null\n@@ -1,423 +0,0 @@\n-/* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2010-2018 Intel Corporation\n- */\n-\n-#include <stdint.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-#include <rte_string_fns.h>\n-#include <rte_table_hash_func.h>\n-\n-#include \"rte_eth_softnic_internals.h\"\n-\n-/**\n- * Input port\n- */\n-int\n-softnic_port_in_action_profile_init(struct pmd_internals *p)\n-{\n-\tTAILQ_INIT(&p->port_in_action_profile_list);\n-\n-\treturn 0;\n-}\n-\n-void\n-softnic_port_in_action_profile_free(struct pmd_internals *p)\n-{\n-\tfor ( ; ; ) {\n-\t\tstruct softnic_port_in_action_profile *profile;\n-\n-\t\tprofile = TAILQ_FIRST(&p->port_in_action_profile_list);\n-\t\tif (profile == NULL)\n-\t\t\tbreak;\n-\n-\t\tTAILQ_REMOVE(&p->port_in_action_profile_list, profile, node);\n-\t\tfree(profile);\n-\t}\n-}\n-\n-struct softnic_port_in_action_profile *\n-softnic_port_in_action_profile_find(struct pmd_internals *p,\n-\tconst char *name)\n-{\n-\tstruct softnic_port_in_action_profile *profile;\n-\n-\tif (name == NULL)\n-\t\treturn NULL;\n-\n-\tTAILQ_FOREACH(profile, &p->port_in_action_profile_list, node)\n-\t\tif (strcmp(profile->name, name) == 0)\n-\t\t\treturn profile;\n-\n-\treturn NULL;\n-}\n-\n-struct softnic_port_in_action_profile *\n-softnic_port_in_action_profile_create(struct pmd_internals *p,\n-\tconst char *name,\n-\tstruct softnic_port_in_action_profile_params *params)\n-{\n-\tstruct softnic_port_in_action_profile *profile;\n-\tstruct rte_port_in_action_profile *ap;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (name == NULL ||\n-\t\tsoftnic_port_in_action_profile_find(p, name) ||\n-\t\tparams == NULL)\n-\t\treturn NULL;\n-\n-\tif ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&\n-\t\tparams->lb.f_hash == NULL) {\n-\t\tswitch (params->lb.key_size) {\n-\t\tcase  8:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key8;\n-\t\t\tbreak;\n-\n-\t\tcase 16:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key16;\n-\t\t\tbreak;\n-\n-\t\tcase 24:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key24;\n-\t\t\tbreak;\n-\n-\t\tcase 32:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key32;\n-\t\t\tbreak;\n-\n-\t\tcase 40:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key40;\n-\t\t\tbreak;\n-\n-\t\tcase 48:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key48;\n-\t\t\tbreak;\n-\n-\t\tcase 56:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key56;\n-\t\t\tbreak;\n-\n-\t\tcase 64:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key64;\n-\t\t\tbreak;\n-\n-\t\tdefault:\n-\t\t\treturn NULL;\n-\t\t}\n-\n-\t\tparams->lb.seed = 0;\n-\t}\n-\n-\t/* Resource */\n-\tap = rte_port_in_action_profile_create(0);\n-\tif (ap == NULL)\n-\t\treturn NULL;\n-\n-\tif (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {\n-\t\tstatus = rte_port_in_action_profile_action_register(ap,\n-\t\t\tRTE_PORT_IN_ACTION_FLTR,\n-\t\t\t&params->fltr);\n-\n-\t\tif (status) {\n-\t\t\trte_port_in_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {\n-\t\tstatus = rte_port_in_action_profile_action_register(ap,\n-\t\t\tRTE_PORT_IN_ACTION_LB,\n-\t\t\t&params->lb);\n-\n-\t\tif (status) {\n-\t\t\trte_port_in_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tstatus = rte_port_in_action_profile_freeze(ap);\n-\tif (status) {\n-\t\trte_port_in_action_profile_free(ap);\n-\t\treturn NULL;\n-\t}\n-\n-\t/* Node allocation */\n-\tprofile = calloc(1, sizeof(struct softnic_port_in_action_profile));\n-\tif (profile == NULL) {\n-\t\trte_port_in_action_profile_free(ap);\n-\t\treturn NULL;\n-\t}\n-\n-\t/* Node fill in */\n-\tstrlcpy(profile->name, name, sizeof(profile->name));\n-\tmemcpy(&profile->params, params, sizeof(*params));\n-\tprofile->ap = ap;\n-\n-\t/* Node add to list */\n-\tTAILQ_INSERT_TAIL(&p->port_in_action_profile_list, profile, node);\n-\n-\treturn profile;\n-}\n-\n-/**\n- * Table\n- */\n-int\n-softnic_table_action_profile_init(struct pmd_internals *p)\n-{\n-\tTAILQ_INIT(&p->table_action_profile_list);\n-\n-\treturn 0;\n-}\n-\n-void\n-softnic_table_action_profile_free(struct pmd_internals *p)\n-{\n-\tfor ( ; ; ) {\n-\t\tstruct softnic_table_action_profile *profile;\n-\n-\t\tprofile = TAILQ_FIRST(&p->table_action_profile_list);\n-\t\tif (profile == NULL)\n-\t\t\tbreak;\n-\n-\t\tTAILQ_REMOVE(&p->table_action_profile_list, profile, node);\n-\t\trte_table_action_profile_free(profile->ap);\n-\t\tfree(profile);\n-\t}\n-}\n-\n-struct softnic_table_action_profile *\n-softnic_table_action_profile_find(struct pmd_internals *p,\n-\tconst char *name)\n-{\n-\tstruct softnic_table_action_profile *profile;\n-\n-\tif (name == NULL)\n-\t\treturn NULL;\n-\n-\tTAILQ_FOREACH(profile, &p->table_action_profile_list, node)\n-\t\tif (strcmp(profile->name, name) == 0)\n-\t\t\treturn profile;\n-\n-\treturn NULL;\n-}\n-\n-struct softnic_table_action_profile *\n-softnic_table_action_profile_create(struct pmd_internals *p,\n-\tconst char *name,\n-\tstruct softnic_table_action_profile_params *params)\n-{\n-\tstruct softnic_table_action_profile *profile;\n-\tstruct rte_table_action_profile *ap;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (name == NULL ||\n-\t\tsoftnic_table_action_profile_find(p, name) ||\n-\t\tparams == NULL ||\n-\t\t((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))\n-\t\treturn NULL;\n-\n-\tif ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&\n-\t\tparams->lb.f_hash == NULL) {\n-\t\tswitch (params->lb.key_size) {\n-\t\tcase 8:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key8;\n-\t\t\tbreak;\n-\n-\t\tcase 16:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key16;\n-\t\t\tbreak;\n-\n-\t\tcase 24:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key24;\n-\t\t\tbreak;\n-\n-\t\tcase 32:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key32;\n-\t\t\tbreak;\n-\n-\t\tcase 40:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key40;\n-\t\t\tbreak;\n-\n-\t\tcase 48:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key48;\n-\t\t\tbreak;\n-\n-\t\tcase 56:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key56;\n-\t\t\tbreak;\n-\n-\t\tcase 64:\n-\t\t\tparams->lb.f_hash = rte_table_hash_crc_key64;\n-\t\t\tbreak;\n-\n-\t\tdefault:\n-\t\t\treturn NULL;\n-\t\t}\n-\n-\t\tparams->lb.seed = 0;\n-\t}\n-\n-\t/* Resource */\n-\tap = rte_table_action_profile_create(&params->common);\n-\tif (ap == NULL)\n-\t\treturn NULL;\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_FWD,\n-\t\t\tNULL);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_LB,\n-\t\t\t&params->lb);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_MTR,\n-\t\t\t&params->mtr);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_TM,\n-\t\t\t&params->tm);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_ENCAP,\n-\t\t\t&params->encap);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_NAT,\n-\t\t\t&params->nat);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_TTL,\n-\t\t\t&params->ttl);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_STATS,\n-\t\t\t&params->stats);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_TIME,\n-\t\t\tNULL);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_TAG,\n-\t\t\tNULL);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_DECAP,\n-\t\t\tNULL);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tif (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {\n-\t\tstatus = rte_table_action_profile_action_register(ap,\n-\t\t\tRTE_TABLE_ACTION_SYM_CRYPTO,\n-\t\t\t&params->sym_crypto);\n-\n-\t\tif (status) {\n-\t\t\trte_table_action_profile_free(ap);\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\n-\tstatus = rte_table_action_profile_freeze(ap);\n-\tif (status) {\n-\t\trte_table_action_profile_free(ap);\n-\t\treturn NULL;\n-\t}\n-\n-\t/* Node allocation */\n-\tprofile = calloc(1, sizeof(struct softnic_table_action_profile));\n-\tif (profile == NULL) {\n-\t\trte_table_action_profile_free(ap);\n-\t\treturn NULL;\n-\t}\n-\n-\t/* Node fill in */\n-\tstrlcpy(profile->name, name, sizeof(profile->name));\n-\tmemcpy(&profile->params, params, sizeof(*params));\n-\tprofile->ap = ap;\n-\n-\t/* Node add to list */\n-\tTAILQ_INSERT_TAIL(&p->table_action_profile_list, profile, node);\n-\n-\treturn profile;\n-}\ndiff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c\nindex abe275ec83..2b00b65c6c 100644\n--- a/drivers/net/softnic/rte_eth_softnic_cli.c\n+++ b/drivers/net/softnic/rte_eth_softnic_cli.c\n@@ -196,6 +196,7 @@ cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n \tsize_t out_size)\n {\n \tchar *pipeline_name;\n+\tstruct pipeline *p;\n \tuint32_t thread_id;\n \tint status;\n \n@@ -215,13 +216,18 @@ cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n \t}\n \n \tpipeline_name = tokens[3];\n+\tp = softnic_pipeline_find(softnic, pipeline_name);\n+\tif (!p) {\n+\t\tsnprintf(out, out_size, MSG_ARG_INVALID, \"pipeline_name\");\n+\t\treturn;\n+\t}\n \n \tif (strcmp(tokens[4], \"enable\") != 0) {\n \t\tsnprintf(out, out_size, MSG_ARG_NOT_FOUND, \"enable\");\n \t\treturn;\n \t}\n \n-\tstatus = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);\n+\tstatus = softnic_thread_pipeline_enable(softnic, thread_id, p);\n \tif (status) {\n \t\tsnprintf(out, out_size, MSG_CMD_FAIL, \"thread pipeline enable\");\n \t\treturn;\n@@ -239,6 +245,7 @@ cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \tsize_t out_size)\n {\n \tchar *pipeline_name;\n+\tstruct pipeline *p;\n \tuint32_t thread_id;\n \tint status;\n \n@@ -258,13 +265,18 @@ cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \t}\n \n \tpipeline_name = tokens[3];\n+\tp = softnic_pipeline_find(softnic, pipeline_name);\n+\tif (!p) {\n+\t\tsnprintf(out, out_size, MSG_ARG_INVALID, \"pipeline_name\");\n+\t\treturn;\n+\t}\n \n \tif (strcmp(tokens[4], \"disable\") != 0) {\n \t\tsnprintf(out, out_size, MSG_ARG_NOT_FOUND, \"disable\");\n \t\treturn;\n \t}\n \n-\tstatus = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);\n+\tstatus = softnic_thread_pipeline_disable(softnic, thread_id, p);\n \tif (status) {\n \t\tsnprintf(out, out_size, MSG_CMD_FAIL,\n \t\t\t\"thread pipeline disable\");\ndiff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h\nindex df74c1fbdc..d817883a39 100644\n--- a/drivers/net/softnic/rte_eth_softnic_internals.h\n+++ b/drivers/net/softnic/rte_eth_softnic_internals.h\n@@ -13,9 +13,8 @@\n #include <rte_mbuf.h>\n #include <rte_ring.h>\n #include <rte_ethdev.h>\n-#include <rte_port_in_action.h>\n-#include <rte_table_action.h>\n-#include <rte_pipeline.h>\n+#include <rte_swx_pipeline.h>\n+#include <rte_swx_ctl.h>\n \n #include <rte_ethdev_core.h>\n #include <ethdev_driver.h>\n@@ -89,207 +88,18 @@ struct softnic_link {\n \n TAILQ_HEAD(softnic_link_list, softnic_link);\n \n-/**\n- * Input port action\n- */\n-struct softnic_port_in_action_profile_params {\n-\tuint64_t action_mask;\n-\tstruct rte_port_in_action_fltr_config fltr;\n-\tstruct rte_port_in_action_lb_config lb;\n-};\n-\n-struct softnic_port_in_action_profile {\n-\tTAILQ_ENTRY(softnic_port_in_action_profile) node;\n-\tchar name[NAME_SIZE];\n-\tstruct softnic_port_in_action_profile_params params;\n-\tstruct rte_port_in_action_profile *ap;\n-};\n-\n-TAILQ_HEAD(softnic_port_in_action_profile_list, softnic_port_in_action_profile);\n-\n-/**\n- * Table action\n- */\n-struct softnic_table_action_profile_params {\n-\tuint64_t action_mask;\n-\tstruct rte_table_action_common_config common;\n-\tstruct rte_table_action_lb_config lb;\n-\tstruct rte_table_action_mtr_config mtr;\n-\tstruct rte_table_action_tm_config tm;\n-\tstruct rte_table_action_encap_config encap;\n-\tstruct rte_table_action_nat_config nat;\n-\tstruct rte_table_action_ttl_config ttl;\n-\tstruct rte_table_action_stats_config stats;\n-\tstruct rte_table_action_sym_crypto_config sym_crypto;\n-};\n-\n-struct softnic_table_action_profile {\n-\tTAILQ_ENTRY(softnic_table_action_profile) node;\n-\tchar name[NAME_SIZE];\n-\tstruct softnic_table_action_profile_params params;\n-\tstruct rte_table_action_profile *ap;\n-};\n-\n-TAILQ_HEAD(softnic_table_action_profile_list, softnic_table_action_profile);\n-\n-struct softnic_table_meter_profile {\n-\tTAILQ_ENTRY(softnic_table_meter_profile) node;\n-\tuint32_t meter_profile_id;\n-\tstruct rte_table_action_meter_profile profile;\n-};\n-\n-TAILQ_HEAD(softnic_table_meter_profile_list,\n-\tsoftnic_table_meter_profile);\n-\n /**\n  * Pipeline\n  */\n-struct pipeline_params {\n-\tuint32_t timer_period_ms;\n-\tuint32_t offset_port_id;\n-};\n-\n-enum softnic_port_in_type {\n-\tPORT_IN_RXQ,\n-\tPORT_IN_SWQ,\n-\tPORT_IN_SOURCE,\n-};\n-\n-struct softnic_port_in_params {\n-\t/* Read */\n-\tenum softnic_port_in_type type;\n-\tchar dev_name[NAME_SIZE];\n-\tunion {\n-\t\tstruct {\n-\t\t\tuint16_t queue_id;\n-\t\t} rxq;\n-\n-\t\tstruct {\n-\t\t\tconst char *mempool_name;\n-\t\t\tconst char *file_name;\n-\t\t\tuint32_t n_bytes_per_pkt;\n-\t\t} source;\n-\t};\n-\tuint32_t burst_size;\n-\n-\t/* Action */\n-\tchar action_profile_name[NAME_SIZE];\n-};\n-\n-enum softnic_port_out_type {\n-\tPORT_OUT_TXQ,\n-\tPORT_OUT_SWQ,\n-\tPORT_OUT_SINK,\n-};\n-\n-struct softnic_port_out_params {\n-\tenum softnic_port_out_type type;\n-\tchar dev_name[NAME_SIZE];\n-\tunion {\n-\t\tstruct {\n-\t\t\tuint16_t queue_id;\n-\t\t} txq;\n-\n-\t\tstruct {\n-\t\t\tconst char *file_name;\n-\t\t\tuint32_t max_n_pkts;\n-\t\t} sink;\n-\t};\n-\tuint32_t burst_size;\n-\tint retry;\n-\tuint32_t n_retries;\n-};\n-\n-enum softnic_table_type {\n-\tTABLE_ACL,\n-\tTABLE_ARRAY,\n-\tTABLE_HASH,\n-\tTABLE_LPM,\n-\tTABLE_STUB,\n-};\n-\n-struct softnic_table_acl_params {\n-\tuint32_t n_rules;\n-\tuint32_t ip_header_offset;\n-\tint ip_version;\n-};\n-\n-struct softnic_table_array_params {\n-\tuint32_t n_keys;\n-\tuint32_t key_offset;\n-};\n-\n-#ifndef TABLE_RULE_MATCH_SIZE_MAX\n-#define TABLE_RULE_MATCH_SIZE_MAX                          256\n-#endif\n-\n-struct softnic_table_hash_params {\n-\tuint32_t n_keys;\n-\tuint32_t key_offset;\n-\tuint32_t key_size;\n-\tuint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];\n-\tuint32_t n_buckets;\n-\tint extendable_bucket;\n-};\n-\n-struct softnic_table_lpm_params {\n-\tuint32_t n_rules;\n-\tuint32_t key_offset;\n-\tuint32_t key_size;\n-};\n-\n-struct softnic_table_params {\n-\t/* Match */\n-\tenum softnic_table_type match_type;\n-\tunion {\n-\t\tstruct softnic_table_acl_params acl;\n-\t\tstruct softnic_table_array_params array;\n-\t\tstruct softnic_table_hash_params hash;\n-\t\tstruct softnic_table_lpm_params lpm;\n-\t} match;\n-\n-\t/* Action */\n-\tchar action_profile_name[NAME_SIZE];\n-};\n-\n-struct softnic_port_in {\n-\tstruct softnic_port_in_params params;\n-\tstruct softnic_port_in_action_profile *ap;\n-\tstruct rte_port_in_action *a;\n-};\n-\n-struct softnic_port_out {\n-\tstruct softnic_port_out_params params;\n-};\n-\n-struct softnic_table {\n-\tstruct softnic_table_params params;\n-\tstruct softnic_table_action_profile *ap;\n-\tstruct rte_table_action *a;\n-\tstruct rte_table_action_dscp_table dscp_table;\n-\tstruct softnic_table_meter_profile_list meter_profiles;\n-};\n-\n struct pipeline {\n \tTAILQ_ENTRY(pipeline) node;\n \tchar name[NAME_SIZE];\n \n-\tstruct rte_pipeline *p;\n-\tstruct pipeline_params params;\n-\tstruct softnic_port_in port_in[RTE_PIPELINE_PORT_IN_MAX];\n-\tstruct softnic_port_out port_out[RTE_PIPELINE_PORT_OUT_MAX];\n-\tstruct softnic_table table[RTE_PIPELINE_TABLE_MAX];\n-\tuint32_t n_ports_in;\n-\tuint32_t n_ports_out;\n-\tuint32_t n_tables;\n-\n-\tstruct rte_ring *msgq_req;\n-\tstruct rte_ring *msgq_rsp;\n-\tuint32_t timer_period_ms;\n+\tstruct rte_swx_pipeline *p;\n+\tstruct rte_swx_ctl_pipeline *ctl;\n \n \tint enabled;\n \tuint32_t thread_id;\n-\tuint32_t cpu_id;\n };\n \n TAILQ_HEAD(pipeline_list, pipeline);\n@@ -309,6 +119,15 @@ TAILQ_HEAD(pipeline_list, pipeline);\n #define THREAD_TIMER_PERIOD_MS                             100\n #endif\n \n+/* Pipeline instruction quanta: Needs to be big enough to do some meaningful\n+ * work, but not too big to avoid starving any other pipelines mapped to the\n+ * same thread. For a pipeline that executes 10 instructions per packet, a\n+ * quanta of 1000 instructions equates to processing 100 packets.\n+ */\n+#ifndef PIPELINE_INSTR_QUANTA\n+#define PIPELINE_INSTR_QUANTA                              1000\n+#endif\n+\n /**\n  * Main thread: data plane thread context\n  */\n@@ -322,37 +141,14 @@ struct softnic_thread {\n /**\n  * Data plane threads: context\n  */\n-#ifndef TABLE_RULE_ACTION_SIZE_MAX\n-#define TABLE_RULE_ACTION_SIZE_MAX                         2048\n-#endif\n-\n-struct softnic_table_data {\n-\tstruct rte_table_action *a;\n-};\n-\n-struct pipeline_data {\n-\tstruct rte_pipeline *p;\n-\tstruct softnic_table_data table_data[RTE_PIPELINE_TABLE_MAX];\n-\tuint32_t n_tables;\n-\n-\tstruct rte_ring *msgq_req;\n-\tstruct rte_ring *msgq_rsp;\n-\tuint64_t timer_period; /* Measured in CPU cycles. */\n-\tuint64_t time_next;\n-\n-\tuint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];\n-};\n-\n struct softnic_thread_data {\n-\tstruct rte_pipeline *p[THREAD_PIPELINES_MAX];\n+\tstruct rte_swx_pipeline *p[THREAD_PIPELINES_MAX];\n \tuint32_t n_pipelines;\n \n-\tstruct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];\n \tstruct rte_ring *msgq_req;\n \tstruct rte_ring *msgq_rsp;\n \tuint64_t timer_period; /* Measured in CPU cycles. */\n \tuint64_t time_next;\n-\tuint64_t time_next_min;\n \tuint64_t iter;\n } __rte_cache_aligned;\n \n@@ -367,8 +163,6 @@ struct pmd_internals {\n \tstruct softnic_mempool_list mempool_list;\n \tstruct softnic_swq_list swq_list;\n \tstruct softnic_link_list link_list;\n-\tstruct softnic_port_in_action_profile_list port_in_action_profile_list;\n-\tstruct softnic_table_action_profile_list table_action_profile_list;\n \tstruct pipeline_list pipeline_list;\n \tstruct softnic_thread thread[RTE_MAX_LCORE];\n \tstruct softnic_thread_data thread_data[RTE_MAX_LCORE];\n@@ -447,42 +241,6 @@ softnic_link_create(struct pmd_internals *p,\n \tconst char *name,\n \tstruct softnic_link_params *params);\n \n-/**\n- * Input port action\n- */\n-int\n-softnic_port_in_action_profile_init(struct pmd_internals *p);\n-\n-void\n-softnic_port_in_action_profile_free(struct pmd_internals *p);\n-\n-struct softnic_port_in_action_profile *\n-softnic_port_in_action_profile_find(struct pmd_internals *p,\n-\tconst char *name);\n-\n-struct softnic_port_in_action_profile *\n-softnic_port_in_action_profile_create(struct pmd_internals *p,\n-\tconst char *name,\n-\tstruct softnic_port_in_action_profile_params *params);\n-\n-/**\n- * Table action\n- */\n-int\n-softnic_table_action_profile_init(struct pmd_internals *p);\n-\n-void\n-softnic_table_action_profile_free(struct pmd_internals *p);\n-\n-struct softnic_table_action_profile *\n-softnic_table_action_profile_find(struct pmd_internals *p,\n-\tconst char *name);\n-\n-struct softnic_table_action_profile *\n-softnic_table_action_profile_create(struct pmd_internals *p,\n-\tconst char *name,\n-\tstruct softnic_table_action_profile_params *params);\n-\n /**\n  * Pipeline\n  */\n@@ -504,228 +262,9 @@ softnic_pipeline_find(struct pmd_internals *p, const char *name);\n struct pipeline *\n softnic_pipeline_create(struct pmd_internals *p,\n \tconst char *name,\n-\tstruct pipeline_params *params);\n-\n-int\n-softnic_pipeline_port_in_create(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tstruct softnic_port_in_params *params,\n-\tint enabled);\n-\n-int\n-softnic_pipeline_port_in_connect_to_table(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id,\n-\tuint32_t table_id);\n-\n-int\n-softnic_pipeline_port_out_create(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tstruct softnic_port_out_params *params);\n-\n-int\n-softnic_pipeline_port_out_find(struct pmd_internals *softnic,\n-\t\tconst char *pipeline_name,\n-\t\tconst char *name,\n-\t\tuint32_t *port_id);\n-\n-int\n-softnic_pipeline_table_create(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tstruct softnic_table_params *params);\n-\n-struct softnic_table_meter_profile *\n-softnic_pipeline_table_meter_profile_find(struct softnic_table *table,\n-\tuint32_t meter_profile_id);\n-\n-struct softnic_table_rule_match_acl {\n-\tint ip_version;\n-\n-\tRTE_STD_C11\n-\tunion {\n-\t\tstruct {\n-\t\t\tuint32_t sa;\n-\t\t\tuint32_t da;\n-\t\t} ipv4;\n-\n-\t\tstruct {\n-\t\t\tuint8_t sa[16];\n-\t\t\tuint8_t da[16];\n-\t\t} ipv6;\n-\t};\n-\n-\tuint32_t sa_depth;\n-\tuint32_t da_depth;\n-\tuint16_t sp0;\n-\tuint16_t sp1;\n-\tuint16_t dp0;\n-\tuint16_t dp1;\n-\tuint8_t proto;\n-\tuint8_t proto_mask;\n-\tuint32_t priority;\n-};\n-\n-struct softnic_table_rule_match_array {\n-\tuint32_t pos;\n-};\n-\n-struct softnic_table_rule_match_hash {\n-\tuint8_t key[TABLE_RULE_MATCH_SIZE_MAX];\n-};\n-\n-struct softnic_table_rule_match_lpm {\n-\tint ip_version;\n-\n-\tRTE_STD_C11\n-\tunion {\n-\t\tuint32_t ipv4;\n-\t\tuint8_t ipv6[16];\n-\t};\n-\n-\tuint8_t depth;\n-};\n-\n-struct softnic_table_rule_match {\n-\tenum softnic_table_type match_type;\n-\n-\tunion {\n-\t\tstruct softnic_table_rule_match_acl acl;\n-\t\tstruct softnic_table_rule_match_array array;\n-\t\tstruct softnic_table_rule_match_hash hash;\n-\t\tstruct softnic_table_rule_match_lpm lpm;\n-\t} match;\n-};\n-\n-#ifndef SYM_CRYPTO_MAX_KEY_SIZE\n-#define SYM_CRYPTO_MAX_KEY_SIZE\t\t(256)\n-#endif\n-struct softnic_table_rule_action {\n-\tuint64_t action_mask;\n-\tstruct rte_table_action_fwd_params fwd;\n-\tstruct rte_table_action_lb_params lb;\n-\tstruct rte_table_action_mtr_params mtr;\n-\tstruct rte_table_action_tm_params tm;\n-\tstruct rte_table_action_encap_params encap;\n-\tstruct rte_table_action_nat_params nat;\n-\tstruct rte_table_action_ttl_params ttl;\n-\tstruct rte_table_action_stats_params stats;\n-\tstruct rte_table_action_time_params time;\n-\tstruct rte_table_action_tag_params tag;\n-\tstruct rte_table_action_decap_params decap;\n-\tstruct rte_table_action_sym_crypto_params sym_crypto;\n-\tuint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];\n-};\n-\n-int\n-softnic_pipeline_port_in_stats_read(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id,\n-\tstruct rte_pipeline_port_in_stats *stats,\n-\tint clear);\n-\n-int\n-softnic_pipeline_port_in_enable(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id);\n-\n-int\n-softnic_pipeline_port_in_disable(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id);\n-\n-int\n-softnic_pipeline_port_out_stats_read(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id,\n-\tstruct rte_pipeline_port_out_stats *stats,\n-\tint clear);\n-\n-int\n-softnic_pipeline_table_stats_read(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct rte_pipeline_table_stats *stats,\n-\tint clear);\n-\n-int\n-softnic_pipeline_table_rule_add(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_match *match,\n-\tstruct softnic_table_rule_action *action,\n-\tvoid **data);\n-\n-int\n-softnic_pipeline_table_rule_add_bulk(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_match *match,\n-\tstruct softnic_table_rule_action *action,\n-\tvoid **data,\n-\tuint32_t *n_rules);\n-\n-int\n-softnic_pipeline_table_rule_add_default(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_action *action,\n-\tvoid **data);\n-\n-int\n-softnic_pipeline_table_rule_delete(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_match *match);\n-\n-int\n-softnic_pipeline_table_rule_delete_default(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id);\n-\n-int\n-softnic_pipeline_table_rule_stats_read(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tvoid *data,\n-\tstruct rte_table_action_stats_counters *stats,\n-\tint clear);\n-\n-int\n-softnic_pipeline_table_mtr_profile_add(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tuint32_t meter_profile_id,\n-\tstruct rte_table_action_meter_profile *profile);\n-\n-int\n-softnic_pipeline_table_mtr_profile_delete(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tuint32_t meter_profile_id);\n-\n-int\n-softnic_pipeline_table_rule_mtr_read(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tvoid *data,\n-\tuint32_t tc_mask,\n-\tstruct rte_table_action_mtr_counters *stats,\n-\tint clear);\n-\n-int\n-softnic_pipeline_table_dscp_table_update(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tuint64_t dscp_mask,\n-\tstruct rte_table_action_dscp_table *dscp_table);\n-\n-int\n-softnic_pipeline_table_rule_ttl_read(struct pmd_internals *p,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tvoid *data,\n-\tstruct rte_table_action_ttl_counters *stats,\n-\tint clear);\n+\tconst char *lib_file_name,\n+\tconst char *iospec_file_name,\n+\tint numa_node);\n \n /**\n  * Thread\n@@ -739,12 +278,15 @@ softnic_thread_free(struct pmd_internals *p);\n int\n softnic_thread_pipeline_enable(struct pmd_internals *p,\n \tuint32_t thread_id,\n-\tconst char *pipeline_name);\n+\tstruct pipeline *pipeline);\n \n int\n softnic_thread_pipeline_disable(struct pmd_internals *p,\n \tuint32_t thread_id,\n-\tconst char *pipeline_name);\n+\tstruct pipeline *pipeline);\n+\n+void\n+softnic_thread_pipeline_disable_all(struct pmd_internals *p);\n \n /**\n  * CLI\ndiff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c\nindex 7a2828b785..76570b2cb3 100644\n--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c\n+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c\n@@ -6,35 +6,10 @@\n #include <string.h>\n \n #include <rte_common.h>\n-#include <rte_ip.h>\n-#include <rte_tcp.h>\n-\n #include <rte_string_fns.h>\n-#include <rte_port_ethdev.h>\n-#include <rte_port_ring.h>\n-#include <rte_port_source_sink.h>\n-#include <rte_port_fd.h>\n-#include <rte_port_sched.h>\n-#include <rte_port_sym_crypto.h>\n-\n-#include <rte_table_acl.h>\n-#include <rte_table_array.h>\n-#include <rte_table_hash.h>\n-#include <rte_table_hash_func.h>\n-#include <rte_table_lpm.h>\n-#include <rte_table_lpm_ipv6.h>\n-#include <rte_table_stub.h>\n \n #include \"rte_eth_softnic_internals.h\"\n \n-#ifndef PIPELINE_MSGQ_SIZE\n-#define PIPELINE_MSGQ_SIZE                                 64\n-#endif\n-\n-#ifndef TABLE_LPM_NUMBER_TBL8\n-#define TABLE_LPM_NUMBER_TBL8                              256\n-#endif\n-\n int\n softnic_pipeline_init(struct pmd_internals *p)\n {\n@@ -43,44 +18,19 @@ softnic_pipeline_init(struct pmd_internals *p)\n \treturn 0;\n }\n \n-static void\n-softnic_pipeline_table_free(struct softnic_table *table)\n-{\n-\tfor ( ; ; ) {\n-\t\tstruct softnic_table_meter_profile *mp;\n-\n-\t\tmp = TAILQ_FIRST(&table->meter_profiles);\n-\t\tif (mp == NULL)\n-\t\t\tbreak;\n-\n-\t\tTAILQ_REMOVE(&table->meter_profiles, mp, node);\n-\t\tfree(mp);\n-\t}\n-}\n-\n void\n softnic_pipeline_free(struct pmd_internals *p)\n {\n \tfor ( ; ; ) {\n \t\tstruct pipeline *pipeline;\n-\t\tuint32_t table_id;\n \n \t\tpipeline = TAILQ_FIRST(&p->pipeline_list);\n \t\tif (pipeline == NULL)\n \t\t\tbreak;\n \n \t\tTAILQ_REMOVE(&p->pipeline_list, pipeline, node);\n-\n-\t\tfor (table_id = 0; table_id < pipeline->n_tables; table_id++) {\n-\t\t\tstruct softnic_table *table =\n-\t\t\t\t&pipeline->table[table_id];\n-\n-\t\t\tsoftnic_pipeline_table_free(table);\n-\t\t}\n-\n-\t\trte_ring_free(pipeline->msgq_req);\n-\t\trte_ring_free(pipeline->msgq_rsp);\n-\t\trte_pipeline_free(pipeline->p);\n+\t\trte_swx_ctl_pipeline_free(pipeline->ctl);\n+\t\trte_swx_pipeline_free(pipeline->p);\n \t\tfree(pipeline);\n \t}\n }\n@@ -94,7 +44,7 @@ softnic_pipeline_disable_all(struct pmd_internals *p)\n \t\tif (pipeline->enabled)\n \t\t\tsoftnic_thread_pipeline_disable(p,\n \t\t\t\tpipeline->thread_id,\n-\t\t\t\tpipeline->name);\n+\t\t\t\tpipeline);\n }\n \n uint32_t\n@@ -126,850 +76,170 @@ softnic_pipeline_find(struct pmd_internals *p,\n \treturn NULL;\n }\n \n-struct pipeline *\n-softnic_pipeline_create(struct pmd_internals *softnic,\n-\tconst char *name,\n-\tstruct pipeline_params *params)\n-{\n-\tchar resource_name[NAME_MAX];\n-\tstruct rte_pipeline_params pp;\n-\tstruct pipeline *pipeline;\n-\tstruct rte_pipeline *p;\n-\tstruct rte_ring *msgq_req;\n-\tstruct rte_ring *msgq_rsp;\n-\n-\t/* Check input params */\n-\tif (name == NULL ||\n-\t\tsoftnic_pipeline_find(softnic, name) ||\n-\t\tparams == NULL ||\n-\t\tparams->timer_period_ms == 0)\n-\t\treturn NULL;\n-\n-\t/* Resource create */\n-\tsnprintf(resource_name, sizeof(resource_name), \"%s-%s-REQ\",\n-\t\tsoftnic->params.name,\n-\t\tname);\n-\n-\tmsgq_req = rte_ring_create(resource_name,\n-\t\tPIPELINE_MSGQ_SIZE,\n-\t\tsoftnic->params.cpu_id,\n-\t\tRING_F_SP_ENQ | RING_F_SC_DEQ);\n-\tif (msgq_req == NULL)\n-\t\treturn NULL;\n-\n-\tsnprintf(resource_name, sizeof(resource_name), \"%s-%s-RSP\",\n-\t\tsoftnic->params.name,\n-\t\tname);\n-\n-\tmsgq_rsp = rte_ring_create(resource_name,\n-\t\tPIPELINE_MSGQ_SIZE,\n-\t\tsoftnic->params.cpu_id,\n-\t\tRING_F_SP_ENQ | RING_F_SC_DEQ);\n-\tif (msgq_rsp == NULL) {\n-\t\trte_ring_free(msgq_req);\n-\t\treturn NULL;\n-\t}\n-\n-\tsnprintf(resource_name, sizeof(resource_name), \"%s_%s\",\n-\t\tsoftnic->params.name,\n-\t\tname);\n-\n-\tpp.name = resource_name;\n-\tpp.socket_id = (int)softnic->params.cpu_id;\n-\tpp.offset_port_id = params->offset_port_id;\n-\n-\tp = rte_pipeline_create(&pp);\n-\tif (p == NULL) {\n-\t\trte_ring_free(msgq_rsp);\n-\t\trte_ring_free(msgq_req);\n-\t\treturn NULL;\n-\t}\n-\n-\t/* Node allocation */\n-\tpipeline = calloc(1, sizeof(struct pipeline));\n-\tif (pipeline == NULL) {\n-\t\trte_pipeline_free(p);\n-\t\trte_ring_free(msgq_rsp);\n-\t\trte_ring_free(msgq_req);\n-\t\treturn NULL;\n-\t}\n-\n-\t/* Node fill in */\n-\tstrlcpy(pipeline->name, name, sizeof(pipeline->name));\n-\tpipeline->p = p;\n-\tmemcpy(&pipeline->params, params, sizeof(*params));\n-\tpipeline->n_ports_in = 0;\n-\tpipeline->n_ports_out = 0;\n-\tpipeline->n_tables = 0;\n-\tpipeline->msgq_req = msgq_req;\n-\tpipeline->msgq_rsp = msgq_rsp;\n-\tpipeline->timer_period_ms = params->timer_period_ms;\n-\tpipeline->enabled = 0;\n-\tpipeline->cpu_id = softnic->params.cpu_id;\n-\n-\t/* Node add to list */\n-\tTAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);\n-\n-\treturn pipeline;\n-}\n+#ifndef MAX_LINE_LENGTH\n+#define MAX_LINE_LENGTH 2048\n+#endif\n \n-int\n-softnic_pipeline_port_in_create(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tstruct softnic_port_in_params *params,\n-\tint enabled)\n+/* The Soft NIC device internal resources such as mempools, rings or pipelines are globally visible,\n+ * hence they need to have globally unique names. In order to apply the same configuration scripts\n+ * unmodified to all the Soft NIC devices that instantiate the same program, the pipeline I/O\n+ * configuration files are silently translated internally to prefix the name of the above resources\n+ * with the Soft NIC device name, thus making the resource names globally unique.\n+ */\n+static int\n+iospec_translate(struct pmd_internals *softnic __rte_unused,\n+\t\t const char *file_in_name,\n+\t\t const char *file_out_name)\n {\n-\tstruct rte_pipeline_port_in_params p;\n-\n-\tunion {\n-\t\tstruct rte_port_ethdev_reader_params ethdev;\n-\t\tstruct rte_port_ring_reader_params ring;\n-\t\tstruct rte_port_sched_reader_params sched;\n-\t\tstruct rte_port_fd_reader_params fd;\n-\t\tstruct rte_port_source_params source;\n-\t} pp;\n+\tFILE *fi = NULL, *fo = NULL;\n+\tchar *line = NULL;\n+\tint status = 0;\n \n-\tstruct pipeline *pipeline;\n-\tstruct softnic_port_in *port_in;\n-\tstruct softnic_port_in_action_profile *ap;\n-\tstruct rte_port_in_action *action;\n-\tuint32_t port_id;\n-\tint status;\n-\n-\tmemset(&p, 0, sizeof(p));\n-\tmemset(&pp, 0, sizeof(pp));\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tparams == NULL ||\n-\t\tparams->burst_size == 0 ||\n-\t\tparams->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)\n-\t\treturn -1;\n-\n-\tpipeline = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (pipeline == NULL)\n-\t\treturn -1;\n-\n-\tap = NULL;\n-\tif (strlen(params->action_profile_name)) {\n-\t\tap = softnic_port_in_action_profile_find(softnic,\n-\t\t\tparams->action_profile_name);\n-\t\tif (ap == NULL)\n-\t\t\treturn -1;\n+\t/* File open. */\n+\tfi = fopen(file_in_name, \"r\");\n+\tfo = fopen(file_out_name, \"w\");\n+\tif (!fi || !fo) {\n+\t\tstatus = -EIO;\n+\t\tgoto free;\n \t}\n \n-\tswitch (params->type) {\n-\tcase PORT_IN_RXQ:\n-\t{\n-\t\tstruct softnic_link *link;\n-\n-\t\tlink = softnic_link_find(softnic, params->dev_name);\n-\t\tif (link == NULL)\n-\t\t\treturn -1;\n-\n-\t\tif (params->rxq.queue_id >= link->n_rxq)\n-\t\t\treturn -1;\n-\n-\t\tpp.ethdev.port_id = link->port_id;\n-\t\tpp.ethdev.queue_id = params->rxq.queue_id;\n-\n-\t\tp.ops = &rte_port_ethdev_reader_ops;\n-\t\tp.arg_create = &pp.ethdev;\n-\t\tbreak;\n+\t/* Memory allocation. */\n+\tline = malloc(MAX_LINE_LENGTH);\n+\tif (!line) {\n+\t\tstatus = -ENOMEM;\n+\t\tgoto free;\n \t}\n \n-\tcase PORT_IN_SWQ:\n-\t{\n-\t\tstruct softnic_swq *swq;\n-\n-\t\tswq = softnic_swq_find(softnic, params->dev_name);\n-\t\tif (swq == NULL)\n-\t\t\treturn -1;\n-\n-\t\tpp.ring.ring = swq->r;\n-\n-\t\tp.ops = &rte_port_ring_reader_ops;\n-\t\tp.arg_create = &pp.ring;\n-\t\tbreak;\n-\t}\n+\t/* Read from the input file and write to the output file. */\n+\tfor ( ; ; ) {\n+\t\tchar *ptr = line;\n+\t\tuint32_t n_tokens;\n+\t\tint flag = 0;\n \n-\tcase PORT_IN_SOURCE:\n-\t{\n-\t\tstruct softnic_mempool *mempool;\n+\t\t/* Read next line. */\n+\t\tif (!fgets(line, MAX_LINE_LENGTH, fi))\n+\t\t\tbreak;\n \n-\t\tmempool = softnic_mempool_find(softnic, params->source.mempool_name);\n-\t\tif (mempool == NULL)\n-\t\t\treturn -1;\n+\t\t/* Parse the line into tokens. */\n+\t\tfor (n_tokens = 0; ; n_tokens++) {\n+\t\t\tchar *token;\n \n-\t\tpp.source.mempool = mempool->m;\n-\t\tpp.source.file_name = params->source.file_name;\n-\t\tpp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;\n+\t\t\t/* Read token. */\n+\t\t\ttoken = strtok_r(ptr, \" \\f\\n\\r\\t\\v\", &ptr);\n+\t\t\tif (!token)\n+\t\t\t\tbreak;\n \n-\t\tp.ops = &rte_port_source_ops;\n-\t\tp.arg_create = &pp.source;\n-\t\tbreak;\n-\t}\n+\t\t\t/* Handle comments. */\n+\t\t\tif (!n_tokens &&\n+\t\t\t    ((token[0] == '#') ||\n+\t\t\t     (token[0] == ';') ||\n+\t\t\t     ((token[0] == '/') && (token[1] == '/'))))\n+\t\t\t\tbreak;\n \n-\tdefault:\n-\t\treturn -1;\n-\t}\n+\t\t\t/* Process token. */\n+\t\t\tif (flag) {\n+\t\t\t\tfprintf(fo, \"%s_%s \", softnic->params.name, token);\n+\t\t\t\tflag = 0;\n+\t\t\t\tcontinue;\n+\t\t\t}\n \n-\tp.burst_size = params->burst_size;\n+\t\t\tif (!strcmp(token, \"mempool\") ||\n+\t\t\t    !strcmp(token, \"ring\")) {\n+\t\t\t\tflag = 1;\n+\t\t\t\tfprintf(fo, \"%s \", token);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \n-\t/* Resource create */\n-\taction = NULL;\n-\tp.f_action = NULL;\n-\tp.arg_ah = NULL;\n-\n-\tif (ap) {\n-\t\taction = rte_port_in_action_create(ap->ap,\n-\t\t\tsoftnic->params.cpu_id);\n-\t\tif (action == NULL)\n-\t\t\treturn -1;\n-\n-\t\tstatus = rte_port_in_action_params_get(action,\n-\t\t\t&p);\n-\t\tif (status) {\n-\t\t\trte_port_in_action_free(action);\n-\t\t\treturn -1;\n+\t\t\t/* Default action: write token. */\n+\t\t\tfprintf(fo, \"%s \", token);\n \t\t}\n-\t}\n-\n-\tstatus = rte_pipeline_port_in_create(pipeline->p,\n-\t\t&p,\n-\t\t&port_id);\n-\tif (status) {\n-\t\trte_port_in_action_free(action);\n-\t\treturn -1;\n-\t}\n-\n-\tif (enabled)\n-\t\trte_pipeline_port_in_enable(pipeline->p, port_id);\n-\n-\t/* Pipeline */\n-\tport_in = &pipeline->port_in[pipeline->n_ports_in];\n-\tmemcpy(&port_in->params, params, sizeof(*params));\n-\tport_in->ap = ap;\n-\tport_in->a = action;\n-\tpipeline->n_ports_in++;\n-\n-\treturn 0;\n-}\n-\n-int\n-softnic_pipeline_port_in_connect_to_table(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id,\n-\tuint32_t table_id)\n-{\n-\tstruct pipeline *pipeline;\n-\tint status;\n \n-\t/* Check input params */\n-\tif (pipeline_name == NULL)\n-\t\treturn -1;\n+\t\t/* Handle empty or comment lines. */\n+\t\tif (!n_tokens)\n+\t\t\tcontinue;\n \n-\tpipeline = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (pipeline == NULL ||\n-\t\tport_id >= pipeline->n_ports_in ||\n-\t\ttable_id >= pipeline->n_tables)\n-\t\treturn -1;\n+\t\t/* Write newline. */\n+\t\tfprintf(fo, \"\\n\");\n+\t}\n \n-\t/* Resource */\n-\tstatus = rte_pipeline_port_in_connect_to_table(pipeline->p,\n-\t\tport_id,\n-\t\ttable_id);\n+free:\n+\t/* Memory free. */\n+\tfree(line);\n \n+\t/* File close. */\n+\tif (fi)\n+\t\tfclose(fi);\n+\tif (fo)\n+\t\tfclose(fo);\n \treturn status;\n }\n \n-int\n-softnic_pipeline_port_out_create(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tstruct softnic_port_out_params *params)\n+struct pipeline *\n+softnic_pipeline_create(struct pmd_internals *softnic,\n+\tconst char *name,\n+\tconst char *lib_file_name,\n+\tconst char *iospec_file_name,\n+\tint numa_node)\n {\n-\tstruct rte_pipeline_port_out_params p;\n-\n-\tunion {\n-\t\tstruct rte_port_ethdev_writer_params ethdev;\n-\t\tstruct rte_port_ring_writer_params ring;\n-\t\tstruct rte_port_sched_writer_params sched;\n-\t\tstruct rte_port_fd_writer_params fd;\n-\t\tstruct rte_port_sink_params sink;\n-\t} pp;\n-\n-\tunion {\n-\t\tstruct rte_port_ethdev_writer_nodrop_params ethdev;\n-\t\tstruct rte_port_ring_writer_nodrop_params ring;\n-\t\tstruct rte_port_fd_writer_nodrop_params fd;\n-\t} pp_nodrop;\n-\n-\tstruct pipeline *pipeline;\n-\tstruct softnic_port_out *port_out;\n-\tuint32_t port_id;\n-\tint status;\n-\n-\tmemset(&p, 0, sizeof(p));\n-\tmemset(&pp, 0, sizeof(pp));\n-\tmemset(&pp_nodrop, 0, sizeof(pp_nodrop));\n+\tchar global_name[NAME_MAX];\n+\tFILE *iospec_file = NULL;\n+\tstruct pipeline *pipeline = NULL;\n+\tstruct rte_swx_pipeline *p = NULL;\n+\tstruct rte_swx_ctl_pipeline *ctl = NULL;\n+\tint status = 0;\n \n \t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tparams == NULL ||\n-\t\tparams->burst_size == 0 ||\n-\t\tparams->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)\n-\t\treturn -1;\n-\n-\tpipeline = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (pipeline == NULL)\n-\t\treturn -1;\n-\n-\tswitch (params->type) {\n-\tcase PORT_OUT_TXQ:\n-\t{\n-\t\tstruct softnic_link *link;\n-\n-\t\tlink = softnic_link_find(softnic, params->dev_name);\n-\t\tif (link == NULL)\n-\t\t\treturn -1;\n-\n-\t\tif (params->txq.queue_id >= link->n_txq)\n-\t\t\treturn -1;\n-\n-\t\tpp.ethdev.port_id = link->port_id;\n-\t\tpp.ethdev.queue_id = params->txq.queue_id;\n-\t\tpp.ethdev.tx_burst_sz = params->burst_size;\n-\n-\t\tpp_nodrop.ethdev.port_id = link->port_id;\n-\t\tpp_nodrop.ethdev.queue_id = params->txq.queue_id;\n-\t\tpp_nodrop.ethdev.tx_burst_sz = params->burst_size;\n-\t\tpp_nodrop.ethdev.n_retries = params->n_retries;\n-\n-\t\tif (params->retry == 0) {\n-\t\t\tp.ops = &rte_port_ethdev_writer_ops;\n-\t\t\tp.arg_create = &pp.ethdev;\n-\t\t} else {\n-\t\t\tp.ops = &rte_port_ethdev_writer_nodrop_ops;\n-\t\t\tp.arg_create = &pp_nodrop.ethdev;\n-\t\t}\n-\t\tbreak;\n-\t}\n-\n-\tcase PORT_OUT_SWQ:\n-\t{\n-\t\tstruct softnic_swq *swq;\n-\n-\t\tswq = softnic_swq_find(softnic, params->dev_name);\n-\t\tif (swq == NULL)\n-\t\t\treturn -1;\n-\n-\t\tpp.ring.ring = swq->r;\n-\t\tpp.ring.tx_burst_sz = params->burst_size;\n-\n-\t\tpp_nodrop.ring.ring = swq->r;\n-\t\tpp_nodrop.ring.tx_burst_sz = params->burst_size;\n-\t\tpp_nodrop.ring.n_retries = params->n_retries;\n-\n-\t\tif (params->retry == 0) {\n-\t\t\tp.ops = &rte_port_ring_writer_ops;\n-\t\t\tp.arg_create = &pp.ring;\n-\t\t} else {\n-\t\t\tp.ops = &rte_port_ring_writer_nodrop_ops;\n-\t\t\tp.arg_create = &pp_nodrop.ring;\n-\t\t}\n-\t\tbreak;\n-\t}\n-\n-\tcase PORT_OUT_SINK:\n-\t{\n-\t\tpp.sink.file_name = params->sink.file_name;\n-\t\tpp.sink.max_n_pkts = params->sink.max_n_pkts;\n-\n-\t\tp.ops = &rte_port_sink_ops;\n-\t\tp.arg_create = &pp.sink;\n-\t\tbreak;\n-\t}\n-\n-\tdefault:\n-\t\treturn -1;\n-\t}\n-\n-\tp.f_action = NULL;\n-\tp.arg_ah = NULL;\n+\tif (!name || !name[0] || softnic_pipeline_find(softnic, name))\n+\t\tgoto error;\n \n \t/* Resource create */\n-\tstatus = rte_pipeline_port_out_create(pipeline->p,\n-\t\t&p,\n-\t\t&port_id);\n+\tsnprintf(global_name, sizeof(global_name), \"/tmp/%s_%s.io\", softnic->params.name, name);\n \n+\tstatus = iospec_translate(softnic, iospec_file_name, global_name);\n \tif (status)\n-\t\treturn -1;\n-\n-\t/* Pipeline */\n-\tport_out = &pipeline->port_out[pipeline->n_ports_out];\n-\tmemcpy(&port_out->params, params, sizeof(*params));\n-\tpipeline->n_ports_out++;\n-\n-\treturn 0;\n-}\n+\t\tgoto error;\n \n-static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {\n-\t/* Protocol */\n-\t[0] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n-\t\t.size = sizeof(uint8_t),\n-\t\t.field_index = 0,\n-\t\t.input_index = 0,\n-\t\t.offset = offsetof(struct rte_ipv4_hdr, next_proto_id),\n-\t},\n-\n-\t/* Source IP address (IPv4) */\n-\t[1] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 1,\n-\t\t.input_index = 1,\n-\t\t.offset = offsetof(struct rte_ipv4_hdr, src_addr),\n-\t},\n-\n-\t/* Destination IP address (IPv4) */\n-\t[2] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 2,\n-\t\t.input_index = 2,\n-\t\t.offset = offsetof(struct rte_ipv4_hdr, dst_addr),\n-\t},\n-\n-\t/* Source Port */\n-\t[3] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_RANGE,\n-\t\t.size = sizeof(uint16_t),\n-\t\t.field_index = 3,\n-\t\t.input_index = 3,\n-\t\t.offset = sizeof(struct rte_ipv4_hdr) +\n-\t\t\toffsetof(struct rte_tcp_hdr, src_port),\n-\t},\n-\n-\t/* Destination Port */\n-\t[4] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_RANGE,\n-\t\t.size = sizeof(uint16_t),\n-\t\t.field_index = 4,\n-\t\t.input_index = 3,\n-\t\t.offset = sizeof(struct rte_ipv4_hdr) +\n-\t\t\toffsetof(struct rte_tcp_hdr, dst_port),\n-\t},\n-};\n-\n-static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {\n-\t/* Protocol */\n-\t[0] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_BITMASK,\n-\t\t.size = sizeof(uint8_t),\n-\t\t.field_index = 0,\n-\t\t.input_index = 0,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, proto),\n-\t},\n-\n-\t/* Source IP address (IPv6) */\n-\t[1] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 1,\n-\t\t.input_index = 1,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, src_addr[0]),\n-\t},\n-\n-\t[2] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 2,\n-\t\t.input_index = 2,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, src_addr[4]),\n-\t},\n-\n-\t[3] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 3,\n-\t\t.input_index = 3,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, src_addr[8]),\n-\t},\n-\n-\t[4] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 4,\n-\t\t.input_index = 4,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, src_addr[12]),\n-\t},\n-\n-\t/* Destination IP address (IPv6) */\n-\t[5] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 5,\n-\t\t.input_index = 5,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, dst_addr[0]),\n-\t},\n-\n-\t[6] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 6,\n-\t\t.input_index = 6,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, dst_addr[4]),\n-\t},\n-\n-\t[7] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 7,\n-\t\t.input_index = 7,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, dst_addr[8]),\n-\t},\n-\n-\t[8] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_MASK,\n-\t\t.size = sizeof(uint32_t),\n-\t\t.field_index = 8,\n-\t\t.input_index = 8,\n-\t\t.offset = offsetof(struct rte_ipv6_hdr, dst_addr[12]),\n-\t},\n-\n-\t/* Source Port */\n-\t[9] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_RANGE,\n-\t\t.size = sizeof(uint16_t),\n-\t\t.field_index = 9,\n-\t\t.input_index = 9,\n-\t\t.offset = sizeof(struct rte_ipv6_hdr) +\n-\t\t\toffsetof(struct rte_tcp_hdr, src_port),\n-\t},\n-\n-\t/* Destination Port */\n-\t[10] = {\n-\t\t.type = RTE_ACL_FIELD_TYPE_RANGE,\n-\t\t.size = sizeof(uint16_t),\n-\t\t.field_index = 10,\n-\t\t.input_index = 9,\n-\t\t.offset = sizeof(struct rte_ipv6_hdr) +\n-\t\t\toffsetof(struct rte_tcp_hdr, dst_port),\n-\t},\n-};\n-\n-int\n-softnic_pipeline_table_create(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tstruct softnic_table_params *params)\n-{\n-\tchar name[NAME_MAX];\n-\tstruct rte_pipeline_table_params p;\n-\n-\tunion {\n-\t\tstruct rte_table_acl_params acl;\n-\t\tstruct rte_table_array_params array;\n-\t\tstruct rte_table_hash_params hash;\n-\t\tstruct rte_table_lpm_params lpm;\n-\t\tstruct rte_table_lpm_ipv6_params lpm_ipv6;\n-\t} pp;\n-\n-\tstruct pipeline *pipeline;\n-\tstruct softnic_table *table;\n-\tstruct softnic_table_action_profile *ap;\n-\tstruct rte_table_action *action;\n-\tuint32_t table_id;\n-\tint status;\n+\tiospec_file = fopen(global_name, \"r\");\n+\tif (!iospec_file)\n+\t\tgoto error;\n \n-\tmemset(&p, 0, sizeof(p));\n-\tmemset(&pp, 0, sizeof(pp));\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tparams == NULL)\n-\t\treturn -1;\n-\n-\tpipeline = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (pipeline == NULL ||\n-\t\tpipeline->n_tables >= RTE_PIPELINE_TABLE_MAX)\n-\t\treturn -1;\n-\n-\tap = NULL;\n-\tif (strlen(params->action_profile_name)) {\n-\t\tap = softnic_table_action_profile_find(softnic,\n-\t\t\tparams->action_profile_name);\n-\t\tif (ap == NULL)\n-\t\t\treturn -1;\n-\t}\n-\n-\tsnprintf(name, NAME_MAX, \"%s_%s_table%u\",\n-\t\tsoftnic->params.name, pipeline_name, pipeline->n_tables);\n-\n-\tswitch (params->match_type) {\n-\tcase TABLE_ACL:\n-\t{\n-\t\tuint32_t ip_header_offset = params->match.acl.ip_header_offset -\n-\t\t\t(sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);\n-\t\tuint32_t i;\n-\n-\t\tif (params->match.acl.n_rules == 0)\n-\t\t\treturn -1;\n-\n-\t\tpp.acl.name = name;\n-\t\tpp.acl.n_rules = params->match.acl.n_rules;\n-\t\tif (params->match.acl.ip_version) {\n-\t\t\tmemcpy(&pp.acl.field_format,\n-\t\t\t\t&table_acl_field_format_ipv4,\n-\t\t\t\tsizeof(table_acl_field_format_ipv4));\n-\t\t\tpp.acl.n_rule_fields =\n-\t\t\t\tRTE_DIM(table_acl_field_format_ipv4);\n-\t\t} else {\n-\t\t\tmemcpy(&pp.acl.field_format,\n-\t\t\t\t&table_acl_field_format_ipv6,\n-\t\t\t\tsizeof(table_acl_field_format_ipv6));\n-\t\t\tpp.acl.n_rule_fields =\n-\t\t\t\tRTE_DIM(table_acl_field_format_ipv6);\n-\t\t}\n-\n-\t\tfor (i = 0; i < pp.acl.n_rule_fields; i++)\n-\t\t\tpp.acl.field_format[i].offset += ip_header_offset;\n-\n-\t\tp.ops = &rte_table_acl_ops;\n-\t\tp.arg_create = &pp.acl;\n-\t\tbreak;\n-\t}\n-\n-\tcase TABLE_ARRAY:\n-\t{\n-\t\tif (params->match.array.n_keys == 0)\n-\t\t\treturn -1;\n-\n-\t\tpp.array.n_entries = params->match.array.n_keys;\n-\t\tpp.array.offset = params->match.array.key_offset;\n-\n-\t\tp.ops = &rte_table_array_ops;\n-\t\tp.arg_create = &pp.array;\n-\t\tbreak;\n-\t}\n-\n-\tcase TABLE_HASH:\n-\t{\n-\t\tstruct rte_table_ops *ops;\n-\t\trte_table_hash_op_hash f_hash;\n-\n-\t\tif (params->match.hash.n_keys == 0)\n-\t\t\treturn -1;\n-\n-\t\tswitch (params->match.hash.key_size) {\n-\t\tcase  8:\n-\t\t\tf_hash = rte_table_hash_crc_key8;\n-\t\t\tbreak;\n-\t\tcase 16:\n-\t\t\tf_hash = rte_table_hash_crc_key16;\n-\t\t\tbreak;\n-\t\tcase 24:\n-\t\t\tf_hash = rte_table_hash_crc_key24;\n-\t\t\tbreak;\n-\t\tcase 32:\n-\t\t\tf_hash = rte_table_hash_crc_key32;\n-\t\t\tbreak;\n-\t\tcase 40:\n-\t\t\tf_hash = rte_table_hash_crc_key40;\n-\t\t\tbreak;\n-\t\tcase 48:\n-\t\t\tf_hash = rte_table_hash_crc_key48;\n-\t\t\tbreak;\n-\t\tcase 56:\n-\t\t\tf_hash = rte_table_hash_crc_key56;\n-\t\t\tbreak;\n-\t\tcase 64:\n-\t\t\tf_hash = rte_table_hash_crc_key64;\n-\t\t\tbreak;\n-\t\tdefault:\n-\t\t\treturn -1;\n-\t\t}\n+\tsnprintf(global_name, sizeof(global_name), \"%s_%s\", softnic->params.name, name);\n \n-\t\tpp.hash.name = name;\n-\t\tpp.hash.key_size = params->match.hash.key_size;\n-\t\tpp.hash.key_offset = params->match.hash.key_offset;\n-\t\tpp.hash.key_mask = params->match.hash.key_mask;\n-\t\tpp.hash.n_keys = params->match.hash.n_keys;\n-\t\tpp.hash.n_buckets = params->match.hash.n_buckets;\n-\t\tpp.hash.f_hash = f_hash;\n-\t\tpp.hash.seed = 0;\n-\n-\t\tif (params->match.hash.extendable_bucket)\n-\t\t\tswitch (params->match.hash.key_size) {\n-\t\t\tcase  8:\n-\t\t\t\tops = &rte_table_hash_key8_ext_ops;\n-\t\t\t\tbreak;\n-\t\t\tcase 16:\n-\t\t\t\tops = &rte_table_hash_key16_ext_ops;\n-\t\t\t\tbreak;\n-\t\t\tdefault:\n-\t\t\t\tops = &rte_table_hash_ext_ops;\n-\t\t\t}\n-\t\telse\n-\t\t\tswitch (params->match.hash.key_size) {\n-\t\t\tcase  8:\n-\t\t\t\tops = &rte_table_hash_key8_lru_ops;\n-\t\t\t\tbreak;\n-\t\t\tcase 16:\n-\t\t\t\tops = &rte_table_hash_key16_lru_ops;\n-\t\t\t\tbreak;\n-\t\t\tdefault:\n-\t\t\t\tops = &rte_table_hash_lru_ops;\n-\t\t\t}\n-\n-\t\tp.ops = ops;\n-\t\tp.arg_create = &pp.hash;\n-\t\tbreak;\n-\t}\n-\n-\tcase TABLE_LPM:\n-\t{\n-\t\tif (params->match.lpm.n_rules == 0)\n-\t\t\treturn -1;\n-\n-\t\tswitch (params->match.lpm.key_size) {\n-\t\tcase 4:\n-\t\t{\n-\t\t\tpp.lpm.name = name;\n-\t\t\tpp.lpm.n_rules = params->match.lpm.n_rules;\n-\t\t\tpp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;\n-\t\t\tpp.lpm.flags = 0;\n-\t\t\tpp.lpm.entry_unique_size = p.action_data_size +\n-\t\t\t\tsizeof(struct rte_pipeline_table_entry);\n-\t\t\tpp.lpm.offset = params->match.lpm.key_offset;\n-\n-\t\t\tp.ops = &rte_table_lpm_ops;\n-\t\t\tp.arg_create = &pp.lpm;\n-\t\t\tbreak;\n-\t\t}\n-\n-\t\tcase 16:\n-\t\t{\n-\t\t\tpp.lpm_ipv6.name = name;\n-\t\t\tpp.lpm_ipv6.n_rules = params->match.lpm.n_rules;\n-\t\t\tpp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;\n-\t\t\tpp.lpm_ipv6.entry_unique_size = p.action_data_size +\n-\t\t\t\tsizeof(struct rte_pipeline_table_entry);\n-\t\t\tpp.lpm_ipv6.offset = params->match.lpm.key_offset;\n-\n-\t\t\tp.ops = &rte_table_lpm_ipv6_ops;\n-\t\t\tp.arg_create = &pp.lpm_ipv6;\n-\t\t\tbreak;\n-\t\t}\n-\n-\t\tdefault:\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tbreak;\n-\t}\n-\n-\tcase TABLE_STUB:\n-\t{\n-\t\tp.ops = &rte_table_stub_ops;\n-\t\tp.arg_create = NULL;\n-\t\tbreak;\n-\t}\n-\n-\tdefault:\n-\t\treturn -1;\n-\t}\n-\n-\t/* Resource create */\n-\taction = NULL;\n-\tp.f_action_hit = NULL;\n-\tp.f_action_miss = NULL;\n-\tp.arg_ah = NULL;\n-\n-\tif (ap) {\n-\t\taction = rte_table_action_create(ap->ap,\n-\t\t\tsoftnic->params.cpu_id);\n-\t\tif (action == NULL)\n-\t\t\treturn -1;\n-\n-\t\tstatus = rte_table_action_table_params_get(action,\n-\t\t\t&p);\n-\t\tif (status ||\n-\t\t\t((p.action_data_size +\n-\t\t\tsizeof(struct rte_pipeline_table_entry)) >\n-\t\t\tTABLE_RULE_ACTION_SIZE_MAX)) {\n-\t\t\trte_table_action_free(action);\n-\t\t\treturn -1;\n-\t\t}\n-\t}\n-\n-\tif (params->match_type == TABLE_LPM) {\n-\t\tif (params->match.lpm.key_size == 4)\n-\t\t\tpp.lpm.entry_unique_size = p.action_data_size +\n-\t\t\t\tsizeof(struct rte_pipeline_table_entry);\n-\n-\t\tif (params->match.lpm.key_size == 16)\n-\t\t\tpp.lpm_ipv6.entry_unique_size = p.action_data_size +\n-\t\t\t\tsizeof(struct rte_pipeline_table_entry);\n-\t}\n-\n-\tstatus = rte_pipeline_table_create(pipeline->p,\n-\t\t&p,\n-\t\t&table_id);\n-\tif (status) {\n-\t\trte_table_action_free(action);\n-\t\treturn -1;\n-\t}\n+\tstatus = rte_swx_pipeline_build_from_lib(&p,\n+\t\t\t\t\t\t global_name,\n+\t\t\t\t\t\t lib_file_name,\n+\t\t\t\t\t\t iospec_file,\n+\t\t\t\t\t\t numa_node);\n+\tif (status)\n+\t\tgoto error;\n \n-\t/* Pipeline */\n-\ttable = &pipeline->table[pipeline->n_tables];\n-\tmemcpy(&table->params, params, sizeof(*params));\n-\ttable->ap = ap;\n-\ttable->a = action;\n-\tTAILQ_INIT(&table->meter_profiles);\n-\tmemset(&table->dscp_table, 0, sizeof(table->dscp_table));\n-\tpipeline->n_tables++;\n+\tfclose(iospec_file);\n+\tiospec_file = NULL;\n \n-\treturn 0;\n-}\n+\tctl = rte_swx_ctl_pipeline_create(p);\n+\tif (!ctl)\n+\t\tgoto error;\n \n-int\n-softnic_pipeline_port_out_find(struct pmd_internals *softnic,\n-\t\tconst char *pipeline_name,\n-\t\tconst char *name,\n-\t\tuint32_t *port_id)\n-{\n-\tstruct pipeline *pipeline;\n-\tuint32_t i;\n-\n-\tif (softnic == NULL ||\n-\t\t\tpipeline_name == NULL ||\n-\t\t\tname == NULL ||\n-\t\t\tport_id == NULL)\n-\t\treturn -1;\n-\n-\tpipeline = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (pipeline == NULL)\n-\t\treturn -1;\n-\n-\tfor (i = 0; i < pipeline->n_ports_out; i++)\n-\t\tif (strcmp(pipeline->port_out[i].params.dev_name, name) == 0) {\n-\t\t\t*port_id = i;\n-\t\t\treturn 0;\n-\t\t}\n+\t/* Node allocation */\n+\tpipeline = calloc(1, sizeof(struct pipeline));\n+\tif (!pipeline)\n+\t\tgoto error;\n \n-\treturn -1;\n-}\n+\t/* Node fill in */\n+\tstrlcpy(pipeline->name, name, sizeof(pipeline->name));\n+\tpipeline->p = p;\n+\tpipeline->ctl = ctl;\n \n-struct softnic_table_meter_profile *\n-softnic_pipeline_table_meter_profile_find(struct softnic_table *table,\n-\tuint32_t meter_profile_id)\n-{\n-\tstruct softnic_table_meter_profile *mp;\n+\t/* Node add to list */\n+\tTAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);\n \n-\tTAILQ_FOREACH(mp, &table->meter_profiles, node)\n-\t\tif (mp->meter_profile_id == meter_profile_id)\n-\t\t\treturn mp;\n+\treturn pipeline;\n \n+error:\n+\tfree(pipeline);\n+\trte_swx_ctl_pipeline_free(ctl);\n+\trte_swx_pipeline_free(p);\n+\tif (iospec_file)\n+\t\tfclose(iospec_file);\n \treturn NULL;\n }\ndiff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c\nindex ec8bef4694..888af6caf4 100644\n--- a/drivers/net/softnic/rte_eth_softnic_thread.c\n+++ b/drivers/net/softnic/rte_eth_softnic_thread.c\n@@ -10,11 +10,6 @@\n #include <rte_service_component.h>\n #include <rte_ring.h>\n \n-#include <rte_table_acl.h>\n-#include <rte_table_array.h>\n-#include <rte_table_hash.h>\n-#include <rte_table_lpm.h>\n-#include <rte_table_lpm_ipv6.h>\n #include \"rte_eth_softnic_internals.h\"\n \n /**\n@@ -88,7 +83,6 @@ softnic_thread_init(struct pmd_internals *softnic)\n \t\tt_data->timer_period =\n \t\t\t(rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;\n \t\tt_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;\n-\t\tt_data->time_next_min = t_data->time_next;\n \t}\n \n \treturn 0;\n@@ -97,6 +91,9 @@ softnic_thread_init(struct pmd_internals *softnic)\n static inline int\n thread_is_valid(struct pmd_internals *softnic, uint32_t thread_id)\n {\n+\tif (thread_id >= RTE_MAX_LCORE)\n+\t\treturn 0; /* FALSE */\n+\n \tif (thread_id == rte_get_main_lcore())\n \t\treturn 0; /* FALSE */\n \n@@ -190,18 +187,22 @@ thread_sc_service_down(struct pmd_internals *softnic, uint32_t thread_id)\n \tt->service_id = UINT32_MAX;\n }\n \n-/**\n- * Pipeline is running when:\n- *    (A) Pipeline is mapped to a data plane thread AND\n- *    (B) Its data plane thread is in RUNNING state.\n- */\n-static inline int\n-pipeline_is_running(struct pipeline *p)\n+void\n+softnic_thread_pipeline_disable_all(struct pmd_internals *softnic)\n {\n-\tif (p->enabled == 0)\n-\t\treturn 0;\n+\tuint32_t thread_id;\n \n-\treturn thread_is_running(p->thread_id);\n+\tfor (thread_id = 0; thread_id < RTE_MAX_LCORE; thread_id++) {\n+\t\tstruct softnic_thread_data *td = &softnic->thread_data[thread_id];\n+\n+\t\tif (!thread_is_valid(softnic, thread_id))\n+\t\t\tcontinue;\n+\n+\t\tif (softnic->params.sc && td->n_pipelines)\n+\t\t\tthread_sc_service_down(softnic, thread_id);\n+\n+\t\ttd->n_pipelines = 0;\n+\t}\n }\n \n /**\n@@ -218,18 +219,11 @@ struct thread_msg_req {\n \n \tunion {\n \t\tstruct {\n-\t\t\tstruct rte_pipeline *p;\n-\t\t\tstruct {\n-\t\t\t\tstruct rte_table_action *a;\n-\t\t\t} table[RTE_PIPELINE_TABLE_MAX];\n-\t\t\tstruct rte_ring *msgq_req;\n-\t\t\tstruct rte_ring *msgq_rsp;\n-\t\t\tuint32_t timer_period_ms;\n-\t\t\tuint32_t n_tables;\n+\t\t\tstruct rte_swx_pipeline *p;\n \t\t} pipeline_enable;\n \n \t\tstruct {\n-\t\t\tstruct rte_pipeline *p;\n+\t\t\tstruct rte_swx_pipeline *p;\n \t\t} pipeline_disable;\n \t};\n };\n@@ -283,20 +277,16 @@ thread_msg_send_recv(struct pmd_internals *softnic,\n int\n softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n \tuint32_t thread_id,\n-\tconst char *pipeline_name)\n+\tstruct pipeline *p)\n {\n-\tstruct pipeline *p = softnic_pipeline_find(softnic, pipeline_name);\n \tstruct thread_msg_req *req;\n \tstruct thread_msg_rsp *rsp;\n-\tuint32_t n_pipelines, i;\n+\tuint32_t n_pipelines;\n \tint status;\n \n \t/* Check input params */\n \tif (!thread_is_valid(softnic, thread_id) ||\n \t\t(p == NULL) ||\n-\t\t(p->n_ports_in == 0) ||\n-\t\t(p->n_ports_out == 0) ||\n-\t\t(p->n_tables == 0) ||\n \t\tp->enabled)\n \t\treturn -1;\n \n@@ -312,22 +302,9 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n \n \tif (!thread_is_running(thread_id)) {\n \t\tstruct softnic_thread_data *td = &softnic->thread_data[thread_id];\n-\t\tstruct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];\n \n \t\t/* Data plane thread */\n \t\ttd->p[td->n_pipelines] = p->p;\n-\n-\t\ttdp->p = p->p;\n-\t\tfor (i = 0; i < p->n_tables; i++)\n-\t\t\ttdp->table_data[i].a =\n-\t\t\t\tp->table[i].a;\n-\t\ttdp->n_tables = p->n_tables;\n-\n-\t\ttdp->msgq_req = p->msgq_req;\n-\t\ttdp->msgq_rsp = p->msgq_rsp;\n-\t\ttdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;\n-\t\ttdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;\n-\n \t\ttd->n_pipelines++;\n \n \t\t/* Pipeline */\n@@ -345,13 +322,6 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n \t/* Write request */\n \treq->type = THREAD_REQ_PIPELINE_ENABLE;\n \treq->pipeline_enable.p = p->p;\n-\tfor (i = 0; i < p->n_tables; i++)\n-\t\treq->pipeline_enable.table[i].a =\n-\t\t\tp->table[i].a;\n-\treq->pipeline_enable.msgq_req = p->msgq_req;\n-\treq->pipeline_enable.msgq_rsp = p->msgq_rsp;\n-\treq->pipeline_enable.timer_period_ms = p->timer_period_ms;\n-\treq->pipeline_enable.n_tables = p->n_tables;\n \n \t/* Send request and wait for response */\n \trsp = thread_msg_send_recv(softnic, thread_id, req);\n@@ -375,9 +345,8 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n int\n softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \tuint32_t thread_id,\n-\tconst char *pipeline_name)\n+\tstruct pipeline *p)\n {\n-\tstruct pipeline *p = softnic_pipeline_find(softnic, pipeline_name);\n \tstruct thread_msg_req *req;\n \tstruct thread_msg_rsp *rsp;\n \tuint32_t n_pipelines;\n@@ -397,21 +366,12 @@ softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \t\tuint32_t i;\n \n \t\tfor (i = 0; i < td->n_pipelines; i++) {\n-\t\t\tstruct pipeline_data *tdp = &td->pipeline_data[i];\n-\n-\t\t\tif (tdp->p != p->p)\n+\t\t\tif (td->p[i] != p->p)\n \t\t\t\tcontinue;\n \n \t\t\t/* Data plane thread */\n-\t\t\tif (i < td->n_pipelines - 1) {\n-\t\t\t\tstruct rte_pipeline *pipeline_last =\n-\t\t\t\t\ttd->p[td->n_pipelines - 1];\n-\t\t\t\tstruct pipeline_data *tdp_last =\n-\t\t\t\t\t&td->pipeline_data[td->n_pipelines - 1];\n-\n-\t\t\t\ttd->p[i] = pipeline_last;\n-\t\t\t\tmemcpy(tdp, tdp_last, sizeof(*tdp));\n-\t\t\t}\n+\t\t\tif (i < td->n_pipelines - 1)\n+\t\t\t\ttd->p[i] = td->p[td->n_pipelines - 1];\n \n \t\t\ttd->n_pipelines--;\n \n@@ -490,25 +450,9 @@ thread_msg_handle_pipeline_enable(struct softnic_thread_data *t,\n \tstruct thread_msg_req *req)\n {\n \tstruct thread_msg_rsp *rsp = (struct thread_msg_rsp *)req;\n-\tstruct pipeline_data *p = &t->pipeline_data[t->n_pipelines];\n-\tuint32_t i;\n \n \t/* Request */\n \tt->p[t->n_pipelines] = req->pipeline_enable.p;\n-\n-\tp->p = req->pipeline_enable.p;\n-\tfor (i = 0; i < req->pipeline_enable.n_tables; i++)\n-\t\tp->table_data[i].a =\n-\t\t\treq->pipeline_enable.table[i].a;\n-\n-\tp->n_tables = req->pipeline_enable.n_tables;\n-\n-\tp->msgq_req = req->pipeline_enable.msgq_req;\n-\tp->msgq_rsp = req->pipeline_enable.msgq_rsp;\n-\tp->timer_period =\n-\t\t(rte_get_tsc_hz() * req->pipeline_enable.timer_period_ms) / 1000;\n-\tp->time_next = rte_get_tsc_cycles() + p->timer_period;\n-\n \tt->n_pipelines++;\n \n \t/* Response */\n@@ -522,25 +466,16 @@ thread_msg_handle_pipeline_disable(struct softnic_thread_data *t,\n {\n \tstruct thread_msg_rsp *rsp = (struct thread_msg_rsp *)req;\n \tuint32_t n_pipelines = t->n_pipelines;\n-\tstruct rte_pipeline *pipeline = req->pipeline_disable.p;\n+\tstruct rte_swx_pipeline *pipeline = req->pipeline_disable.p;\n \tuint32_t i;\n \n \t/* find pipeline */\n \tfor (i = 0; i < n_pipelines; i++) {\n-\t\tstruct pipeline_data *p = &t->pipeline_data[i];\n-\n-\t\tif (p->p != pipeline)\n+\t\tif (t->p[i] != pipeline)\n \t\t\tcontinue;\n \n-\t\tif (i < n_pipelines - 1) {\n-\t\t\tstruct rte_pipeline *pipeline_last =\n-\t\t\t\tt->p[n_pipelines - 1];\n-\t\t\tstruct pipeline_data *p_last =\n-\t\t\t\t&t->pipeline_data[n_pipelines - 1];\n-\n-\t\t\tt->p[i] = pipeline_last;\n-\t\t\tmemcpy(p, p_last, sizeof(*p));\n-\t\t}\n+\t\tif (i < n_pipelines - 1)\n+\t\t\tt->p[i] = t->p[n_pipelines - 1];\n \n \t\tt->n_pipelines--;\n \n@@ -583,2464 +518,37 @@ thread_msg_handle(struct softnic_thread_data *t)\n }\n \n /**\n- * Main thread & data plane threads: message passing\n- */\n-enum pipeline_req_type {\n-\t/* Port IN */\n-\tPIPELINE_REQ_PORT_IN_STATS_READ,\n-\tPIPELINE_REQ_PORT_IN_ENABLE,\n-\tPIPELINE_REQ_PORT_IN_DISABLE,\n-\n-\t/* Port OUT */\n-\tPIPELINE_REQ_PORT_OUT_STATS_READ,\n-\n-\t/* Table */\n-\tPIPELINE_REQ_TABLE_STATS_READ,\n-\tPIPELINE_REQ_TABLE_RULE_ADD,\n-\tPIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,\n-\tPIPELINE_REQ_TABLE_RULE_ADD_BULK,\n-\tPIPELINE_REQ_TABLE_RULE_DELETE,\n-\tPIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,\n-\tPIPELINE_REQ_TABLE_RULE_STATS_READ,\n-\tPIPELINE_REQ_TABLE_MTR_PROFILE_ADD,\n-\tPIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,\n-\tPIPELINE_REQ_TABLE_RULE_MTR_READ,\n-\tPIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,\n-\tPIPELINE_REQ_TABLE_RULE_TTL_READ,\n-\tPIPELINE_REQ_MAX\n-};\n-\n-struct pipeline_msg_req_port_in_stats_read {\n-\tint clear;\n-};\n-\n-struct pipeline_msg_req_port_out_stats_read {\n-\tint clear;\n-};\n-\n-struct pipeline_msg_req_table_stats_read {\n-\tint clear;\n-};\n-\n-struct pipeline_msg_req_table_rule_add {\n-\tstruct softnic_table_rule_match match;\n-\tstruct softnic_table_rule_action action;\n-};\n-\n-struct pipeline_msg_req_table_rule_add_default {\n-\tstruct softnic_table_rule_action action;\n-};\n-\n-struct pipeline_msg_req_table_rule_add_bulk {\n-\tstruct softnic_table_rule_match *match;\n-\tstruct softnic_table_rule_action *action;\n-\tvoid **data;\n-\tuint32_t n_rules;\n-\tint bulk;\n-};\n-\n-struct pipeline_msg_req_table_rule_delete {\n-\tstruct softnic_table_rule_match match;\n-};\n-\n-struct pipeline_msg_req_table_rule_stats_read {\n-\tvoid *data;\n-\tint clear;\n-};\n-\n-struct pipeline_msg_req_table_mtr_profile_add {\n-\tuint32_t meter_profile_id;\n-\tstruct rte_table_action_meter_profile profile;\n-};\n-\n-struct pipeline_msg_req_table_mtr_profile_delete {\n-\tuint32_t meter_profile_id;\n-};\n-\n-struct pipeline_msg_req_table_rule_mtr_read {\n-\tvoid *data;\n-\tuint32_t tc_mask;\n-\tint clear;\n-};\n-\n-struct pipeline_msg_req_table_dscp_table_update {\n-\tuint64_t dscp_mask;\n-\tstruct rte_table_action_dscp_table dscp_table;\n-};\n-\n-struct pipeline_msg_req_table_rule_ttl_read {\n-\tvoid *data;\n-\tint clear;\n-};\n-\n-struct pipeline_msg_req {\n-\tenum pipeline_req_type type;\n-\tuint32_t id; /* Port IN, port OUT or table ID */\n-\n-\tRTE_STD_C11\n-\tunion {\n-\t\tstruct pipeline_msg_req_port_in_stats_read port_in_stats_read;\n-\t\tstruct pipeline_msg_req_port_out_stats_read port_out_stats_read;\n-\t\tstruct pipeline_msg_req_table_stats_read table_stats_read;\n-\t\tstruct pipeline_msg_req_table_rule_add table_rule_add;\n-\t\tstruct pipeline_msg_req_table_rule_add_default table_rule_add_default;\n-\t\tstruct pipeline_msg_req_table_rule_add_bulk table_rule_add_bulk;\n-\t\tstruct pipeline_msg_req_table_rule_delete table_rule_delete;\n-\t\tstruct pipeline_msg_req_table_rule_stats_read table_rule_stats_read;\n-\t\tstruct pipeline_msg_req_table_mtr_profile_add table_mtr_profile_add;\n-\t\tstruct pipeline_msg_req_table_mtr_profile_delete table_mtr_profile_delete;\n-\t\tstruct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;\n-\t\tstruct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;\n-\t\tstruct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;\n-\t};\n-};\n-\n-struct pipeline_msg_rsp_port_in_stats_read {\n-\tstruct rte_pipeline_port_in_stats stats;\n-};\n-\n-struct pipeline_msg_rsp_port_out_stats_read {\n-\tstruct rte_pipeline_port_out_stats stats;\n-};\n-\n-struct pipeline_msg_rsp_table_stats_read {\n-\tstruct rte_pipeline_table_stats stats;\n-};\n-\n-struct pipeline_msg_rsp_table_rule_add {\n-\tvoid *data;\n-};\n-\n-struct pipeline_msg_rsp_table_rule_add_default {\n-\tvoid *data;\n-};\n-\n-struct pipeline_msg_rsp_table_rule_add_bulk {\n-\tuint32_t n_rules;\n-};\n-\n-struct pipeline_msg_rsp_table_rule_stats_read {\n-\tstruct rte_table_action_stats_counters stats;\n-};\n-\n-struct pipeline_msg_rsp_table_rule_mtr_read {\n-\tstruct rte_table_action_mtr_counters stats;\n-};\n-\n-struct pipeline_msg_rsp_table_rule_ttl_read {\n-\tstruct rte_table_action_ttl_counters stats;\n-};\n-\n-struct pipeline_msg_rsp {\n-\tint status;\n-\n-\tRTE_STD_C11\n-\tunion {\n-\t\tstruct pipeline_msg_rsp_port_in_stats_read port_in_stats_read;\n-\t\tstruct pipeline_msg_rsp_port_out_stats_read port_out_stats_read;\n-\t\tstruct pipeline_msg_rsp_table_stats_read table_stats_read;\n-\t\tstruct pipeline_msg_rsp_table_rule_add table_rule_add;\n-\t\tstruct pipeline_msg_rsp_table_rule_add_default table_rule_add_default;\n-\t\tstruct pipeline_msg_rsp_table_rule_add_bulk table_rule_add_bulk;\n-\t\tstruct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;\n-\t\tstruct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;\n-\t\tstruct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;\n-\t};\n-};\n-\n-/**\n- * Main thread\n+ * Data plane threads: main\n  */\n-static struct pipeline_msg_req *\n-pipeline_msg_alloc(void)\n-{\n-\tsize_t size = RTE_MAX(sizeof(struct pipeline_msg_req),\n-\t\tsizeof(struct pipeline_msg_rsp));\n-\n-\treturn calloc(1, size);\n-}\n-\n-static void\n-pipeline_msg_free(struct pipeline_msg_rsp *rsp)\n-{\n-\tfree(rsp);\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_send_recv(struct pipeline *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct rte_ring *msgq_req = p->msgq_req;\n-\tstruct rte_ring *msgq_rsp = p->msgq_rsp;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* send */\n-\tdo {\n-\t\tstatus = rte_ring_sp_enqueue(msgq_req, req);\n-\t} while (status == -ENOBUFS);\n-\n-\t/* recv */\n-\tdo {\n-\t\tstatus = rte_ring_sc_dequeue(msgq_rsp, (void **)&rsp);\n-\t} while (status != 0);\n-\n-\treturn rsp;\n-}\n-\n-int\n-softnic_pipeline_port_in_stats_read(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id,\n-\tstruct rte_pipeline_port_in_stats *stats,\n-\tint clear)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tstats == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\tport_id >= p->n_ports_in)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_pipeline_port_in_stats_read(p->p,\n-\t\t\tport_id,\n-\t\t\tstats,\n-\t\t\tclear);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_PORT_IN_STATS_READ;\n-\treq->id = port_id;\n-\treq->port_in_stats_read.clear = clear;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status)\n-\t\tmemcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_port_in_enable(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\tport_id >= p->n_ports_in)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_pipeline_port_in_enable(p->p, port_id);\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_PORT_IN_ENABLE;\n-\treq->id = port_id;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_port_in_disable(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\tport_id >= p->n_ports_in)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_pipeline_port_in_disable(p->p, port_id);\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_PORT_IN_DISABLE;\n-\treq->id = port_id;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_port_out_stats_read(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t port_id,\n-\tstruct rte_pipeline_port_out_stats *stats,\n-\tint clear)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tstats == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\tport_id >= p->n_ports_out)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_pipeline_port_out_stats_read(p->p,\n-\t\t\tport_id,\n-\t\t\tstats,\n-\t\t\tclear);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_PORT_OUT_STATS_READ;\n-\treq->id = port_id;\n-\treq->port_out_stats_read.clear = clear;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status)\n-\t\tmemcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_stats_read(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct rte_pipeline_table_stats *stats,\n-\tint clear)\n+static int32_t\n+rte_pmd_softnic_run_internal(void *arg)\n {\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tstats == NULL)\n-\t\treturn -1;\n+\tstruct rte_eth_dev *dev = arg;\n+\tstruct pmd_internals *softnic;\n+\tstruct softnic_thread_data *t;\n+\tuint32_t thread_id, j;\n \n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n+\tsoftnic = dev->data->dev_private;\n+\tthread_id = rte_lcore_id();\n+\tt = &softnic->thread_data[thread_id];\n+\tt->iter++;\n \n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_pipeline_table_stats_read(p->p,\n-\t\t\ttable_id,\n-\t\t\tstats,\n-\t\t\tclear);\n+\t/* Data Plane */\n+\tfor (j = 0; j < t->n_pipelines; j++)\n+\t\trte_swx_pipeline_run(t->p[j], PIPELINE_INSTR_QUANTA);\n \n-\t\treturn status;\n-\t}\n+\t/* Control Plane */\n+\tif ((t->iter & 0xFLLU) == 0) {\n+\t\tuint64_t time = rte_get_tsc_cycles();\n+\t\tuint64_t time_next = t->time_next;\n \n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_STATS_READ;\n-\treq->id = table_id;\n-\treq->table_stats_read.clear = clear;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status)\n-\t\tmemcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-static int\n-match_check(struct softnic_table_rule_match *match,\n-\tstruct pipeline *p,\n-\tuint32_t table_id)\n-{\n-\tstruct softnic_table *table;\n-\n-\tif (match == NULL ||\n-\t\tp == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\ttable = &p->table[table_id];\n-\tif (match->match_type != table->params.match_type)\n-\t\treturn -1;\n-\n-\tswitch (match->match_type) {\n-\tcase TABLE_ACL:\n-\t{\n-\t\tstruct softnic_table_acl_params *t = &table->params.match.acl;\n-\t\tstruct softnic_table_rule_match_acl *r = &match->match.acl;\n-\n-\t\tif ((r->ip_version && (t->ip_version == 0)) ||\n-\t\t\t((r->ip_version == 0) && t->ip_version))\n-\t\t\treturn -1;\n-\n-\t\tif (r->ip_version) {\n-\t\t\tif (r->sa_depth > 32 ||\n-\t\t\t\tr->da_depth > 32)\n-\t\t\t\treturn -1;\n-\t\t} else {\n-\t\t\tif (r->sa_depth > 128 ||\n-\t\t\t\tr->da_depth > 128)\n-\t\t\t\treturn -1;\n-\t\t}\n-\t\treturn 0;\n-\t}\n-\n-\tcase TABLE_ARRAY:\n-\t\treturn 0;\n-\n-\tcase TABLE_HASH:\n-\t\treturn 0;\n-\n-\tcase TABLE_LPM:\n-\t{\n-\t\tstruct softnic_table_lpm_params *t = &table->params.match.lpm;\n-\t\tstruct softnic_table_rule_match_lpm *r = &match->match.lpm;\n-\n-\t\tif ((r->ip_version && (t->key_size != 4)) ||\n-\t\t\t((r->ip_version == 0) && (t->key_size != 16)))\n-\t\t\treturn -1;\n-\n-\t\tif (r->ip_version) {\n-\t\t\tif (r->depth > 32)\n-\t\t\t\treturn -1;\n-\t\t} else {\n-\t\t\tif (r->depth > 128)\n-\t\t\t\treturn -1;\n-\t\t}\n-\t\treturn 0;\n-\t}\n-\n-\tcase TABLE_STUB:\n-\t\treturn -1;\n-\n-\tdefault:\n-\t\treturn -1;\n-\t}\n-}\n-\n-static int\n-action_check(struct softnic_table_rule_action *action,\n-\tstruct pipeline *p,\n-\tuint32_t table_id)\n-{\n-\tstruct softnic_table_action_profile *ap;\n-\n-\tif (action == NULL ||\n-\t\tp == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tap = p->table[table_id].ap;\n-\tif (action->action_mask != ap->params.action_mask)\n-\t\treturn -1;\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {\n-\t\tif (action->fwd.action == RTE_PIPELINE_ACTION_PORT &&\n-\t\t\taction->fwd.id >= p->n_ports_out)\n-\t\t\treturn -1;\n-\n-\t\tif (action->fwd.action == RTE_PIPELINE_ACTION_TABLE &&\n-\t\t\taction->fwd.id >= p->n_tables)\n-\t\t\treturn -1;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {\n-\t\tuint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;\n-\t\tuint32_t tc_mask1 = action->mtr.tc_mask;\n-\n-\t\tif (tc_mask1 != tc_mask0)\n-\t\t\treturn -1;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {\n-\t\tuint32_t n_subports_per_port =\n-\t\t\tap->params.tm.n_subports_per_port;\n-\t\tuint32_t n_pipes_per_subport =\n-\t\t\tap->params.tm.n_pipes_per_subport;\n-\t\tuint32_t subport_id = action->tm.subport_id;\n-\t\tuint32_t pipe_id = action->tm.pipe_id;\n-\n-\t\tif (subport_id >= n_subports_per_port ||\n-\t\t\tpipe_id >= n_pipes_per_subport)\n-\t\t\treturn -1;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {\n-\t\tuint64_t encap_mask = ap->params.encap.encap_mask;\n-\t\tenum rte_table_action_encap_type type = action->encap.type;\n-\n-\t\tif ((encap_mask & (1LLU << type)) == 0)\n-\t\t\treturn -1;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {\n-\t\tint ip_version0 = ap->params.common.ip_version;\n-\t\tint ip_version1 = action->nat.ip_version;\n-\n-\t\tif ((ip_version1 && (ip_version0 == 0)) ||\n-\t\t\t((ip_version1 == 0) && ip_version0))\n-\t\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static int\n-action_default_check(struct softnic_table_rule_action *action,\n-\tstruct pipeline *p,\n-\tuint32_t table_id)\n-{\n-\tif (action == NULL ||\n-\t\taction->action_mask != (1LLU << RTE_TABLE_ACTION_FWD) ||\n-\t\tp == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {\n-\t\tif (action->fwd.action == RTE_PIPELINE_ACTION_PORT &&\n-\t\t\taction->fwd.id >= p->n_ports_out)\n-\t\t\treturn -1;\n-\n-\t\tif (action->fwd.action == RTE_PIPELINE_ACTION_TABLE &&\n-\t\t\taction->fwd.id >= p->n_tables)\n-\t\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-union table_rule_match_low_level {\n-\tstruct rte_table_acl_rule_add_params acl_add;\n-\tstruct rte_table_acl_rule_delete_params acl_delete;\n-\tstruct rte_table_array_key array;\n-\tuint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];\n-\tstruct rte_table_lpm_key lpm_ipv4;\n-\tstruct rte_table_lpm_ipv6_key lpm_ipv6;\n-};\n-\n-static int\n-match_convert(struct softnic_table_rule_match *mh,\n-\tunion table_rule_match_low_level *ml,\n-\tint add);\n-\n-static int\n-action_convert(struct rte_table_action *a,\n-\tstruct softnic_table_rule_action *action,\n-\tstruct rte_pipeline_table_entry *data);\n-\n-int\n-softnic_pipeline_table_rule_add(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_match *match,\n-\tstruct softnic_table_rule_action *action,\n-\tvoid **data)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tmatch == NULL ||\n-\t\taction == NULL ||\n-\t\tdata == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables ||\n-\t\tmatch_check(match, p, table_id) ||\n-\t\taction_check(action, p, table_id))\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\t\tunion table_rule_match_low_level match_ll;\n-\t\tstruct rte_pipeline_table_entry *data_in, *data_out;\n-\t\tint key_found;\n-\t\tuint8_t *buffer;\n-\n-\t\tbuffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));\n-\t\tif (buffer == NULL)\n-\t\t\treturn -1;\n-\n-\t\t/* Table match-action rule conversion */\n-\t\tdata_in = (struct rte_pipeline_table_entry *)buffer;\n-\n-\t\tstatus = match_convert(match, &match_ll, 1);\n-\t\tif (status) {\n-\t\t\tfree(buffer);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tstatus = action_convert(a, action, data_in);\n-\t\tif (status) {\n-\t\t\tfree(buffer);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t/* Add rule (match, action) to table */\n-\t\tstatus = rte_pipeline_table_entry_add(p->p,\n-\t\t\t\ttable_id,\n-\t\t\t\t&match_ll,\n-\t\t\t\tdata_in,\n-\t\t\t\t&key_found,\n-\t\t\t\t&data_out);\n-\t\tif (status) {\n-\t\t\tfree(buffer);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t/* Write Response */\n-\t\t*data = data_out;\n-\n-\t\tfree(buffer);\n-\t\treturn 0;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_ADD;\n-\treq->id = table_id;\n-\tmemcpy(&req->table_rule_add.match, match, sizeof(*match));\n-\tmemcpy(&req->table_rule_add.action, action, sizeof(*action));\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status == 0)\n-\t\t*data = rsp->table_rule_add.data;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_action *action,\n-\tvoid **data)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\taction == NULL ||\n-\t\tdata == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables ||\n-\t\taction_default_check(action, p, table_id))\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_pipeline_table_entry *data_in, *data_out;\n-\t\tuint8_t *buffer;\n-\n-\t\tbuffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));\n-\t\tif (buffer == NULL)\n-\t\t\treturn -1;\n-\n-\t\t/* Apply actions */\n-\t\tdata_in = (struct rte_pipeline_table_entry *)buffer;\n-\n-\t\tdata_in->action = action->fwd.action;\n-\t\tif (action->fwd.action == RTE_PIPELINE_ACTION_PORT)\n-\t\t\tdata_in->port_id = action->fwd.id;\n-\t\tif (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)\n-\t\t\tdata_in->table_id = action->fwd.id;\n-\n-\t\t/* Add default rule to table */\n-\t\tstatus = rte_pipeline_table_default_entry_add(p->p,\n-\t\t\t\ttable_id,\n-\t\t\t\tdata_in,\n-\t\t\t\t&data_out);\n-\t\tif (status) {\n-\t\t\tfree(buffer);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\t/* Write Response */\n-\t\t*data = data_out;\n-\n-\t\tfree(buffer);\n-\t\treturn 0;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;\n-\treq->id = table_id;\n-\tmemcpy(&req->table_rule_add_default.action, action, sizeof(*action));\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status == 0)\n-\t\t*data = rsp->table_rule_add_default.data;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_match *match,\n-\tstruct softnic_table_rule_action *action,\n-\tvoid **data,\n-\tuint32_t *n_rules)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tuint32_t i;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tmatch == NULL ||\n-\t\taction == NULL ||\n-\t\tdata == NULL ||\n-\t\tn_rules == NULL ||\n-\t\t(*n_rules == 0))\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tfor (i = 0; i < *n_rules; i++)\n-\t\tif (match_check(match, p, table_id) ||\n-\t\t\taction_check(action, p, table_id))\n-\t\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\t\tunion table_rule_match_low_level *match_ll;\n-\t\tuint8_t *action_ll;\n-\t\tvoid **match_ll_ptr;\n-\t\tstruct rte_pipeline_table_entry **action_ll_ptr;\n-\t\tstruct rte_pipeline_table_entry **entries_ptr =\n-\t\t\t(struct rte_pipeline_table_entry **)data;\n-\t\tuint32_t bulk =\n-\t\t\t(p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;\n-\t\tint *found;\n-\n-\t\t/* Memory allocation */\n-\t\tmatch_ll = calloc(*n_rules, sizeof(union table_rule_match_low_level));\n-\t\taction_ll = calloc(*n_rules, TABLE_RULE_ACTION_SIZE_MAX);\n-\t\tmatch_ll_ptr = calloc(*n_rules, sizeof(void *));\n-\t\taction_ll_ptr =\n-\t\t\tcalloc(*n_rules, sizeof(struct rte_pipeline_table_entry *));\n-\t\tfound = calloc(*n_rules, sizeof(int));\n-\n-\t\tif (match_ll == NULL ||\n-\t\t\taction_ll == NULL ||\n-\t\t\tmatch_ll_ptr == NULL ||\n-\t\t\taction_ll_ptr == NULL ||\n-\t\t\tfound == NULL)\n-\t\t\tgoto fail;\n-\n-\t\tfor (i = 0; i < *n_rules; i++) {\n-\t\t\tmatch_ll_ptr[i] = (void *)&match_ll[i];\n-\t\t\taction_ll_ptr[i] =\n-\t\t\t\t(struct rte_pipeline_table_entry *)&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];\n-\t\t}\n-\n-\t\t/* Rule match conversion */\n-\t\tfor (i = 0; i < *n_rules; i++) {\n-\t\t\tstatus = match_convert(&match[i], match_ll_ptr[i], 1);\n-\t\t\tif (status)\n-\t\t\t\tgoto fail;\n-\t\t}\n-\n-\t\t/* Rule action conversion */\n-\t\tfor (i = 0; i < *n_rules; i++) {\n-\t\t\tstatus = action_convert(a, &action[i], action_ll_ptr[i]);\n-\t\t\tif (status)\n-\t\t\t\tgoto fail;\n-\t\t}\n-\n-\t\t/* Add rule (match, action) to table */\n-\t\tif (bulk) {\n-\t\t\tstatus = rte_pipeline_table_entry_add_bulk(p->p,\n-\t\t\t\ttable_id,\n-\t\t\t\tmatch_ll_ptr,\n-\t\t\t\taction_ll_ptr,\n-\t\t\t\t*n_rules,\n-\t\t\t\tfound,\n-\t\t\t\tentries_ptr);\n-\t\t\tif (status)\n-\t\t\t\t*n_rules = 0;\n-\t\t} else {\n-\t\t\tfor (i = 0; i < *n_rules; i++) {\n-\t\t\t\tstatus = rte_pipeline_table_entry_add(p->p,\n-\t\t\t\t\ttable_id,\n-\t\t\t\t\tmatch_ll_ptr[i],\n-\t\t\t\t\taction_ll_ptr[i],\n-\t\t\t\t\t&found[i],\n-\t\t\t\t\t&entries_ptr[i]);\n-\t\t\t\tif (status) {\n-\t\t\t\t\t*n_rules = i;\n-\t\t\t\t\tbreak;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t}\n-\n-\t\t/* Free */\n-\t\tfree(found);\n-\t\tfree(action_ll_ptr);\n-\t\tfree(match_ll_ptr);\n-\t\tfree(action_ll);\n-\t\tfree(match_ll);\n-\n-\t\treturn status;\n-\n-fail:\n-\t\tfree(found);\n-\t\tfree(action_ll_ptr);\n-\t\tfree(match_ll_ptr);\n-\t\tfree(action_ll);\n-\t\tfree(match_ll);\n-\n-\t\t*n_rules = 0;\n-\t\treturn -1;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;\n-\treq->id = table_id;\n-\treq->table_rule_add_bulk.match = match;\n-\treq->table_rule_add_bulk.action = action;\n-\treq->table_rule_add_bulk.data = data;\n-\treq->table_rule_add_bulk.n_rules = *n_rules;\n-\treq->table_rule_add_bulk.bulk =\n-\t\t(p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status == 0)\n-\t\t*n_rules = rsp->table_rule_add_bulk.n_rules;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tstruct softnic_table_rule_match *match)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tmatch == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables ||\n-\t\tmatch_check(match, p, table_id))\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tunion table_rule_match_low_level match_ll;\n-\t\tint key_found;\n-\n-\t\tstatus = match_convert(match, &match_ll, 0);\n-\t\tif (status)\n-\t\t\treturn -1;\n-\n-\t\tstatus = rte_pipeline_table_entry_delete(p->p,\n-\t\t\t\ttable_id,\n-\t\t\t\t&match_ll,\n-\t\t\t\t&key_found,\n-\t\t\t\tNULL);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_DELETE;\n-\treq->id = table_id;\n-\tmemcpy(&req->table_rule_delete.match, match, sizeof(*match));\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_pipeline_table_default_entry_delete(p->p,\n-\t\t\ttable_id,\n-\t\t\tNULL);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT;\n-\treq->id = table_id;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tvoid *data,\n-\tstruct rte_table_action_stats_counters *stats,\n-\tint clear)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tdata == NULL ||\n-\t\tstats == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\n-\t\tstatus = rte_table_action_stats_read(a,\n-\t\t\tdata,\n-\t\t\tstats,\n-\t\t\tclear);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;\n-\treq->id = table_id;\n-\treq->table_rule_stats_read.data = data;\n-\treq->table_rule_stats_read.clear = clear;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status)\n-\t\tmemcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tuint32_t meter_profile_id,\n-\tstruct rte_table_action_meter_profile *profile)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tstruct softnic_table *table;\n-\tstruct softnic_table_meter_profile *mp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tprofile == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\ttable = &p->table[table_id];\n-\tmp = softnic_pipeline_table_meter_profile_find(table, meter_profile_id);\n-\tif (mp)\n-\t\treturn -1;\n-\n-\t/* Resource Allocation */\n-\tmp = calloc(1, sizeof(struct softnic_table_meter_profile));\n-\tif (mp == NULL)\n-\t\treturn -1;\n-\n-\tmp->meter_profile_id = meter_profile_id;\n-\tmemcpy(&mp->profile, profile, sizeof(mp->profile));\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstatus = rte_table_action_meter_profile_add(table->a,\n-\t\t\tmeter_profile_id,\n-\t\t\tprofile);\n-\t\tif (status) {\n-\t\t\tfree(mp);\n-\t\t\treturn status;\n-\t\t}\n-\n-\t\t/* Add profile to the table. */\n-\t\tTAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL) {\n-\t\tfree(mp);\n-\t\treturn -1;\n-\t}\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;\n-\treq->id = table_id;\n-\treq->table_mtr_profile_add.meter_profile_id = meter_profile_id;\n-\tmemcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status == 0)\n-\t\tTAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);\n-\telse\n-\t\tfree(mp);\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_mtr_profile_delete(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tuint32_t meter_profile_id)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\n-\t\tstatus = rte_table_action_meter_profile_delete(a,\n-\t\t\t\tmeter_profile_id);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;\n-\treq->id = table_id;\n-\treq->table_mtr_profile_delete.meter_profile_id = meter_profile_id;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_mtr_read(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tvoid *data,\n-\tuint32_t tc_mask,\n-\tstruct rte_table_action_mtr_counters *stats,\n-\tint clear)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tdata == NULL ||\n-\t\tstats == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\n-\t\tstatus = rte_table_action_meter_read(a,\n-\t\t\t\tdata,\n-\t\t\t\ttc_mask,\n-\t\t\t\tstats,\n-\t\t\t\tclear);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;\n-\treq->id = table_id;\n-\treq->table_rule_mtr_read.data = data;\n-\treq->table_rule_mtr_read.tc_mask = tc_mask;\n-\treq->table_rule_mtr_read.clear = clear;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status)\n-\t\tmemcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tuint64_t dscp_mask,\n-\tstruct rte_table_action_dscp_table *dscp_table)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tdscp_table == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\n-\t\tstatus = rte_table_action_dscp_table_update(a,\n-\t\t\t\tdscp_mask,\n-\t\t\t\tdscp_table);\n-\n-\t\t/* Update table dscp table */\n-\t\tif (!status)\n-\t\t\tmemcpy(&p->table[table_id].dscp_table, dscp_table,\n-\t\t\t\tsizeof(p->table[table_id].dscp_table));\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;\n-\treq->id = table_id;\n-\treq->table_dscp_table_update.dscp_mask = dscp_mask;\n-\tmemcpy(&req->table_dscp_table_update.dscp_table,\n-\t\tdscp_table, sizeof(*dscp_table));\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\n-\t/* Update table dscp table */\n-\tif (!status)\n-\t\tmemcpy(&p->table[table_id].dscp_table, dscp_table,\n-\t\t\tsizeof(p->table[table_id].dscp_table));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-int\n-softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic,\n-\tconst char *pipeline_name,\n-\tuint32_t table_id,\n-\tvoid *data,\n-\tstruct rte_table_action_ttl_counters *stats,\n-\tint clear)\n-{\n-\tstruct pipeline *p;\n-\tstruct pipeline_msg_req *req;\n-\tstruct pipeline_msg_rsp *rsp;\n-\tint status;\n-\n-\t/* Check input params */\n-\tif (pipeline_name == NULL ||\n-\t\tdata == NULL ||\n-\t\tstats == NULL)\n-\t\treturn -1;\n-\n-\tp = softnic_pipeline_find(softnic, pipeline_name);\n-\tif (p == NULL ||\n-\t\ttable_id >= p->n_tables)\n-\t\treturn -1;\n-\n-\tif (!pipeline_is_running(p)) {\n-\t\tstruct rte_table_action *a = p->table[table_id].a;\n-\n-\t\tstatus = rte_table_action_ttl_read(a,\n-\t\t\t\tdata,\n-\t\t\t\tstats,\n-\t\t\t\tclear);\n-\n-\t\treturn status;\n-\t}\n-\n-\t/* Allocate request */\n-\treq = pipeline_msg_alloc();\n-\tif (req == NULL)\n-\t\treturn -1;\n-\n-\t/* Write request */\n-\treq->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;\n-\treq->id = table_id;\n-\treq->table_rule_ttl_read.data = data;\n-\treq->table_rule_ttl_read.clear = clear;\n-\n-\t/* Send request and wait for response */\n-\trsp = pipeline_msg_send_recv(p, req);\n-\n-\t/* Read response */\n-\tstatus = rsp->status;\n-\tif (status)\n-\t\tmemcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));\n-\n-\t/* Free response */\n-\tpipeline_msg_free(rsp);\n-\n-\treturn status;\n-}\n-\n-/**\n- * Data plane threads: message handling\n- */\n-static inline struct pipeline_msg_req *\n-pipeline_msg_recv(struct rte_ring *msgq_req)\n-{\n-\tstruct pipeline_msg_req *req;\n-\n-\tint status = rte_ring_sc_dequeue(msgq_req, (void **)&req);\n-\n-\tif (status != 0)\n-\t\treturn NULL;\n-\n-\treturn req;\n-}\n-\n-static inline void\n-pipeline_msg_send(struct rte_ring *msgq_rsp,\n-\tstruct pipeline_msg_rsp *rsp)\n-{\n-\tint status;\n-\n-\tdo {\n-\t\tstatus = rte_ring_sp_enqueue(msgq_rsp, rsp);\n-\t} while (status == -ENOBUFS);\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_port_in_stats_read(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t port_id = req->id;\n-\tint clear = req->port_in_stats_read.clear;\n-\n-\trsp->status = rte_pipeline_port_in_stats_read(p->p,\n-\t\tport_id,\n-\t\t&rsp->port_in_stats_read.stats,\n-\t\tclear);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_port_in_enable(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t port_id = req->id;\n-\n-\trsp->status = rte_pipeline_port_in_enable(p->p,\n-\t\tport_id);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_port_in_disable(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t port_id = req->id;\n-\n-\trsp->status = rte_pipeline_port_in_disable(p->p,\n-\t\tport_id);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_port_out_stats_read(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t port_id = req->id;\n-\tint clear = req->port_out_stats_read.clear;\n-\n-\trsp->status = rte_pipeline_port_out_stats_read(p->p,\n-\t\tport_id,\n-\t\t&rsp->port_out_stats_read.stats,\n-\t\tclear);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_stats_read(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t port_id = req->id;\n-\tint clear = req->table_stats_read.clear;\n-\n-\trsp->status = rte_pipeline_table_stats_read(p->p,\n-\t\tport_id,\n-\t\t&rsp->table_stats_read.stats,\n-\t\tclear);\n-\n-\treturn rsp;\n-}\n-\n-static int\n-match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)\n-{\n-\tif (depth > 128)\n-\t\treturn -1;\n-\n-\tswitch (depth / 32) {\n-\tcase 0:\n-\t\tdepth32[0] = depth;\n-\t\tdepth32[1] = 0;\n-\t\tdepth32[2] = 0;\n-\t\tdepth32[3] = 0;\n-\t\treturn 0;\n-\n-\tcase 1:\n-\t\tdepth32[0] = 32;\n-\t\tdepth32[1] = depth - 32;\n-\t\tdepth32[2] = 0;\n-\t\tdepth32[3] = 0;\n-\t\treturn 0;\n-\n-\tcase 2:\n-\t\tdepth32[0] = 32;\n-\t\tdepth32[1] = 32;\n-\t\tdepth32[2] = depth - 64;\n-\t\tdepth32[3] = 0;\n-\t\treturn 0;\n-\n-\tcase 3:\n-\t\tdepth32[0] = 32;\n-\t\tdepth32[1] = 32;\n-\t\tdepth32[2] = 32;\n-\t\tdepth32[3] = depth - 96;\n-\t\treturn 0;\n-\n-\tcase 4:\n-\t\tdepth32[0] = 32;\n-\t\tdepth32[1] = 32;\n-\t\tdepth32[2] = 32;\n-\t\tdepth32[3] = 32;\n-\t\treturn 0;\n-\n-\tdefault:\n-\t\treturn -1;\n-\t}\n-}\n-\n-static int\n-match_convert(struct softnic_table_rule_match *mh,\n-\tunion table_rule_match_low_level *ml,\n-\tint add)\n-{\n-\tmemset(ml, 0, sizeof(*ml));\n-\n-\tswitch (mh->match_type) {\n-\tcase TABLE_ACL:\n-\t\tif (mh->match.acl.ip_version)\n-\t\t\tif (add) {\n-\t\t\t\tml->acl_add.field_value[0].value.u8 =\n-\t\t\t\t\tmh->match.acl.proto;\n-\t\t\t\tml->acl_add.field_value[0].mask_range.u8 =\n-\t\t\t\t\tmh->match.acl.proto_mask;\n-\n-\t\t\t\tml->acl_add.field_value[1].value.u32 =\n-\t\t\t\t\tmh->match.acl.ipv4.sa;\n-\t\t\t\tml->acl_add.field_value[1].mask_range.u32 =\n-\t\t\t\t\tmh->match.acl.sa_depth;\n-\n-\t\t\t\tml->acl_add.field_value[2].value.u32 =\n-\t\t\t\t\tmh->match.acl.ipv4.da;\n-\t\t\t\tml->acl_add.field_value[2].mask_range.u32 =\n-\t\t\t\t\tmh->match.acl.da_depth;\n-\n-\t\t\t\tml->acl_add.field_value[3].value.u16 =\n-\t\t\t\t\tmh->match.acl.sp0;\n-\t\t\t\tml->acl_add.field_value[3].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.sp1;\n-\n-\t\t\t\tml->acl_add.field_value[4].value.u16 =\n-\t\t\t\t\tmh->match.acl.dp0;\n-\t\t\t\tml->acl_add.field_value[4].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.dp1;\n-\n-\t\t\t\tml->acl_add.priority =\n-\t\t\t\t\t(int32_t)mh->match.acl.priority;\n-\t\t\t} else {\n-\t\t\t\tml->acl_delete.field_value[0].value.u8 =\n-\t\t\t\t\tmh->match.acl.proto;\n-\t\t\t\tml->acl_delete.field_value[0].mask_range.u8 =\n-\t\t\t\t\tmh->match.acl.proto_mask;\n-\n-\t\t\t\tml->acl_delete.field_value[1].value.u32 =\n-\t\t\t\t\tmh->match.acl.ipv4.sa;\n-\t\t\t\tml->acl_delete.field_value[1].mask_range.u32 =\n-\t\t\t\t\tmh->match.acl.sa_depth;\n-\n-\t\t\t\tml->acl_delete.field_value[2].value.u32 =\n-\t\t\t\t\tmh->match.acl.ipv4.da;\n-\t\t\t\tml->acl_delete.field_value[2].mask_range.u32 =\n-\t\t\t\t\tmh->match.acl.da_depth;\n-\n-\t\t\t\tml->acl_delete.field_value[3].value.u16 =\n-\t\t\t\t\tmh->match.acl.sp0;\n-\t\t\t\tml->acl_delete.field_value[3].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.sp1;\n-\n-\t\t\t\tml->acl_delete.field_value[4].value.u16 =\n-\t\t\t\t\tmh->match.acl.dp0;\n-\t\t\t\tml->acl_delete.field_value[4].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.dp1;\n-\t\t\t}\n-\t\telse\n-\t\t\tif (add) {\n-\t\t\t\tuint32_t *sa32 =\n-\t\t\t\t\t(uint32_t *)mh->match.acl.ipv6.sa;\n-\t\t\t\tuint32_t *da32 =\n-\t\t\t\t\t(uint32_t *)mh->match.acl.ipv6.da;\n-\t\t\t\tuint32_t sa32_depth[4], da32_depth[4];\n-\t\t\t\tint status;\n-\n-\t\t\t\tstatus = match_convert_ipv6_depth(mh->match.acl.sa_depth,\n-\t\t\t\t\tsa32_depth);\n-\t\t\t\tif (status)\n-\t\t\t\t\treturn status;\n-\n-\t\t\t\tstatus = match_convert_ipv6_depth(\n-\t\t\t\t\tmh->match.acl.da_depth,\n-\t\t\t\t\tda32_depth);\n-\t\t\t\tif (status)\n-\t\t\t\t\treturn status;\n-\n-\t\t\t\tml->acl_add.field_value[0].value.u8 =\n-\t\t\t\t\tmh->match.acl.proto;\n-\t\t\t\tml->acl_add.field_value[0].mask_range.u8 =\n-\t\t\t\t\tmh->match.acl.proto_mask;\n-\n-\t\t\t\tml->acl_add.field_value[1].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[0]);\n-\t\t\t\tml->acl_add.field_value[1].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[0];\n-\t\t\t\tml->acl_add.field_value[2].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[1]);\n-\t\t\t\tml->acl_add.field_value[2].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[1];\n-\t\t\t\tml->acl_add.field_value[3].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[2]);\n-\t\t\t\tml->acl_add.field_value[3].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[2];\n-\t\t\t\tml->acl_add.field_value[4].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[3]);\n-\t\t\t\tml->acl_add.field_value[4].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[3];\n-\n-\t\t\t\tml->acl_add.field_value[5].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[0]);\n-\t\t\t\tml->acl_add.field_value[5].mask_range.u32 =\n-\t\t\t\t\tda32_depth[0];\n-\t\t\t\tml->acl_add.field_value[6].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[1]);\n-\t\t\t\tml->acl_add.field_value[6].mask_range.u32 =\n-\t\t\t\t\tda32_depth[1];\n-\t\t\t\tml->acl_add.field_value[7].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[2]);\n-\t\t\t\tml->acl_add.field_value[7].mask_range.u32 =\n-\t\t\t\t\tda32_depth[2];\n-\t\t\t\tml->acl_add.field_value[8].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[3]);\n-\t\t\t\tml->acl_add.field_value[8].mask_range.u32 =\n-\t\t\t\t\tda32_depth[3];\n-\n-\t\t\t\tml->acl_add.field_value[9].value.u16 =\n-\t\t\t\t\tmh->match.acl.sp0;\n-\t\t\t\tml->acl_add.field_value[9].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.sp1;\n-\n-\t\t\t\tml->acl_add.field_value[10].value.u16 =\n-\t\t\t\t\tmh->match.acl.dp0;\n-\t\t\t\tml->acl_add.field_value[10].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.dp1;\n-\n-\t\t\t\tml->acl_add.priority =\n-\t\t\t\t\t(int32_t)mh->match.acl.priority;\n-\t\t\t} else {\n-\t\t\t\tuint32_t *sa32 =\n-\t\t\t\t\t(uint32_t *)mh->match.acl.ipv6.sa;\n-\t\t\t\tuint32_t *da32 =\n-\t\t\t\t\t(uint32_t *)mh->match.acl.ipv6.da;\n-\t\t\t\tuint32_t sa32_depth[4], da32_depth[4];\n-\t\t\t\tint status;\n-\n-\t\t\t\tstatus = match_convert_ipv6_depth(mh->match.acl.sa_depth,\n-\t\t\t\t\tsa32_depth);\n-\t\t\t\tif (status)\n-\t\t\t\t\treturn status;\n-\n-\t\t\t\tstatus = match_convert_ipv6_depth(mh->match.acl.da_depth,\n-\t\t\t\t\tda32_depth);\n-\t\t\t\tif (status)\n-\t\t\t\t\treturn status;\n-\n-\t\t\t\tml->acl_delete.field_value[0].value.u8 =\n-\t\t\t\t\tmh->match.acl.proto;\n-\t\t\t\tml->acl_delete.field_value[0].mask_range.u8 =\n-\t\t\t\t\tmh->match.acl.proto_mask;\n-\n-\t\t\t\tml->acl_delete.field_value[1].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[0]);\n-\t\t\t\tml->acl_delete.field_value[1].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[0];\n-\t\t\t\tml->acl_delete.field_value[2].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[1]);\n-\t\t\t\tml->acl_delete.field_value[2].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[1];\n-\t\t\t\tml->acl_delete.field_value[3].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[2]);\n-\t\t\t\tml->acl_delete.field_value[3].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[2];\n-\t\t\t\tml->acl_delete.field_value[4].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(sa32[3]);\n-\t\t\t\tml->acl_delete.field_value[4].mask_range.u32 =\n-\t\t\t\t\tsa32_depth[3];\n-\n-\t\t\t\tml->acl_delete.field_value[5].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[0]);\n-\t\t\t\tml->acl_delete.field_value[5].mask_range.u32 =\n-\t\t\t\t\tda32_depth[0];\n-\t\t\t\tml->acl_delete.field_value[6].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[1]);\n-\t\t\t\tml->acl_delete.field_value[6].mask_range.u32 =\n-\t\t\t\t\tda32_depth[1];\n-\t\t\t\tml->acl_delete.field_value[7].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[2]);\n-\t\t\t\tml->acl_delete.field_value[7].mask_range.u32 =\n-\t\t\t\t\tda32_depth[2];\n-\t\t\t\tml->acl_delete.field_value[8].value.u32 =\n-\t\t\t\t\trte_be_to_cpu_32(da32[3]);\n-\t\t\t\tml->acl_delete.field_value[8].mask_range.u32 =\n-\t\t\t\t\tda32_depth[3];\n-\n-\t\t\t\tml->acl_delete.field_value[9].value.u16 =\n-\t\t\t\t\tmh->match.acl.sp0;\n-\t\t\t\tml->acl_delete.field_value[9].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.sp1;\n-\n-\t\t\t\tml->acl_delete.field_value[10].value.u16 =\n-\t\t\t\t\tmh->match.acl.dp0;\n-\t\t\t\tml->acl_delete.field_value[10].mask_range.u16 =\n-\t\t\t\t\tmh->match.acl.dp1;\n-\t\t\t}\n-\t\treturn 0;\n-\n-\tcase TABLE_ARRAY:\n-\t\tml->array.pos = mh->match.array.pos;\n-\t\treturn 0;\n-\n-\tcase TABLE_HASH:\n-\t\tmemcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));\n-\t\treturn 0;\n-\n-\tcase TABLE_LPM:\n-\t\tif (mh->match.lpm.ip_version) {\n-\t\t\tml->lpm_ipv4.ip = mh->match.lpm.ipv4;\n-\t\t\tml->lpm_ipv4.depth = mh->match.lpm.depth;\n-\t\t} else {\n-\t\t\tmemcpy(ml->lpm_ipv6.ip,\n-\t\t\t\tmh->match.lpm.ipv6, sizeof(ml->lpm_ipv6.ip));\n-\t\t\tml->lpm_ipv6.depth = mh->match.lpm.depth;\n-\t\t}\n-\n-\t\treturn 0;\n-\n-\tdefault:\n-\t\treturn -1;\n-\t}\n-}\n-\n-static int\n-action_convert(struct rte_table_action *a,\n-\tstruct softnic_table_rule_action *action,\n-\tstruct rte_pipeline_table_entry *data)\n-{\n-\tint status;\n-\n-\t/* Apply actions */\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_FWD,\n-\t\t\t&action->fwd);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_LB,\n-\t\t\t&action->lb);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_MTR,\n-\t\t\t&action->mtr);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_TM,\n-\t\t\t&action->tm);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_ENCAP,\n-\t\t\t&action->encap);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_NAT,\n-\t\t\t&action->nat);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_TTL,\n-\t\t\t&action->ttl);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_STATS,\n-\t\t\t&action->stats);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_TIME,\n-\t\t\t&action->time);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_TAG,\n-\t\t\t&action->tag);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_DECAP,\n-\t\t\t&action->decap);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\tif (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {\n-\t\tstatus = rte_table_action_apply(a,\n-\t\t\tdata,\n-\t\t\tRTE_TABLE_ACTION_SYM_CRYPTO,\n-\t\t\t&action->sym_crypto);\n-\n-\t\tif (status)\n-\t\t\treturn status;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tunion table_rule_match_low_level match_ll;\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tstruct softnic_table_rule_match *match = &req->table_rule_add.match;\n-\tstruct softnic_table_rule_action *action = &req->table_rule_add.action;\n-\tstruct rte_pipeline_table_entry *data_in, *data_out;\n-\tuint32_t table_id = req->id;\n-\tint key_found, status;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\t/* Apply actions */\n-\tmemset(p->buffer, 0, sizeof(p->buffer));\n-\tdata_in = (struct rte_pipeline_table_entry *)p->buffer;\n-\n-\tstatus = match_convert(match, &match_ll, 1);\n-\tif (status) {\n-\t\trsp->status = -1;\n-\t\treturn rsp;\n-\t}\n-\n-\tstatus = action_convert(a, action, data_in);\n-\tif (status) {\n-\t\trsp->status = -1;\n-\t\treturn rsp;\n-\t}\n-\n-\tstatus = rte_pipeline_table_entry_add(p->p,\n-\t\ttable_id,\n-\t\t&match_ll,\n-\t\tdata_in,\n-\t\t&key_found,\n-\t\t&data_out);\n-\tif (status) {\n-\t\trsp->status = -1;\n-\t\treturn rsp;\n-\t}\n-\n-\t/* Write response */\n-\trsp->status = 0;\n-\trsp->table_rule_add.data = data_out;\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tstruct softnic_table_rule_action *action = &req->table_rule_add_default.action;\n-\tstruct rte_pipeline_table_entry *data_in, *data_out;\n-\tuint32_t table_id = req->id;\n-\tint status;\n-\n-\t/* Apply actions */\n-\tmemset(p->buffer, 0, sizeof(p->buffer));\n-\tdata_in = (struct rte_pipeline_table_entry *)p->buffer;\n-\n-\tdata_in->action = action->fwd.action;\n-\tif (action->fwd.action == RTE_PIPELINE_ACTION_PORT)\n-\t\tdata_in->port_id = action->fwd.id;\n-\tif (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)\n-\t\tdata_in->table_id = action->fwd.id;\n-\n-\t/* Add default rule to table */\n-\tstatus = rte_pipeline_table_default_entry_add(p->p,\n-\t\ttable_id,\n-\t\tdata_in,\n-\t\t&data_out);\n-\tif (status) {\n-\t\trsp->status = -1;\n-\t\treturn rsp;\n-\t}\n-\n-\t/* Write response */\n-\trsp->status = 0;\n-\trsp->table_rule_add_default.data = data_out;\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\n-\tuint32_t table_id = req->id;\n-\tstruct softnic_table_rule_match *match = req->table_rule_add_bulk.match;\n-\tstruct softnic_table_rule_action *action = req->table_rule_add_bulk.action;\n-\tstruct rte_pipeline_table_entry **data =\n-\t\t(struct rte_pipeline_table_entry **)req->table_rule_add_bulk.data;\n-\tuint32_t n_rules = req->table_rule_add_bulk.n_rules;\n-\tuint32_t bulk = req->table_rule_add_bulk.bulk;\n-\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\tunion table_rule_match_low_level *match_ll;\n-\tuint8_t *action_ll;\n-\tvoid **match_ll_ptr;\n-\tstruct rte_pipeline_table_entry **action_ll_ptr;\n-\tint *found, status;\n-\tuint32_t i;\n-\n-\t/* Memory allocation */\n-\tmatch_ll = calloc(n_rules, sizeof(union table_rule_match_low_level));\n-\taction_ll = calloc(n_rules, TABLE_RULE_ACTION_SIZE_MAX);\n-\tmatch_ll_ptr = calloc(n_rules, sizeof(void *));\n-\taction_ll_ptr =\n-\t\tcalloc(n_rules, sizeof(struct rte_pipeline_table_entry *));\n-\tfound = calloc(n_rules, sizeof(int));\n-\n-\tif (match_ll == NULL ||\n-\t\taction_ll == NULL ||\n-\t\tmatch_ll_ptr == NULL ||\n-\t\taction_ll_ptr == NULL ||\n-\t\tfound == NULL)\n-\t\tgoto fail;\n-\n-\tfor (i = 0; i < n_rules; i++) {\n-\t\tmatch_ll_ptr[i] = (void *)&match_ll[i];\n-\t\taction_ll_ptr[i] =\n-\t\t\t(struct rte_pipeline_table_entry *)&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];\n-\t}\n-\n-\t/* Rule match conversion */\n-\tfor (i = 0; i < n_rules; i++) {\n-\t\tstatus = match_convert(&match[i], match_ll_ptr[i], 1);\n-\t\tif (status)\n-\t\t\tgoto fail;\n-\t}\n-\n-\t/* Rule action conversion */\n-\tfor (i = 0; i < n_rules; i++) {\n-\t\tstatus = action_convert(a, &action[i], action_ll_ptr[i]);\n-\t\tif (status)\n-\t\t\tgoto fail;\n-\t}\n-\n-\t/* Add rule (match, action) to table */\n-\tif (bulk) {\n-\t\tstatus = rte_pipeline_table_entry_add_bulk(p->p,\n-\t\t\ttable_id,\n-\t\t\tmatch_ll_ptr,\n-\t\t\taction_ll_ptr,\n-\t\t\tn_rules,\n-\t\t\tfound,\n-\t\t\tdata);\n-\t\tif (status)\n-\t\t\tn_rules = 0;\n-\t} else {\n-\t\tfor (i = 0; i < n_rules; i++) {\n-\t\t\tstatus = rte_pipeline_table_entry_add(p->p,\n-\t\t\t\ttable_id,\n-\t\t\t\tmatch_ll_ptr[i],\n-\t\t\t\taction_ll_ptr[i],\n-\t\t\t\t&found[i],\n-\t\t\t\t&data[i]);\n-\t\t\tif (status) {\n-\t\t\t\tn_rules = i;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t}\n-\n-\t/* Write response */\n-\trsp->status = 0;\n-\trsp->table_rule_add_bulk.n_rules = n_rules;\n-\n-\t/* Free */\n-\tfree(found);\n-\tfree(action_ll_ptr);\n-\tfree(match_ll_ptr);\n-\tfree(action_ll);\n-\tfree(match_ll);\n-\n-\treturn rsp;\n-\n-fail:\n-\tfree(found);\n-\tfree(action_ll_ptr);\n-\tfree(match_ll_ptr);\n-\tfree(action_ll);\n-\tfree(match_ll);\n-\n-\trsp->status = -1;\n-\trsp->table_rule_add_bulk.n_rules = 0;\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_delete(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tunion table_rule_match_low_level match_ll;\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tstruct softnic_table_rule_match *match = &req->table_rule_delete.match;\n-\tuint32_t table_id = req->id;\n-\tint key_found, status;\n-\n-\tstatus = match_convert(match, &match_ll, 0);\n-\tif (status) {\n-\t\trsp->status = -1;\n-\t\treturn rsp;\n-\t}\n-\n-\trsp->status = rte_pipeline_table_entry_delete(p->p,\n-\t\ttable_id,\n-\t\t&match_ll,\n-\t\t&key_found,\n-\t\tNULL);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_delete_default(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\n-\trsp->status = rte_pipeline_table_default_entry_delete(p->p,\n-\t\ttable_id,\n-\t\tNULL);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_stats_read(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\tvoid *data = req->table_rule_stats_read.data;\n-\tint clear = req->table_rule_stats_read.clear;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\trsp->status = rte_table_action_stats_read(a,\n-\t\tdata,\n-\t\t&rsp->table_rule_stats_read.stats,\n-\t\tclear);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_mtr_profile_add(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\tuint32_t meter_profile_id = req->table_mtr_profile_add.meter_profile_id;\n-\tstruct rte_table_action_meter_profile *profile =\n-\t\t&req->table_mtr_profile_add.profile;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\trsp->status = rte_table_action_meter_profile_add(a,\n-\t\tmeter_profile_id,\n-\t\tprofile);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_mtr_profile_delete(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\tuint32_t meter_profile_id =\n-\t\treq->table_mtr_profile_delete.meter_profile_id;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\trsp->status = rte_table_action_meter_profile_delete(a,\n-\t\tmeter_profile_id);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_mtr_read(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\tvoid *data = req->table_rule_mtr_read.data;\n-\tuint32_t tc_mask = req->table_rule_mtr_read.tc_mask;\n-\tint clear = req->table_rule_mtr_read.clear;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\trsp->status = rte_table_action_meter_read(a,\n-\t\tdata,\n-\t\ttc_mask,\n-\t\t&rsp->table_rule_mtr_read.stats,\n-\t\tclear);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_dscp_table_update(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\tuint64_t dscp_mask = req->table_dscp_table_update.dscp_mask;\n-\tstruct rte_table_action_dscp_table *dscp_table =\n-\t\t&req->table_dscp_table_update.dscp_table;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\trsp->status = rte_table_action_dscp_table_update(a,\n-\t\tdscp_mask,\n-\t\tdscp_table);\n-\n-\treturn rsp;\n-}\n-\n-static struct pipeline_msg_rsp *\n-pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,\n-\tstruct pipeline_msg_req *req)\n-{\n-\tstruct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;\n-\tuint32_t table_id = req->id;\n-\tvoid *data = req->table_rule_ttl_read.data;\n-\tint clear = req->table_rule_ttl_read.clear;\n-\tstruct rte_table_action *a = p->table_data[table_id].a;\n-\n-\trsp->status = rte_table_action_ttl_read(a,\n-\t\tdata,\n-\t\t&rsp->table_rule_ttl_read.stats,\n-\t\tclear);\n-\n-\treturn rsp;\n-}\n-\n-static void\n-pipeline_msg_handle(struct pipeline_data *p)\n-{\n-\tfor ( ; ; ) {\n-\t\tstruct pipeline_msg_req *req;\n-\t\tstruct pipeline_msg_rsp *rsp;\n-\n-\t\treq = pipeline_msg_recv(p->msgq_req);\n-\t\tif (req == NULL)\n-\t\t\tbreak;\n-\n-\t\tswitch (req->type) {\n-\t\tcase PIPELINE_REQ_PORT_IN_STATS_READ:\n-\t\t\trsp = pipeline_msg_handle_port_in_stats_read(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_PORT_IN_ENABLE:\n-\t\t\trsp = pipeline_msg_handle_port_in_enable(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_PORT_IN_DISABLE:\n-\t\t\trsp = pipeline_msg_handle_port_in_disable(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_PORT_OUT_STATS_READ:\n-\t\t\trsp = pipeline_msg_handle_port_out_stats_read(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_STATS_READ:\n-\t\t\trsp = pipeline_msg_handle_table_stats_read(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_ADD:\n-\t\t\trsp = pipeline_msg_handle_table_rule_add(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT:\n-\t\t\trsp = pipeline_msg_handle_table_rule_add_default(p,\treq);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_ADD_BULK:\n-\t\t\trsp = pipeline_msg_handle_table_rule_add_bulk(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_DELETE:\n-\t\t\trsp = pipeline_msg_handle_table_rule_delete(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT:\n-\t\t\trsp = pipeline_msg_handle_table_rule_delete_default(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_STATS_READ:\n-\t\t\trsp = pipeline_msg_handle_table_rule_stats_read(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_MTR_PROFILE_ADD:\n-\t\t\trsp = pipeline_msg_handle_table_mtr_profile_add(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE:\n-\t\t\trsp = pipeline_msg_handle_table_mtr_profile_delete(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_MTR_READ:\n-\t\t\trsp = pipeline_msg_handle_table_rule_mtr_read(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE:\n-\t\t\trsp = pipeline_msg_handle_table_dscp_table_update(p, req);\n-\t\t\tbreak;\n-\n-\t\tcase PIPELINE_REQ_TABLE_RULE_TTL_READ:\n-\t\t\trsp = pipeline_msg_handle_table_rule_ttl_read(p, req);\n-\t\t\tbreak;\n-\n-\t\tdefault:\n-\t\t\trsp = (struct pipeline_msg_rsp *)req;\n-\t\t\trsp->status = -1;\n-\t\t}\n-\n-\t\tpipeline_msg_send(p->msgq_rsp, rsp);\n-\t}\n-}\n-\n-/**\n- * Data plane threads: main\n- */\n-static int32_t\n-rte_pmd_softnic_run_internal(void *arg)\n-{\n-\tstruct rte_eth_dev *dev = arg;\n-\tstruct pmd_internals *softnic;\n-\tstruct softnic_thread_data *t;\n-\tuint32_t thread_id, j;\n-\n-\tsoftnic = dev->data->dev_private;\n-\tthread_id = rte_lcore_id();\n-\tt = &softnic->thread_data[thread_id];\n-\tt->iter++;\n-\n-\t/* Data Plane */\n-\tfor (j = 0; j < t->n_pipelines; j++)\n-\t\trte_pipeline_run(t->p[j]);\n-\n-\t/* Control Plane */\n-\tif ((t->iter & 0xFLLU) == 0) {\n-\t\tuint64_t time = rte_get_tsc_cycles();\n-\t\tuint64_t time_next_min = UINT64_MAX;\n-\n-\t\tif (time < t->time_next_min)\n-\t\t\treturn 0;\n-\n-\t\t/* Pipeline message queues */\n-\t\tfor (j = 0; j < t->n_pipelines; j++) {\n-\t\t\tstruct pipeline_data *p =\n-\t\t\t\t&t->pipeline_data[j];\n-\t\t\tuint64_t time_next = p->time_next;\n-\n-\t\t\tif (time_next <= time) {\n-\t\t\t\tpipeline_msg_handle(p);\n-\t\t\t\trte_pipeline_flush(p->p);\n-\t\t\t\ttime_next = time + p->timer_period;\n-\t\t\t\tp->time_next = time_next;\n-\t\t\t}\n-\n-\t\t\tif (time_next < time_next_min)\n-\t\t\t\ttime_next_min = time_next;\n-\t\t}\n+\t\tif (time < time_next)\n+\t\t\treturn 0;\n \n \t\t/* Thread message queues */\n-\t\t{\n-\t\t\tuint64_t time_next = t->time_next;\n-\n-\t\t\tif (time_next <= time) {\n-\t\t\t\tthread_msg_handle(t);\n-\t\t\t\ttime_next = time + t->timer_period;\n-\t\t\t\tt->time_next = time_next;\n-\t\t\t}\n-\n-\t\t\tif (time_next < time_next_min)\n-\t\t\t\ttime_next_min = time_next;\n-\t\t}\n+\t\tthread_msg_handle(t);\n \n-\t\tt->time_next_min = time_next_min;\n+\t\tt->time_next = time_next + t->timer_period;\n \t}\n \n \treturn 0;\n",
    "prefixes": [
        "V3",
        "07/21"
    ]
}