get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 114033,
    "url": "https://patches.dpdk.org/api/patches/114033/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20220718132603.339314-6-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220718132603.339314-6-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220718132603.339314-6-cristian.dumitrescu@intel.com",
    "date": "2022-07-18T13:26:00",
    "name": "[V2,6/9] pipeline: add API for shared library-based pipeline build",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "283d13107d96f67ed61b230ed6c08201029170ef",
    "submitter": {
        "id": 19,
        "url": "https://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20220718132603.339314-6-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 24021,
            "url": "https://patches.dpdk.org/api/series/24021/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=24021",
            "date": "2022-07-18T13:25:55",
            "name": "[V2,1/9] pipeline: move specification data structures to internal header",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/24021/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/114033/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/114033/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 4166BA0032;\n\tMon, 18 Jul 2022 15:26:50 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 896B342B7C;\n\tMon, 18 Jul 2022 15:26:21 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n by mails.dpdk.org (Postfix) with ESMTP id A074540041\n for <dev@dpdk.org>; Mon, 18 Jul 2022 15:26:15 +0200 (CEST)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Jul 2022 06:26:11 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com.) ([10.237.223.157])\n by fmsmga008.fm.intel.com with ESMTP; 18 Jul 2022 06:26:10 -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=1658150775; x=1689686775;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=tD7OfydY1Nmo3iXf/wGHyKNBcMHUHTjx7r2eS5jza30=;\n b=DOYv7mCPel71KevWjNseb3jeCmHcNkGW0sDg7C8t/DAPWP7aQ9S0Ocut\n 602qdBS9cNOmRjBV1R66X2ijQIs6fPNpf4tgi6OpaAk2nLYNRLwW3GPIl\n 1d0Bw5r43Z3uVrn03NGg/tuP+B+n63/X/G4iMy7KygTtjqIkVcuskF8vv\n 0dqXMOh0lFYm2DLw7c88WS3qHJHsQOTU0iGeVfJglnjEfhgkU8m0QHFHv\n 3Wbcw5Wdrp3pR4HAsszbNPq3XNIEdp/0+zEhq9lPb+Ge1ExraEplQj7Hw\n 7KIpnYbKGHXPYeMCFi7KKkk/+ZO2i16jhoac3fnyVE5W9gMB3i0+hfstb w==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6400,9594,10411\"; a=\"284974532\"",
            "E=Sophos;i=\"5.92,281,1650956400\"; d=\"scan'208\";a=\"284974532\"",
            "E=Sophos;i=\"5.92,281,1650956400\"; d=\"scan'208\";a=\"655275279\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "\"Kamalakannan R .\" <kamalakannan.r@intel.com>",
        "Subject": "[PATCH V2 6/9] pipeline: add API for shared library-based pipeline\n build",
        "Date": "Mon, 18 Jul 2022 13:26:00 +0000",
        "Message-Id": "<20220718132603.339314-6-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20220718132603.339314-1-cristian.dumitrescu@intel.com>",
        "References": "<20220718130713.339003-1-cristian.dumitrescu@intel.com>\n <20220718132603.339314-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": "Previously, the pipeline build operation was done based on the\nspecification file (typically produced by the P4 compiler), then the C\ncode with optimized functions for the pipeline actions and\ninstructions was generated, built into a shared object library, loaded\nand installed into the pipeline in a completely hardcoded and\nnon-customizable way.\n\nNow, this process is split into three explicit stages:\ni) code generation (specification file -> C file);\nii) code build (C file -> shared object library);\niii) code installation (library load into the pipeline).\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\nSigned-off-by: Kamalakannan R. <kamalakannan.r@intel.com>\n---\n examples/pipeline/cli.c              |  20 +-\n lib/pipeline/rte_swx_pipeline.c      | 289 +++++++++------------------\n lib/pipeline/rte_swx_pipeline.h      |  22 +-\n lib/pipeline/rte_swx_pipeline_spec.c |  51 -----\n lib/pipeline/version.map             |   2 +-\n 5 files changed, 108 insertions(+), 276 deletions(-)",
    "diff": "diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c\nindex ad553f19ab..1f75b5dc9d 100644\n--- a/examples/pipeline/cli.c\n+++ b/examples/pipeline/cli.c\n@@ -984,7 +984,7 @@ cmd_pipeline_port_out(char **tokens,\n }\n \n static const char cmd_pipeline_build_help[] =\n-\"pipeline <pipeline_name> build <spec_file>\\n\";\n+\"pipeline <pipeline_name> build <lib_file>\\n\";\n \n static void\n cmd_pipeline_build(char **tokens,\n@@ -994,9 +994,6 @@ cmd_pipeline_build(char **tokens,\n \tvoid *obj)\n {\n \tstruct pipeline *p = NULL;\n-\tFILE *spec = NULL;\n-\tuint32_t err_line;\n-\tconst char *err_msg;\n \tint status;\n \n \tif (n_tokens != 4) {\n@@ -1010,20 +1007,9 @@ cmd_pipeline_build(char **tokens,\n \t\treturn;\n \t}\n \n-\tspec = fopen(tokens[3], \"r\");\n-\tif (!spec) {\n-\t\tsnprintf(out, out_size, \"Cannot open file %s.\\n\", tokens[3]);\n-\t\treturn;\n-\t}\n-\n-\tstatus = rte_swx_pipeline_build_from_spec(p->p,\n-\t\tspec,\n-\t\t&err_line,\n-\t\t&err_msg);\n-\tfclose(spec);\n+\tstatus = rte_swx_pipeline_build_from_lib(p->p, tokens[3]);\n \tif (status) {\n-\t\tsnprintf(out, out_size, \"Error %d at line %u: %s\\n.\",\n-\t\t\tstatus, err_line, err_msg);\n+\t\tsnprintf(out, out_size, \"Pipeline build error (%d).\", status);\n \t\treturn;\n \t}\n \ndiff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c\nindex 52760111fd..03414bfd1f 100644\n--- a/lib/pipeline/rte_swx_pipeline.c\n+++ b/lib/pipeline/rte_swx_pipeline.c\n@@ -9807,9 +9807,6 @@ rte_swx_pipeline_instructions_config(struct rte_swx_pipeline *p,\n \treturn 0;\n }\n \n-static int\n-pipeline_compile(struct rte_swx_pipeline *p);\n-\n int\n rte_swx_pipeline_build(struct rte_swx_pipeline *p)\n {\n@@ -9899,8 +9896,6 @@ rte_swx_pipeline_build(struct rte_swx_pipeline *p)\n \n \tp->build_done = 1;\n \n-\tpipeline_compile(p);\n-\n \treturn 0;\n \n error:\n@@ -13222,160 +13217,6 @@ instruction_group_list_custom_instructions_count(struct instruction_group_list *\n \treturn n_custom_instr;\n }\n \n-static int\n-pipeline_codegen(struct rte_swx_pipeline *p, struct instruction_group_list *igl)\n-{\n-\tstruct action *a;\n-\tFILE *f = NULL;\n-\n-\t/* Create the .c file. */\n-\tf = fopen(\"/tmp/pipeline.c\", \"w\");\n-\tif (!f)\n-\t\treturn -EIO;\n-\n-\t/* Include the .h file. */\n-\tfprintf(f, \"#include \\\"rte_swx_pipeline_internal.h\\\"\\n\");\n-\n-\t/* Add the code for each action. */\n-\tTAILQ_FOREACH(a, &p->actions, node) {\n-\t\tfprintf(f, \"/**\\n * Action %s\\n */\\n\\n\", a->name);\n-\n-\t\taction_data_codegen(a, f);\n-\n-\t\tfprintf(f, \"\\n\");\n-\n-\t\taction_instr_codegen(a, f);\n-\n-\t\tfprintf(f, \"\\n\");\n-\t}\n-\n-\t/* Add the pipeline code. */\n-\tinstruction_group_list_codegen(igl, p, f);\n-\n-\t/* Close the .c file. */\n-\tfclose(f);\n-\n-\treturn 0;\n-}\n-\n-#ifndef RTE_SWX_PIPELINE_CMD_MAX_SIZE\n-#define RTE_SWX_PIPELINE_CMD_MAX_SIZE 4096\n-#endif\n-\n-static int\n-pipeline_libload(struct rte_swx_pipeline *p, struct instruction_group_list *igl)\n-{\n-\tstruct action *a;\n-\tstruct instruction_group *g;\n-\tchar *dir_in, *buffer = NULL;\n-\tconst char *dir_out;\n-\tint status = 0;\n-\n-\t/* Get the environment variables. */\n-\tdir_in = getenv(\"RTE_INSTALL_DIR\");\n-\tif (!dir_in) {\n-\t\tstatus = -EINVAL;\n-\t\tgoto free;\n-\t}\n-\n-\tdir_out = \"/tmp\";\n-\n-\t/* Memory allocation for the command buffer. */\n-\tbuffer = malloc(RTE_SWX_PIPELINE_CMD_MAX_SIZE);\n-\tif (!buffer) {\n-\t\tstatus = -ENOMEM;\n-\t\tgoto free;\n-\t}\n-\n-\tsnprintf(buffer,\n-\t\t RTE_SWX_PIPELINE_CMD_MAX_SIZE,\n-\t\t \"gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s/pipeline.o %s/pipeline.c \"\n-\t\t \"-I %s/lib/pipeline \"\n-\t\t \"-I %s/lib/eal/include \"\n-\t\t \"-I %s/lib/eal/x86/include \"\n-\t\t \"-I %s/lib/eal/include/generic \"\n-\t\t \"-I %s/lib/meter \"\n-\t\t \"-I %s/lib/port \"\n-\t\t \"-I %s/lib/table \"\n-\t\t \"-I %s/lib/pipeline \"\n-\t\t \"-I %s/config \"\n-\t\t \"-I %s/build \"\n-\t\t \"-I %s/lib/eal/linux/include \"\n-\t\t \">%s/pipeline.log 2>&1 \"\n-\t\t \"&& \"\n-\t\t \"gcc -shared %s/pipeline.o -o %s/libpipeline.so \"\n-\t\t \">>%s/pipeline.log 2>&1\",\n-\t\t dir_out,\n-\t\t dir_out,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_in,\n-\t\t dir_out,\n-\t\t dir_out,\n-\t\t dir_out,\n-\t\t dir_out);\n-\n-\t/* Build the shared object library. */\n-\tstatus = system(buffer);\n-\tif (status)\n-\t\tgoto free;\n-\n-\t/* Open library. */\n-\tsnprintf(buffer,\n-\t\t RTE_SWX_PIPELINE_CMD_MAX_SIZE,\n-\t\t \"%s/libpipeline.so\",\n-\t\t dir_out);\n-\n-\tp->lib = dlopen(buffer, RTLD_LAZY);\n-\tif (!p->lib) {\n-\t\tstatus = -EIO;\n-\t\tgoto free;\n-\t}\n-\n-\t/* Get the action function symbols. */\n-\tTAILQ_FOREACH(a, &p->actions, node) {\n-\t\tsnprintf(buffer, RTE_SWX_PIPELINE_CMD_MAX_SIZE, \"action_%s_run\", a->name);\n-\n-\t\tp->action_funcs[a->id] = dlsym(p->lib, buffer);\n-\t\tif (!p->action_funcs[a->id]) {\n-\t\t\tstatus = -EINVAL;\n-\t\t\tgoto free;\n-\t\t}\n-\t}\n-\n-\t/* Get the pipeline function symbols. */\n-\tTAILQ_FOREACH(g, igl, node) {\n-\t\tif (g->first_instr_id == g->last_instr_id)\n-\t\t\tcontinue;\n-\n-\t\tsnprintf(buffer, RTE_SWX_PIPELINE_CMD_MAX_SIZE, \"pipeline_func_%u\", g->group_id);\n-\n-\t\tg->func = dlsym(p->lib, buffer);\n-\t\tif (!g->func) {\n-\t\t\tstatus = -EINVAL;\n-\t\t\tgoto free;\n-\t\t}\n-\t}\n-\n-free:\n-\tif (status && p->lib) {\n-\t\tdlclose(p->lib);\n-\t\tp->lib = NULL;\n-\t}\n-\n-\tfree(buffer);\n-\n-\treturn status;\n-}\n-\n static int\n pipeline_adjust_check(struct rte_swx_pipeline *p __rte_unused,\n \t\t      struct instruction_group_list *igl)\n@@ -13443,41 +13284,6 @@ pipeline_adjust(struct rte_swx_pipeline *p, struct instruction_group_list *igl)\n \tinstr_jmp_resolve(p->instructions, p->instruction_data, p->n_instructions);\n }\n \n-static int\n-pipeline_compile(struct rte_swx_pipeline *p)\n-{\n-\tstruct instruction_group_list *igl = NULL;\n-\tint status = 0;\n-\n-\tigl = instruction_group_list_create(p);\n-\tif (!igl) {\n-\t\tstatus = -ENOMEM;\n-\t\tgoto free;\n-\t}\n-\n-\t/* Code generation. */\n-\tstatus = pipeline_codegen(p, igl);\n-\tif (status)\n-\t\tgoto free;\n-\n-\t/* Build and load the shared object library. */\n-\tstatus = pipeline_libload(p, igl);\n-\tif (status)\n-\t\tgoto free;\n-\n-\t/* Adjust instructions. */\n-\tstatus = pipeline_adjust_check(p, igl);\n-\tif (status)\n-\t\tgoto free;\n-\n-\tpipeline_adjust(p, igl);\n-\n-free:\n-\tinstruction_group_list_free(igl);\n-\n-\treturn status;\n-}\n-\n int\n rte_swx_pipeline_codegen(FILE *spec_file,\n \t\t\t FILE *code_file,\n@@ -13570,3 +13376,98 @@ rte_swx_pipeline_codegen(FILE *spec_file,\n \n \treturn status;\n }\n+\n+int\n+rte_swx_pipeline_build_from_lib(struct rte_swx_pipeline *p,\n+\t\t\t\tconst char *lib_file_name)\n+{\n+\tvoid *lib = NULL;\n+\tstruct pipeline_spec *s = NULL;\n+\tstruct instruction_group_list *igl = NULL;\n+\tstruct action *a;\n+\tstruct instruction_group *g;\n+\tint status = 0;\n+\n+\t/* Check input arguments. */\n+\tif (!p || p->build_done || !lib_file_name || !lib_file_name[0]) {\n+\t\tstatus = -EINVAL;\n+\t\tgoto free;\n+\t}\n+\n+\t/* Open the library. */\n+\tlib = dlopen(lib_file_name, RTLD_LAZY);\n+\tif (!lib) {\n+\t\tstatus = -EIO;\n+\t\tgoto free;\n+\t}\n+\n+\t/* Get the pipeline specification structure from the library. */\n+\ts = dlsym(lib, \"pipeline_spec\");\n+\tif (!s) {\n+\t\tstatus = -EINVAL;\n+\t\tgoto free;\n+\t}\n+\n+\t/* Pipeline configuration based on the specification structure. */\n+\tstatus = pipeline_spec_configure(p, s, NULL);\n+\tif (status)\n+\t\tgoto free;\n+\n+\t/* Pipeline build. */\n+\tstatus = rte_swx_pipeline_build(p);\n+\tif (status)\n+\t\tgoto free;\n+\n+\t/* Action instructions. */\n+\tTAILQ_FOREACH(a, &p->actions, node) {\n+\t\tchar name[RTE_SWX_NAME_SIZE * 2];\n+\n+\t\tsnprintf(name, sizeof(name), \"action_%s_run\", a->name);\n+\n+\t\tp->action_funcs[a->id] = dlsym(lib, name);\n+\t\tif (!p->action_funcs[a->id]) {\n+\t\t\tstatus = -EINVAL;\n+\t\t\tgoto free;\n+\t\t}\n+\t}\n+\n+\t/* Pipeline instructions. */\n+\tigl = instruction_group_list_create(p);\n+\tif (!igl) {\n+\t\tstatus = -ENOMEM;\n+\t\tgoto free;\n+\t}\n+\n+\tTAILQ_FOREACH(g, igl, node) {\n+\t\tchar name[RTE_SWX_NAME_SIZE * 2];\n+\n+\t\tif (g->first_instr_id == g->last_instr_id)\n+\t\t\tcontinue;\n+\n+\t\tsnprintf(name, sizeof(name), \"pipeline_func_%u\", g->group_id);\n+\n+\t\tg->func = dlsym(lib, name);\n+\t\tif (!g->func) {\n+\t\t\tstatus = -EINVAL;\n+\t\t\tgoto free;\n+\t\t}\n+\t}\n+\n+\tstatus = pipeline_adjust_check(p, igl);\n+\tif (status)\n+\t\tgoto free;\n+\n+\tpipeline_adjust(p, igl);\n+\n+\tp->lib = lib;\n+\n+free:\n+\tif (status && lib) {\n+\t\tdlclose(lib);\n+\t\tp->lib = NULL;\n+\t}\n+\n+\tinstruction_group_list_free(igl);\n+\n+\treturn status;\n+}\ndiff --git a/lib/pipeline/rte_swx_pipeline.h b/lib/pipeline/rte_swx_pipeline.h\nindex 2bd019b05f..cb834cd64d 100644\n--- a/lib/pipeline/rte_swx_pipeline.h\n+++ b/lib/pipeline/rte_swx_pipeline.h\n@@ -967,30 +967,26 @@ rte_swx_pipeline_codegen(FILE *spec_file,\n \t\t\t const char **err_msg);\n \n /**\n- * Pipeline build from specification file\n+ * Pipeline build from shared object library\n+ *\n+ * The shared object library must be built from the C language source code file\n+ * previously generated by the rte_swx_pipeline_codegen() API function.\n  *\n  * @param[in] p\n  *   Pipeline handle.\n- * @param[in] spec\n- *   Pipeline specification file.\n- * @param[out] err_line\n- *   In case of error and non-NULL, the line number within the *spec* file where\n- *   the error occurred. The first line number in the file is 1.\n- * @param[out] err_msg\n- *   In case of error and non-NULL, the error message.\n+ * @param[in] lib_file_name\n+ *   Shared object library file name.\n  * @return\n  *   0 on success or the following error codes otherwise:\n  *   -EINVAL: Invalid argument;\n  *   -ENOMEM: Not enough space/cannot allocate memory;\n- *   -EEXIST: Resource with the same name already exists;\n+ *   -EEXIST: Pipeline was already built successfully;\n  *   -ENODEV: Extern object or table creation error.\n  */\n __rte_experimental\n int\n-rte_swx_pipeline_build_from_spec(struct rte_swx_pipeline *p,\n-\t\t\t\t FILE *spec,\n-\t\t\t\t uint32_t *err_line,\n-\t\t\t\t const char **err_msg);\n+rte_swx_pipeline_build_from_lib(struct rte_swx_pipeline *p,\n+\t\t\t\tconst char *lib_file_name);\n \n /**\n  * Pipeline run\ndiff --git a/lib/pipeline/rte_swx_pipeline_spec.c b/lib/pipeline/rte_swx_pipeline_spec.c\nindex bf21fe17ba..d6650fcc80 100644\n--- a/lib/pipeline/rte_swx_pipeline_spec.c\n+++ b/lib/pipeline/rte_swx_pipeline_spec.c\n@@ -3515,54 +3515,3 @@ pipeline_spec_configure(struct rte_swx_pipeline *p,\n \n \treturn 0;\n }\n-\n-int\n-rte_swx_pipeline_build_from_spec(struct rte_swx_pipeline *p,\n-\t\t\t\t FILE *spec_file,\n-\t\t\t\t uint32_t *err_line,\n-\t\t\t\t const char **err_msg)\n-{\n-\tstruct pipeline_spec *s = NULL;\n-\tint status = 0;\n-\n-\t/* Check the input arguments. */\n-\tif (!p || !spec_file) {\n-\t\tif (err_line)\n-\t\t\t*err_line = 0;\n-\t\tif (err_msg)\n-\t\t\t*err_msg = \"Invalid input argument.\";\n-\t\tstatus = -EINVAL;\n-\t\tgoto error;\n-\t}\n-\n-\t/* Spec file parse. */\n-\ts = pipeline_spec_parse(spec_file, err_line, err_msg);\n-\tif (!s) {\n-\t\tstatus = -EINVAL;\n-\t\tgoto error;\n-\t}\n-\n-\t/* Pipeline configure. */\n-\tstatus = pipeline_spec_configure(p, s, err_msg);\n-\tif (status) {\n-\t\tif (err_line)\n-\t\t\t*err_line = 0;\n-\t\tgoto error;\n-\t}\n-\n-\t/* Pipeline build. */\n-\tstatus = rte_swx_pipeline_build(p);\n-\tif (status) {\n-\t\tif (err_line)\n-\t\t\t*err_line = 0;\n-\t\tif (err_msg)\n-\t\t\t*err_msg = \"Pipeline build error.\";\n-\t\tgoto error;\n-\t}\n-\n-\treturn 0;\n-\n-error:\n-\tpipeline_spec_free(s);\n-\treturn status;\n-}\ndiff --git a/lib/pipeline/version.map b/lib/pipeline/version.map\nindex 51165d48cf..810cc56467 100644\n--- a/lib/pipeline/version.map\n+++ b/lib/pipeline/version.map\n@@ -82,7 +82,6 @@ EXPERIMENTAL {\n \trte_swx_ctl_table_ops_get;\n \trte_swx_pipeline_action_config;\n \trte_swx_pipeline_build;\n-\trte_swx_pipeline_build_from_spec;\n \trte_swx_pipeline_config;\n \trte_swx_pipeline_extern_func_register;\n \trte_swx_pipeline_extern_object_config;\n@@ -148,4 +147,5 @@ EXPERIMENTAL {\n \n \t#added in 22.11\n \trte_swx_pipeline_codegen;\n+\trte_swx_pipeline_build_from_lib;\n };\n",
    "prefixes": [
        "V2",
        "6/9"
    ]
}