get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 76963,
    "url": "http://patches.dpdk.org/api/patches/76963/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200908201830.74206-30-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200908201830.74206-30-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200908201830.74206-30-cristian.dumitrescu@intel.com",
    "date": "2020-09-08T20:18:18",
    "name": "[v3,29/41] pipeline: add SWX pipeline query API",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7d2a51e4748952fad58ea782ac97e693caeec75f",
    "submitter": {
        "id": 19,
        "url": "http://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200908201830.74206-30-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 12034,
            "url": "http://patches.dpdk.org/api/series/12034/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12034",
            "date": "2020-09-08T20:17:52",
            "name": "Pipeline alignment with the P4 language",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/12034/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/76963/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/76963/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 43051A04B1;\n\tTue,  8 Sep 2020 22:23:52 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id EB1631C238;\n\tTue,  8 Sep 2020 22:19:39 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by dpdk.org (Postfix) with ESMTP id 89CD31C11E\n for <dev@dpdk.org>; Tue,  8 Sep 2020 22:19:04 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 08 Sep 2020 13:19:00 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by fmsmga006.fm.intel.com with ESMTP; 08 Sep 2020 13:18:59 -0700"
        ],
        "IronPort-SDR": [
            "\n 09B3FQVuV9o/MpbNJ7Cv7kHI5aVAp5OfuHk0xvh00KwfPYFWA9TlqEM6cXSBcwwqCGD++rA8vk\n qlVKUxAnMmOw==",
            "\n BEK1oggdS+opt6NjompH6qDjNNwKIQcrT3Y5xQQbhTT9dsY4ry4N+qSvxymwqbIxdFLCIHeMZz\n E55oYFACCaPw=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9738\"; a=\"145939435\"",
            "E=Sophos;i=\"5.76,407,1592895600\"; d=\"scan'208\";a=\"145939435\"",
            "E=Sophos;i=\"5.76,406,1592895600\"; d=\"scan'208\";a=\"504493505\""
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue,  8 Sep 2020 21:18:18 +0100",
        "Message-Id": "<20200908201830.74206-30-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200908201830.74206-1-cristian.dumitrescu@intel.com>",
        "References": "<20200907214032.95052-2-cristian.dumitrescu@intel.com>\n <20200908201830.74206-1-cristian.dumitrescu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v3 29/41] pipeline: add SWX pipeline query API",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Query API to be used by the control plane to detect the configuration\nand state of the SWX pipeline and its internal objects.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n---\n lib/librte_pipeline/rte_pipeline_version.map |  10 +\n lib/librte_pipeline/rte_swx_ctl.h            | 313 +++++++++++++++++++\n lib/librte_pipeline/rte_swx_pipeline.c       | 219 +++++++++++++\n 3 files changed, 542 insertions(+)",
    "diff": "diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map\nindex 793957eb9..bb992fdd0 100644\n--- a/lib/librte_pipeline/rte_pipeline_version.map\n+++ b/lib/librte_pipeline/rte_pipeline_version.map\n@@ -76,4 +76,14 @@ EXPERIMENTAL {\n \trte_swx_pipeline_run;\n \trte_swx_pipeline_table_state_get;\n \trte_swx_pipeline_table_state_set;\n+\trte_swx_ctl_pipeline_info_get;\n+\trte_swx_ctl_pipeline_numa_node_get;\n+\trte_swx_ctl_pipeline_port_in_stats_read;\n+\trte_swx_ctl_pipeline_port_out_stats_read;\n+\trte_swx_ctl_action_info_get;\n+\trte_swx_ctl_action_arg_info_get;\n+\trte_swx_ctl_table_info_get;\n+\trte_swx_ctl_table_match_field_info_get;\n+\trte_swx_ctl_table_action_info_get;\n+\trte_swx_ctl_table_ops_get;\n };\ndiff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h\nindex c824ab56f..bdcc24cee 100644\n--- a/lib/librte_pipeline/rte_swx_ctl.h\n+++ b/lib/librte_pipeline/rte_swx_ctl.h\n@@ -18,8 +18,321 @@ extern \"C\" {\n \n #include <rte_compat.h>\n \n+#include \"rte_swx_port.h\"\n #include \"rte_swx_table.h\"\n \n+struct rte_swx_pipeline;\n+\n+/** Name size. */\n+#ifndef RTE_SWX_CTL_NAME_SIZE\n+#define RTE_SWX_CTL_NAME_SIZE 64\n+#endif\n+\n+/*\n+ * Pipeline Query API.\n+ */\n+\n+/** Pipeline info. */\n+struct rte_swx_ctl_pipeline_info {\n+\t/** Number of input ports. */\n+\tuint32_t n_ports_in;\n+\n+\t/** Number of input ports. */\n+\tuint32_t n_ports_out;\n+\n+\t/** Number of actions. */\n+\tuint32_t n_actions;\n+\n+\t/** Number of tables. */\n+\tuint32_t n_tables;\n+};\n+\n+/**\n+ * Pipeline info get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[out] pipeline\n+ *   Pipeline info.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_pipeline_info_get(struct rte_swx_pipeline *p,\n+\t\t\t      struct rte_swx_ctl_pipeline_info *pipeline);\n+\n+/**\n+ * Pipeline NUMA node get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[out] numa_node\n+ *   Pipeline NUMA node.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_pipeline_numa_node_get(struct rte_swx_pipeline *p,\n+\t\t\t\t   int *numa_node);\n+\n+/*\n+ * Ports Query API.\n+ */\n+\n+/**\n+ * Input port statistics counters read\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] port_id\n+ *   Port ID (0 .. *n_ports_in* - 1).\n+ * @param[out] stats\n+ *   Input port stats.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_pipeline_port_in_stats_read(struct rte_swx_pipeline *p,\n+\t\t\t\t\tuint32_t port_id,\n+\t\t\t\t\tstruct rte_swx_port_in_stats *stats);\n+\n+/**\n+ * Output port statistics counters read\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] port_id\n+ *   Port ID (0 .. *n_ports_out* - 1).\n+ * @param[out] stats\n+ *   Output port stats.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_pipeline_port_out_stats_read(struct rte_swx_pipeline *p,\n+\t\t\t\t\t uint32_t port_id,\n+\t\t\t\t\t struct rte_swx_port_out_stats *stats);\n+\n+/*\n+ * Action Query API.\n+ */\n+\n+/** Action info. */\n+struct rte_swx_ctl_action_info {\n+\t/** Action name. */\n+\tchar name[RTE_SWX_CTL_NAME_SIZE];\n+\n+\t/** Number of action arguments. */\n+\tuint32_t n_args;\n+};\n+\n+/**\n+ * Action info get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] action_id\n+ *   Action ID (0 .. *n_actions* - 1).\n+ * @param[out] action\n+ *   Action info.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_action_info_get(struct rte_swx_pipeline *p,\n+\t\t\t    uint32_t action_id,\n+\t\t\t    struct rte_swx_ctl_action_info *action);\n+\n+/** Action argument info. */\n+struct rte_swx_ctl_action_arg_info {\n+\t/** Action argument name. */\n+\tchar name[RTE_SWX_CTL_NAME_SIZE];\n+\n+\t/** Action argument size (in bits). */\n+\tuint32_t n_bits;\n+};\n+\n+/**\n+ * Action argument info get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] action_id\n+ *   Action ID (0 .. *n_actions* - 1).\n+ * @param[in] action_arg_id\n+ *   Action ID (0 .. *n_args* - 1).\n+ * @param[out] action\n+ *   Action argument info.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_action_arg_info_get(struct rte_swx_pipeline *p,\n+\t\t\t\tuint32_t action_id,\n+\t\t\t\tuint32_t action_arg_id,\n+\t\t\t\tstruct rte_swx_ctl_action_arg_info *action_arg);\n+\n+/*\n+ * Table Query API.\n+ */\n+\n+/** Table info. */\n+struct rte_swx_ctl_table_info {\n+\t/** Table name. */\n+\tchar name[RTE_SWX_CTL_NAME_SIZE];\n+\n+\t/** Table creation arguments. */\n+\tchar args[RTE_SWX_CTL_NAME_SIZE];\n+\n+\t/** Number of match fields. */\n+\tuint32_t n_match_fields;\n+\n+\t/** Number of actions. */\n+\tuint32_t n_actions;\n+\n+\t/** Non-zero (true) when the default action is constant, therefore it\n+\t * cannot be changed; zero (false) when the default action not constant,\n+\t * therefore it can be changed.\n+\t */\n+\tint default_action_is_const;\n+\n+\t/** Table size parameter. */\n+\tuint32_t size;\n+};\n+\n+/**\n+ * Table info get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] table_id\n+ *   Table ID (0 .. *n_tables* - 1).\n+ * @param[out] table\n+ *   Table info.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_table_info_get(struct rte_swx_pipeline *p,\n+\t\t\t   uint32_t table_id,\n+\t\t\t   struct rte_swx_ctl_table_info *table);\n+\n+/** Table match field info.\n+ *\n+ * If (n_bits, offset) are known for all the match fields of the table, then the\n+ * table (key_offset, key_size, key_mask0) can be computed.\n+ */\n+struct rte_swx_ctl_table_match_field_info {\n+\t/** Match type of the current match field. */\n+\tenum rte_swx_table_match_type match_type;\n+\n+\t/** Non-zero (true) when the current match field is part of a registered\n+\t * header, zero (false) when it is part of the registered meta-data.\n+\t */\n+\tint is_header;\n+\n+\t/** Match field size (in bits). */\n+\tuint32_t n_bits;\n+\n+\t/** Match field offset within its parent struct (one of the headers or\n+\t * the meta-data).\n+\t */\n+\tuint32_t offset;\n+};\n+\n+/**\n+ * Table match field info get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] table_id\n+ *   Table ID (0 .. *n_tables*).\n+ * @param[in] match_field_id\n+ *   Match field ID (0 .. *n_match_fields* - 1).\n+ * @param[out] match_field\n+ *   Table match field info.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_table_match_field_info_get(struct rte_swx_pipeline *p,\n+\tuint32_t table_id,\n+\tuint32_t match_field_id,\n+\tstruct rte_swx_ctl_table_match_field_info *match_field);\n+\n+/** Table action info. */\n+struct rte_swx_ctl_table_action_info {\n+\t/** Action ID. */\n+\tuint32_t action_id;\n+};\n+\n+/**\n+ * Table action info get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] table_id\n+ *   Table ID (0 .. *n_tables*).\n+ * @param[in] table_action_id\n+ *   Action index within the set of table actions (0 .. table n_actions - 1).\n+ *   Not to be confused with the action ID, which works at the pipeline level\n+ *   (0 .. pipeline n_actions - 1), which is precisely what this function\n+ *   returns as part of *table_action*.\n+ * @param[out] table_action\n+ *   Table action info.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_table_action_info_get(struct rte_swx_pipeline *p,\n+\tuint32_t table_id,\n+\tuint32_t table_action_id,\n+\tstruct rte_swx_ctl_table_action_info *table_action);\n+\n+/**\n+ * Table operations get\n+ *\n+ * @param[in] p\n+ *   Pipeline handle.\n+ * @param[in] table_id\n+ *   Table ID (0 .. *n_tables*).\n+ * @param[out] table_ops\n+ *   Table operations. Only valid when function returns success and *is_stub* is\n+ *   zero (false).\n+ * @param[out] is_stub\n+ *   A stub table is a table with no match fields. No \"regular\" table entries\n+ *   (i.e. entries other than the default entry) can be added to such a table,\n+ *   therefore the lookup opeation always results in lookup miss. Non-zero\n+ *   (true) when the current table is a stub table, zero (false) otherwise.\n+ * @return\n+ *   0 on success or the following error codes otherwise:\n+ *   -EINVAL: Invalid argument.\n+ */\n+__rte_experimental\n+int\n+rte_swx_ctl_table_ops_get(struct rte_swx_pipeline *p,\n+\t\t\t  uint32_t table_id,\n+\t\t\t  struct rte_swx_table_ops *table_ops,\n+\t\t\t  int *is_stub);\n+\n /*\n  * Table Update API.\n  */\ndiff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c\nindex 77eae1927..da69bab49 100644\n--- a/lib/librte_pipeline/rte_swx_pipeline.c\n+++ b/lib/librte_pipeline/rte_swx_pipeline.c\n@@ -6152,6 +6152,18 @@ action_find(struct rte_swx_pipeline *p, const char *name)\n \treturn NULL;\n }\n \n+static struct action *\n+action_find_by_id(struct rte_swx_pipeline *p, uint32_t id)\n+{\n+\tstruct action *action = NULL;\n+\n+\tTAILQ_FOREACH(action, &p->actions, node)\n+\t\tif (action->id == id)\n+\t\t\treturn action;\n+\n+\treturn NULL;\n+}\n+\n static struct field *\n action_field_find(struct action *a, const char *name)\n {\n@@ -6942,6 +6954,177 @@ rte_swx_pipeline_run(struct rte_swx_pipeline *p, uint32_t n_instructions)\n /*\n  * Control.\n  */\n+int\n+rte_swx_ctl_pipeline_info_get(struct rte_swx_pipeline *p,\n+\t\t\t      struct rte_swx_ctl_pipeline_info *pipeline)\n+{\n+\tstruct action *action;\n+\tstruct table *table;\n+\tuint32_t n_actions = 0, n_tables = 0;\n+\n+\tif (!p || !pipeline)\n+\t\treturn -EINVAL;\n+\n+\tTAILQ_FOREACH(action, &p->actions, node)\n+\t\tn_actions++;\n+\n+\tTAILQ_FOREACH(table, &p->tables, node)\n+\t\tn_tables++;\n+\n+\tpipeline->n_ports_in = p->n_ports_in;\n+\tpipeline->n_ports_out = p->n_ports_out;\n+\tpipeline->n_actions = n_actions;\n+\tpipeline->n_tables = n_tables;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_pipeline_numa_node_get(struct rte_swx_pipeline *p, int *numa_node)\n+{\n+\tif (!p || !numa_node)\n+\t\treturn -EINVAL;\n+\n+\t*numa_node = p->numa_node;\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_action_info_get(struct rte_swx_pipeline *p,\n+\t\t\t    uint32_t action_id,\n+\t\t\t    struct rte_swx_ctl_action_info *action)\n+{\n+\tstruct action *a = NULL;\n+\n+\tif (!p || (action_id >= p->n_actions) || !action)\n+\t\treturn -EINVAL;\n+\n+\ta = action_find_by_id(p, action_id);\n+\tif (!a)\n+\t\treturn -EINVAL;\n+\n+\tstrcpy(action->name, a->name);\n+\taction->n_args = a->st ? a->st->n_fields : 0;\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_action_arg_info_get(struct rte_swx_pipeline *p,\n+\t\t\t\tuint32_t action_id,\n+\t\t\t\tuint32_t action_arg_id,\n+\t\t\t\tstruct rte_swx_ctl_action_arg_info *action_arg)\n+{\n+\tstruct action *a = NULL;\n+\tstruct field *arg = NULL;\n+\n+\tif (!p || (action_id >= p->n_actions) || !action_arg)\n+\t\treturn -EINVAL;\n+\n+\ta = action_find_by_id(p, action_id);\n+\tif (!a || !a->st || (action_arg_id >= a->st->n_fields))\n+\t\treturn -EINVAL;\n+\n+\targ = &a->st->fields[action_arg_id];\n+\tstrcpy(action_arg->name, arg->name);\n+\taction_arg->n_bits = arg->n_bits;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_table_info_get(struct rte_swx_pipeline *p,\n+\t\t\t   uint32_t table_id,\n+\t\t\t   struct rte_swx_ctl_table_info *table)\n+{\n+\tstruct table *t = NULL;\n+\n+\tif (!p || !table)\n+\t\treturn -EINVAL;\n+\n+\tt = table_find_by_id(p, table_id);\n+\tif (!t)\n+\t\treturn -EINVAL;\n+\n+\tstrcpy(table->name, t->name);\n+\tstrcpy(table->args, t->args);\n+\ttable->n_match_fields = t->n_fields;\n+\ttable->n_actions = t->n_actions;\n+\ttable->default_action_is_const = t->default_action_is_const;\n+\ttable->size = t->size;\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_table_match_field_info_get(struct rte_swx_pipeline *p,\n+\tuint32_t table_id,\n+\tuint32_t match_field_id,\n+\tstruct rte_swx_ctl_table_match_field_info *match_field)\n+{\n+\tstruct table *t;\n+\tstruct match_field *f;\n+\n+\tif (!p || (table_id >= p->n_tables) || !match_field)\n+\t\treturn -EINVAL;\n+\n+\tt = table_find_by_id(p, table_id);\n+\tif (!t || (match_field_id >= t->n_fields))\n+\t\treturn -EINVAL;\n+\n+\tf = &t->fields[match_field_id];\n+\tmatch_field->match_type = f->match_type;\n+\tmatch_field->is_header = t->is_header;\n+\tmatch_field->n_bits = f->field->n_bits;\n+\tmatch_field->offset = f->field->offset;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_table_action_info_get(struct rte_swx_pipeline *p,\n+\tuint32_t table_id,\n+\tuint32_t table_action_id,\n+\tstruct rte_swx_ctl_table_action_info *table_action)\n+{\n+\tstruct table *t;\n+\n+\tif (!p || (table_id >= p->n_tables) || !table_action)\n+\t\treturn -EINVAL;\n+\n+\tt = table_find_by_id(p, table_id);\n+\tif (!t || (table_action_id >= t->n_actions))\n+\t\treturn -EINVAL;\n+\n+\ttable_action->action_id = t->actions[table_action_id]->id;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_table_ops_get(struct rte_swx_pipeline *p,\n+\t\t\t  uint32_t table_id,\n+\t\t\t  struct rte_swx_table_ops *table_ops,\n+\t\t\t  int *is_stub)\n+{\n+\tstruct table *t;\n+\n+\tif (!p || (table_id >= p->n_tables))\n+\t\treturn -EINVAL;\n+\n+\tt = table_find_by_id(p, table_id);\n+\tif (!t)\n+\t\treturn -EINVAL;\n+\n+\tif (t->type) {\n+\t\tif (table_ops)\n+\t\t\tmemcpy(table_ops, &t->type->ops, sizeof(*table_ops));\n+\t\t*is_stub = 0;\n+\t} else {\n+\t\t*is_stub = 1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n int\n rte_swx_pipeline_table_state_get(struct rte_swx_pipeline *p,\n \t\t\t\t struct rte_swx_table_state **table_state)\n@@ -6963,3 +7146,39 @@ rte_swx_pipeline_table_state_set(struct rte_swx_pipeline *p,\n \tp->table_state = table_state;\n \treturn 0;\n }\n+\n+int\n+rte_swx_ctl_pipeline_port_in_stats_read(struct rte_swx_pipeline *p,\n+\t\t\t\t\tuint32_t port_id,\n+\t\t\t\t\tstruct rte_swx_port_in_stats *stats)\n+{\n+\tstruct port_in *port;\n+\n+\tif (!p || !stats)\n+\t\treturn -EINVAL;\n+\n+\tport = port_in_find(p, port_id);\n+\tif (!port)\n+\t\treturn -EINVAL;\n+\n+\tport->type->ops.stats_read(port->obj, stats);\n+\treturn 0;\n+}\n+\n+int\n+rte_swx_ctl_pipeline_port_out_stats_read(struct rte_swx_pipeline *p,\n+\t\t\t\t\t uint32_t port_id,\n+\t\t\t\t\t struct rte_swx_port_out_stats *stats)\n+{\n+\tstruct port_out *port;\n+\n+\tif (!p || !stats)\n+\t\treturn -EINVAL;\n+\n+\tport = port_out_find(p, port_id);\n+\tif (!port)\n+\t\treturn -EINVAL;\n+\n+\tport->type->ops.stats_read(port->obj, stats);\n+\treturn 0;\n+}\n",
    "prefixes": [
        "v3",
        "29/41"
    ]
}