get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 67847,
    "url": "https://patches.dpdk.org/api/patches/67847/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20200405085613.1336841-26-jerinj@marvell.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": "<20200405085613.1336841-26-jerinj@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200405085613.1336841-26-jerinj@marvell.com",
    "date": "2020-04-05T08:56:09",
    "name": "[v4,25/29] l3fwd-graph: add graph based l3fwd skeleton",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "0a65d3dbb48932d14974e4c1640bba81f4ef90b8",
    "submitter": {
        "id": 1188,
        "url": "https://patches.dpdk.org/api/people/1188/?format=api",
        "name": "Jerin Jacob Kollanukkaran",
        "email": "jerinj@marvell.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/20200405085613.1336841-26-jerinj@marvell.com/mbox/",
    "series": [
        {
            "id": 9203,
            "url": "https://patches.dpdk.org/api/series/9203/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=9203",
            "date": "2020-04-05T08:55:44",
            "name": "graph: introduce graph subsystem",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/9203/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/67847/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/67847/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 D1153A0577;\n\tSun,  5 Apr 2020 11:01:58 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 575A11BF44;\n\tSun,  5 Apr 2020 10:57:55 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174]) by dpdk.org (Postfix) with ESMTP id 0A7691BFC2\n for <dev@dpdk.org>; Sun,  5 Apr 2020 10:57:53 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id\n 0358uSrh029744; Sun, 5 Apr 2020 01:57:51 -0700",
            "from sc-exch04.marvell.com ([199.233.58.184])\n by mx0a-0016f401.pphosted.com with ESMTP id 306qkqtmtu-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Sun, 05 Apr 2020 01:57:51 -0700",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by SC-EXCH04.marvell.com\n (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Sun, 5 Apr 2020 01:57:50 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend\n Transport; Sun, 5 Apr 2020 01:57:50 -0700",
            "from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14])\n by maili.marvell.com (Postfix) with ESMTP id 583E83F703F;\n Sun,  5 Apr 2020 01:57:45 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0818;\n bh=sFy5RKt7F5t1OGxxyvDVhpwNtJs5E5AUFJGCzF1N7xs=;\n b=GbbC5+WWlme/irq+/dD9R2360yt9IAgDlR3kTdysIIGu4iQBOEpYtL9ghe7k1KLmPV6Y\n wEQFJYYC7gjYpNmK6ya8gUBG2vJv84y2wjy2zu4DDBCJafr+jPLS8nPWWyC0UoUnf6DT\n C1gmlNAZTjxmkktT2FENn+98omYj7H4+9VXdq/gYgXOjV8qtLFVC4tH7TaLdi+fJinkR\n +OeVdFA9KuBpkD5fsipNaM5wipHRvrlX/Q1isFpXPoorFpITwGPt+6MWyDvVtdlOdVYW\n 9Mcl+0VA8sUM2G7j6A4pAGjaU9mSRpf3JxuKSDOPPx3SQnEfcMIPaSxWVhsuj0kDvV8M 0Q==",
        "From": "<jerinj@marvell.com>",
        "To": "Thomas Monjalon <thomas@monjalon.net>, Marko Kovacevic\n <marko.kovacevic@intel.com>, Ori Kam <orika@mellanox.com>, Bruce Richardson\n <bruce.richardson@intel.com>, Radu Nicolau <radu.nicolau@intel.com>, \"Akhil\n Goyal\" <akhil.goyal@nxp.com>, Tomasz Kantecki <tomasz.kantecki@intel.com>,\n Sunil Kumar Kori <skori@marvell.com>, Pavan Nikhilesh\n <pbhagavatula@marvell.com>, Nithin Dabilpuram <ndabilpuram@marvell.com>",
        "CC": "<dev@dpdk.org>, <david.marchand@redhat.com>, <mdr@ashroe.eu>,\n <mattias.ronnblom@ericsson.com>, <kirankumark@marvell.com>,\n <xiao.w.wang@intel.com>",
        "Date": "Sun, 5 Apr 2020 14:26:09 +0530",
        "Message-ID": "<20200405085613.1336841-26-jerinj@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20200405085613.1336841-1-jerinj@marvell.com>",
        "References": "<20200331192945.2466880-1-jerinj@marvell.com>\n <20200405085613.1336841-1-jerinj@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676\n definitions=2020-04-05_01:2020-04-03,\n 2020-04-05 signatures=0",
        "Subject": "[dpdk-dev] [PATCH v4 25/29] l3fwd-graph: add graph based l3fwd\n\tskeleton",
        "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": "From: Nithin Dabilpuram <ndabilpuram@marvell.com>\n\nAdd graph based l3fwd application skeleton with cmdline\nparsing support inline with normal l3fwd.\n\nSigned-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>\n---\n MAINTAINERS                      |   3 +\n examples/Makefile                |   3 +\n examples/l3fwd-graph/Makefile    |  58 ++++\n examples/l3fwd-graph/main.c      | 525 +++++++++++++++++++++++++++++++\n examples/l3fwd-graph/meson.build |  13 +\n examples/meson.build             |   6 +-\n 6 files changed, 606 insertions(+), 2 deletions(-)\n create mode 100644 examples/l3fwd-graph/Makefile\n create mode 100644 examples/l3fwd-graph/main.c\n create mode 100644 examples/l3fwd-graph/meson.build",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 55fb9bbb0..de57f452b 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1574,6 +1574,9 @@ F: doc/guides/sample_app_ug/l2_forward_event.rst\n F: examples/l3fwd/\n F: doc/guides/sample_app_ug/l3_forward.rst\n \n+M: Nithin Dabilpuram <ndabilpuram@marvell.com>\n+F: examples/l3fwd-graph/\n+\n F: examples/link_status_interrupt/\n F: doc/guides/sample_app_ug/link_status_intr.rst\n \ndiff --git a/examples/Makefile b/examples/Makefile\nindex feff79784..b7e99a2f7 100644\n--- a/examples/Makefile\n+++ b/examples/Makefile\n@@ -51,6 +51,9 @@ DIRS-$(CONFIG_RTE_LIBRTE_ACL) += l3fwd-acl\n ifeq ($(CONFIG_RTE_LIBRTE_LPM)$(CONFIG_RTE_LIBRTE_HASH),yy)\n DIRS-$(CONFIG_RTE_LIBRTE_POWER) += l3fwd-power\n endif\n+ifeq ($(CONFIG_RTE_LIBRTE_GRAPH),y)\n+DIRS-y += l3fwd-graph\n+endif\n DIRS-y += link_status_interrupt\n DIRS-y += multi_process\n DIRS-y += ntb\ndiff --git a/examples/l3fwd-graph/Makefile b/examples/l3fwd-graph/Makefile\nnew file mode 100644\nindex 000000000..f3cf275ec\n--- /dev/null\n+++ b/examples/l3fwd-graph/Makefile\n@@ -0,0 +1,58 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(C) 2020 Marvell International Ltd.\n+\n+# binary name\n+APP = l3fwd-graph\n+\n+# all source are stored in SRCS-y\n+SRCS-y := main.c\n+\n+# Build using pkg-config variables if possible\n+ifeq ($(shell pkg-config --exists libdpdk && echo 0),0)\n+\n+all: shared\n+.PHONY: shared static\n+shared: build/$(APP)-shared\n+\tln -sf $(APP)-shared build/$(APP)\n+static: build/$(APP)-static\n+\tln -sf $(APP)-static build/$(APP)\n+\n+PKGCONF=pkg-config --define-prefix\n+\n+PC_FILE := $(shell $(PKGCONF) --path libdpdk)\n+CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) -DALLOW_EXPERIMENTAL_API\n+LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)\n+LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk)\n+\n+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build\n+\t$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)\n+\n+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build\n+\t$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)\n+\n+build:\n+\t@mkdir -p $@\n+\n+.PHONY: clean\n+clean:\n+\trm -f build/$(APP) build/$(APP)-static build/$(APP)-shared\n+\ttest -d build && rmdir -p build || true\n+\n+else # Build using legacy build system\n+\n+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, detect a build directory, by looking for a path with a .config\n+RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config)))))\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+CFLAGS += -DALLOW_EXPERIMENTAL_API\n+CFLAGS += -I$(SRCDIR)\n+CFLAGS += -O3 $(USER_FLAGS)\n+CFLAGS += $(WERROR_FLAGS)\n+\n+include $(RTE_SDK)/mk/rte.extapp.mk\n+endif\ndiff --git a/examples/l3fwd-graph/main.c b/examples/l3fwd-graph/main.c\nnew file mode 100644\nindex 000000000..e0c6f42fa\n--- /dev/null\n+++ b/examples/l3fwd-graph/main.c\n@@ -0,0 +1,525 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2020 Marvell International Ltd.\n+ */\n+\n+#include <arpa/inet.h>\n+#include <errno.h>\n+#include <getopt.h>\n+#include <inttypes.h>\n+#include <signal.h>\n+#include <stdarg.h>\n+#include <stdbool.h>\n+#include <stdint.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include <sys/socket.h>\n+#include <sys/types.h>\n+#include <sys/queue.h>\n+#include <unistd.h>\n+\n+#include <rte_branch_prediction.h>\n+#include <rte_common.h>\n+#include <rte_eal.h>\n+#include <rte_ethdev.h>\n+#include <rte_log.h>\n+#include <rte_mempool.h>\n+#include <rte_per_lcore.h>\n+#include <rte_string_fns.h>\n+#include <rte_vect.h>\n+\n+#include <cmdline_parse.h>\n+#include <cmdline_parse_etheraddr.h>\n+\n+/* Log type */\n+#define RTE_LOGTYPE_L3FWD_GRAPH RTE_LOGTYPE_USER1\n+\n+/*\n+ * Configurable number of RX/TX ring descriptors\n+ */\n+#define RTE_TEST_RX_DESC_DEFAULT 1024\n+#define RTE_TEST_TX_DESC_DEFAULT 1024\n+\n+#define MAX_TX_QUEUE_PER_PORT RTE_MAX_ETHPORTS\n+#define MAX_RX_QUEUE_PER_PORT 128\n+\n+#define MAX_RX_QUEUE_PER_LCORE 16\n+\n+#define MAX_LCORE_PARAMS 1024\n+\n+#define NB_SOCKETS 8\n+\n+/**< Ports set in promiscuous mode off by default. */\n+static int promiscuous_on;\n+\n+static int numa_on = 1;\t  /**< NUMA is enabled by default. */\n+static int per_port_pool; /**< Use separate buffer pools per port; disabled */\n+\t\t\t  /**< by default */\n+\n+static volatile bool force_quit;\n+\n+/* Ethernet addresses of ports */\n+static uint64_t dest_eth_addr[RTE_MAX_ETHPORTS];\n+xmm_t val_eth[RTE_MAX_ETHPORTS];\n+\n+/* Mask of enabled ports */\n+static uint32_t enabled_port_mask;\n+\n+struct lcore_rx_queue {\n+\tuint16_t port_id;\n+\tuint8_t queue_id;\n+};\n+\n+/* Lcore conf */\n+struct lcore_conf {\n+\tuint16_t n_rx_queue;\n+\tstruct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE];\n+} __rte_cache_aligned;\n+\n+static struct lcore_conf lcore_conf[RTE_MAX_LCORE];\n+\n+struct lcore_params {\n+\tuint16_t port_id;\n+\tuint8_t queue_id;\n+\tuint8_t lcore_id;\n+} __rte_cache_aligned;\n+\n+static struct lcore_params lcore_params_array[MAX_LCORE_PARAMS];\n+static struct lcore_params lcore_params_array_default[] = {\n+\t{0, 0, 2}, {0, 1, 2}, {0, 2, 2}, {1, 0, 2}, {1, 1, 2},\n+\t{1, 2, 2}, {2, 0, 2}, {3, 0, 3}, {3, 1, 3},\n+};\n+\n+static struct lcore_params *lcore_params = lcore_params_array_default;\n+static uint16_t nb_lcore_params = RTE_DIM(lcore_params_array_default);\n+\n+static struct rte_eth_conf port_conf = {\n+\t.rxmode = {\n+\t\t.mq_mode = ETH_MQ_RX_RSS,\n+\t\t.max_rx_pkt_len = RTE_ETHER_MAX_LEN,\n+\t\t.split_hdr_size = 0,\n+\t},\n+\t.rx_adv_conf = {\n+\t\t.rss_conf = {\n+\t\t\t\t.rss_key = NULL,\n+\t\t\t\t.rss_hf = ETH_RSS_IP,\n+\t\t},\n+\t},\n+\t.txmode = {\n+\t\t.mq_mode = ETH_MQ_TX_NONE,\n+\t},\n+};\n+\n+static int\n+check_lcore_params(void)\n+{\n+\tuint8_t queue, lcore;\n+\tint socketid;\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < nb_lcore_params; ++i) {\n+\t\tqueue = lcore_params[i].queue_id;\n+\t\tif (queue >= MAX_RX_QUEUE_PER_PORT) {\n+\t\t\tprintf(\"Invalid queue number: %hhu\\n\", queue);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tlcore = lcore_params[i].lcore_id;\n+\t\tif (!rte_lcore_is_enabled(lcore)) {\n+\t\t\tprintf(\"Error: lcore %hhu is not enabled in lcore mask\\n\",\n+\t\t\t       lcore);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (lcore == rte_get_master_lcore()) {\n+\t\t\tprintf(\"Error: lcore %u is master lcore\\n\", lcore);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tsocketid = rte_lcore_to_socket_id(lcore);\n+\t\tif ((socketid != 0) && (numa_on == 0)) {\n+\t\t\tprintf(\"Warning: lcore %hhu is on socket %d with numa off\\n\",\n+\t\t\t       lcore, socketid);\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+check_port_config(void)\n+{\n+\tuint16_t portid;\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < nb_lcore_params; ++i) {\n+\t\tportid = lcore_params[i].port_id;\n+\t\tif ((enabled_port_mask & (1 << portid)) == 0) {\n+\t\t\tprintf(\"Port %u is not enabled in port mask\\n\", portid);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tif (!rte_eth_dev_is_valid_port(portid)) {\n+\t\t\tprintf(\"Port %u is not present on the board\\n\", portid);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+init_lcore_rx_queues(void)\n+{\n+\tuint16_t i, nb_rx_queue;\n+\tuint8_t lcore;\n+\n+\tfor (i = 0; i < nb_lcore_params; ++i) {\n+\t\tlcore = lcore_params[i].lcore_id;\n+\t\tnb_rx_queue = lcore_conf[lcore].n_rx_queue;\n+\t\tif (nb_rx_queue >= MAX_RX_QUEUE_PER_LCORE) {\n+\t\t\tprintf(\"Error: too many queues (%u) for lcore: %u\\n\",\n+\t\t\t       (unsigned int)nb_rx_queue + 1,\n+\t\t\t       (unsigned int)lcore);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tlcore_conf[lcore].rx_queue_list[nb_rx_queue].port_id =\n+\t\t\tlcore_params[i].port_id;\n+\t\tlcore_conf[lcore].rx_queue_list[nb_rx_queue].queue_id =\n+\t\t\tlcore_params[i].queue_id;\n+\t\tlcore_conf[lcore].n_rx_queue++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* Display usage */\n+static void\n+print_usage(const char *prgname)\n+{\n+\tfprintf(stderr,\n+\t\t\"%s [EAL options] --\"\n+\t\t\" -p PORTMASK\"\n+\t\t\" [-P]\"\n+\t\t\" --config (port,queue,lcore)[,(port,queue,lcore)]\"\n+\t\t\" [--eth-dest=X,MM:MM:MM:MM:MM:MM]\"\n+\t\t\" [--enable-jumbo [--max-pkt-len PKTLEN]]\"\n+\t\t\" [--no-numa]\"\n+\t\t\" [--per-port-pool]\\n\\n\"\n+\n+\t\t\"  -p PORTMASK: Hexadecimal bitmask of ports to configure\\n\"\n+\t\t\"  -P : Enable promiscuous mode\\n\"\n+\t\t\"  --config (port,queue,lcore): Rx queue configuration\\n\"\n+\t\t\"  --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for \"\n+\t\t\"port X\\n\"\n+\t\t\"  --enable-jumbo: Enable jumbo frames\\n\"\n+\t\t\"  --max-pkt-len: Under the premise of enabling jumbo,\\n\"\n+\t\t\"                 maximum packet length in decimal (64-9600)\\n\"\n+\t\t\"  --no-numa: Disable numa awareness\\n\"\n+\t\t\"  --per-port-pool: Use separate buffer pool per port\\n\\n\",\n+\t\tprgname);\n+}\n+\n+static int\n+parse_max_pkt_len(const char *pktlen)\n+{\n+\tunsigned long len;\n+\tchar *end = NULL;\n+\n+\t/* Parse decimal string */\n+\tlen = strtoul(pktlen, &end, 10);\n+\tif ((pktlen[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n+\t\treturn -1;\n+\n+\tif (len == 0)\n+\t\treturn -1;\n+\n+\treturn len;\n+}\n+\n+static int\n+parse_portmask(const char *portmask)\n+{\n+\tchar *end = NULL;\n+\tunsigned long pm;\n+\n+\t/* Parse hexadecimal string */\n+\tpm = strtoul(portmask, &end, 16);\n+\tif ((portmask[0] == '\\0') || (end == NULL) || (*end != '\\0'))\n+\t\treturn -1;\n+\n+\tif (pm == 0)\n+\t\treturn -1;\n+\n+\treturn pm;\n+}\n+\n+static int\n+parse_config(const char *q_arg)\n+{\n+\tenum fieldnames { FLD_PORT = 0, FLD_QUEUE, FLD_LCORE, _NUM_FLD };\n+\tunsigned long int_fld[_NUM_FLD];\n+\tconst char *p, *p0 = q_arg;\n+\tchar *str_fld[_NUM_FLD];\n+\tuint32_t size;\n+\tchar s[256];\n+\tchar *end;\n+\tint i;\n+\n+\tnb_lcore_params = 0;\n+\n+\twhile ((p = strchr(p0, '(')) != NULL) {\n+\t\t++p;\n+\t\tp0 = strchr(p, ')');\n+\t\tif (p0 == NULL)\n+\t\t\treturn -1;\n+\n+\t\tsize = p0 - p;\n+\t\tif (size >= sizeof(s))\n+\t\t\treturn -1;\n+\n+\t\tsnprintf(s, sizeof(s), \"%.*s\", size, p);\n+\t\tif (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') !=\n+\t\t    _NUM_FLD)\n+\t\t\treturn -1;\n+\t\tfor (i = 0; i < _NUM_FLD; i++) {\n+\t\t\terrno = 0;\n+\t\t\tint_fld[i] = strtoul(str_fld[i], &end, 0);\n+\t\t\tif (errno != 0 || end == str_fld[i] || int_fld[i] > 255)\n+\t\t\t\treturn -1;\n+\t\t}\n+\t\tif (nb_lcore_params >= MAX_LCORE_PARAMS) {\n+\t\t\tprintf(\"Exceeded max number of lcore params: %hu\\n\",\n+\t\t\t       nb_lcore_params);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tlcore_params_array[nb_lcore_params].port_id =\n+\t\t\t(uint8_t)int_fld[FLD_PORT];\n+\t\tlcore_params_array[nb_lcore_params].queue_id =\n+\t\t\t(uint8_t)int_fld[FLD_QUEUE];\n+\t\tlcore_params_array[nb_lcore_params].lcore_id =\n+\t\t\t(uint8_t)int_fld[FLD_LCORE];\n+\t\t++nb_lcore_params;\n+\t}\n+\tlcore_params = lcore_params_array;\n+\n+\treturn 0;\n+}\n+\n+static void\n+parse_eth_dest(const char *optarg)\n+{\n+\tuint8_t c, *dest, peer_addr[6];\n+\tuint16_t portid;\n+\tchar *port_end;\n+\n+\terrno = 0;\n+\tportid = strtoul(optarg, &port_end, 10);\n+\tif (errno != 0 || port_end == optarg || *port_end++ != ',')\n+\t\trte_exit(EXIT_FAILURE, \"Invalid eth-dest: %s\", optarg);\n+\tif (portid >= RTE_MAX_ETHPORTS)\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t \"eth-dest: port %d >= RTE_MAX_ETHPORTS(%d)\\n\", portid,\n+\t\t\t RTE_MAX_ETHPORTS);\n+\n+\tif (cmdline_parse_etheraddr(NULL, port_end, &peer_addr,\n+\t\t\t\t    sizeof(peer_addr)) < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid ethernet address: %s\\n\",\n+\t\t\t port_end);\n+\tdest = (uint8_t *)&dest_eth_addr[portid];\n+\tfor (c = 0; c < 6; c++)\n+\t\tdest[c] = peer_addr[c];\n+\t*(uint64_t *)(val_eth + portid) = dest_eth_addr[portid];\n+}\n+\n+#define MAX_JUMBO_PKT_LEN  9600\n+#define MEMPOOL_CACHE_SIZE 256\n+\n+static const char short_options[] = \"p:\" /* portmask */\n+\t\t\t\t    \"P\"\t /* promiscuous */\n+\t;\n+\n+#define CMD_LINE_OPT_CONFIG\t   \"config\"\n+#define CMD_LINE_OPT_ETH_DEST\t   \"eth-dest\"\n+#define CMD_LINE_OPT_NO_NUMA\t   \"no-numa\"\n+#define CMD_LINE_OPT_ENABLE_JUMBO  \"enable-jumbo\"\n+#define CMD_LINE_OPT_PER_PORT_POOL \"per-port-pool\"\n+enum {\n+\t/* Long options mapped to a short option */\n+\n+\t/* First long only option value must be >= 256, so that we won't\n+\t * conflict with short options\n+\t */\n+\tCMD_LINE_OPT_MIN_NUM = 256,\n+\tCMD_LINE_OPT_CONFIG_NUM,\n+\tCMD_LINE_OPT_ETH_DEST_NUM,\n+\tCMD_LINE_OPT_NO_NUMA_NUM,\n+\tCMD_LINE_OPT_ENABLE_JUMBO_NUM,\n+\tCMD_LINE_OPT_PARSE_PER_PORT_POOL,\n+};\n+\n+static const struct option lgopts[] = {\n+\t{CMD_LINE_OPT_CONFIG, 1, 0, CMD_LINE_OPT_CONFIG_NUM},\n+\t{CMD_LINE_OPT_ETH_DEST, 1, 0, CMD_LINE_OPT_ETH_DEST_NUM},\n+\t{CMD_LINE_OPT_NO_NUMA, 0, 0, CMD_LINE_OPT_NO_NUMA_NUM},\n+\t{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, CMD_LINE_OPT_ENABLE_JUMBO_NUM},\n+\t{CMD_LINE_OPT_PER_PORT_POOL, 0, 0, CMD_LINE_OPT_PARSE_PER_PORT_POOL},\n+\t{NULL, 0, 0, 0},\n+};\n+\n+/*\n+ * This expression is used to calculate the number of mbufs needed\n+ * depending on user input, taking  into account memory for rx and\n+ * tx hardware rings, cache per lcore and mtable per port per lcore.\n+ * RTE_MAX is used to ensure that NB_MBUF never goes below a minimum\n+ * value of 8192\n+ */\n+#define NB_MBUF(nports)                                                        \\\n+\tRTE_MAX((nports * nb_rx_queue * nb_rxd +                               \\\n+\t\t nports * nb_lcores * RTE_GRAPH_BURST_SIZE +                   \\\n+\t\t nports * n_tx_queue * nb_txd +                                \\\n+\t\t nb_lcores * MEMPOOL_CACHE_SIZE), 8192u)\n+\n+/* Parse the argument given in the command line of the application */\n+static int\n+parse_args(int argc, char **argv)\n+{\n+\tchar *prgname = argv[0];\n+\tint option_index;\n+\tchar **argvopt;\n+\tint opt, ret;\n+\n+\targvopt = argv;\n+\n+\t/* Error or normal output strings. */\n+\twhile ((opt = getopt_long(argc, argvopt, short_options, lgopts,\n+\t\t\t\t  &option_index)) != EOF) {\n+\n+\t\tswitch (opt) {\n+\t\t/* Portmask */\n+\t\tcase 'p':\n+\t\t\tenabled_port_mask = parse_portmask(optarg);\n+\t\t\tif (enabled_port_mask == 0) {\n+\t\t\t\tfprintf(stderr, \"Invalid portmask\\n\");\n+\t\t\t\tprint_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'P':\n+\t\t\tpromiscuous_on = 1;\n+\t\t\tbreak;\n+\n+\t\t/* Long options */\n+\t\tcase CMD_LINE_OPT_CONFIG_NUM:\n+\t\t\tret = parse_config(optarg);\n+\t\t\tif (ret) {\n+\t\t\t\tfprintf(stderr, \"Invalid config\\n\");\n+\t\t\t\tprint_usage(prgname);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase CMD_LINE_OPT_ETH_DEST_NUM:\n+\t\t\tparse_eth_dest(optarg);\n+\t\t\tbreak;\n+\n+\t\tcase CMD_LINE_OPT_NO_NUMA_NUM:\n+\t\t\tnuma_on = 0;\n+\t\t\tbreak;\n+\n+\t\tcase CMD_LINE_OPT_ENABLE_JUMBO_NUM: {\n+\t\t\tconst struct option lenopts = {\"max-pkt-len\",\n+\t\t\t\t\t\t       required_argument, 0, 0};\n+\n+\t\t\tport_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;\n+\t\t\tport_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;\n+\n+\t\t\t/*\n+\t\t\t * if no max-pkt-len set, use the default\n+\t\t\t * value RTE_ETHER_MAX_LEN.\n+\t\t\t */\n+\t\t\tif (getopt_long(argc, argvopt, \"\", &lenopts,\n+\t\t\t\t\t&option_index) == 0) {\n+\t\t\t\tret = parse_max_pkt_len(optarg);\n+\t\t\t\tif (ret < 64 || ret > MAX_JUMBO_PKT_LEN) {\n+\t\t\t\t\tfprintf(stderr, \"Invalid maximum \"\n+\t\t\t\t\t\t\t\"packet length\\n\");\n+\t\t\t\t\tprint_usage(prgname);\n+\t\t\t\t\treturn -1;\n+\t\t\t\t}\n+\t\t\t\tport_conf.rxmode.max_rx_pkt_len = ret;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tcase CMD_LINE_OPT_PARSE_PER_PORT_POOL:\n+\t\t\tprintf(\"Per port buffer pool is enabled\\n\");\n+\t\t\tper_port_pool = 1;\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\tprint_usage(prgname);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tif (optind >= 0)\n+\t\targv[optind - 1] = prgname;\n+\tret = optind - 1;\n+\toptind = 1; /* Reset getopt lib */\n+\n+\treturn ret;\n+}\n+\n+static void\n+signal_handler(int signum)\n+{\n+\tif (signum == SIGINT || signum == SIGTERM) {\n+\t\tprintf(\"\\n\\nSignal %d received, preparing to exit...\\n\",\n+\t\t       signum);\n+\t\tforce_quit = true;\n+\t}\n+}\n+\n+int\n+main(int argc, char **argv)\n+{\n+\tuint16_t portid;\n+\tint ret;\n+\n+\t/* Init EAL */\n+\tret = rte_eal_init(argc, argv);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid EAL parameters\\n\");\n+\targc -= ret;\n+\targv += ret;\n+\n+\tforce_quit = false;\n+\tsignal(SIGINT, signal_handler);\n+\tsignal(SIGTERM, signal_handler);\n+\n+\t/* Pre-init dst MACs for all ports to 02:00:00:00:00:xx */\n+\tfor (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {\n+\t\tdest_eth_addr[portid] =\n+\t\t\tRTE_ETHER_LOCAL_ADMIN_ADDR + ((uint64_t)portid << 40);\n+\t\t*(uint64_t *)(val_eth + portid) = dest_eth_addr[portid];\n+\t}\n+\n+\t/* Parse application arguments (after the EAL ones) */\n+\tret = parse_args(argc, argv);\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"Invalid L3FWD_GRAPH parameters\\n\");\n+\n+\tif (check_lcore_params() < 0)\n+\t\trte_exit(EXIT_FAILURE, \"check_lcore_params() failed\\n\");\n+\n+\tret = init_lcore_rx_queues();\n+\tif (ret < 0)\n+\t\trte_exit(EXIT_FAILURE, \"init_lcore_rx_queues() failed\\n\");\n+\n+\tif (check_port_config() < 0)\n+\t\trte_exit(EXIT_FAILURE, \"check_port_config() failed\\n\");\n+\n+\tprintf(\"Bye...\\n\");\n+\n+\treturn ret;\n+}\ndiff --git a/examples/l3fwd-graph/meson.build b/examples/l3fwd-graph/meson.build\nnew file mode 100644\nindex 000000000..a816bd890\n--- /dev/null\n+++ b/examples/l3fwd-graph/meson.build\n@@ -0,0 +1,13 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(C) 2020 Marvell International Ltd.\n+\n+# meson file, for building this example as part of a main DPDK build.\n+#\n+# To build this example as a standalone application with an already-installed\n+# DPDK instance, use 'make'\n+\n+deps += ['graph', 'eal', 'lpm', 'ethdev', 'node' ]\n+sources = files(\n+\t'main.c'\n+)\n+allow_experimental_apis = true\ndiff --git a/examples/meson.build b/examples/meson.build\nindex 1f2b6f516..3b540012f 100644\n--- a/examples/meson.build\n+++ b/examples/meson.build\n@@ -2,8 +2,10 @@\n # Copyright(c) 2017-2019 Intel Corporation\n \n driver_libs = []\n+node_libs = []\n if get_option('default_library') == 'static'\n \tdriver_libs = dpdk_drivers\n+\tnode_libs = dpdk_graph_nodes\n endif\n \n execinfo = cc.find_library('execinfo', required: false)\n@@ -23,7 +25,7 @@ all_examples = [\n \t'l2fwd', 'l2fwd-cat', 'l2fwd-event',\n \t'l2fwd-crypto', 'l2fwd-jobstats',\n \t'l2fwd-keepalive', 'l3fwd',\n-\t'l3fwd-acl', 'l3fwd-power',\n+\t'l3fwd-acl', 'l3fwd-power', 'l3fwd-graph',\n \t'link_status_interrupt',\n \t'multi_process/client_server_mp/mp_client',\n \t'multi_process/client_server_mp/mp_server',\n@@ -99,7 +101,7 @@ foreach example: examples\n \t\tendif\n \t\texecutable('dpdk-' + name, sources,\n \t\t\tinclude_directories: includes,\n-\t\t\tlink_whole: driver_libs,\n+\t\t\tlink_whole: driver_libs + node_libs,\n \t\t\tlink_args: dpdk_extra_ldflags,\n \t\t\tc_args: cflags,\n \t\t\tdependencies: dep_objs)\n",
    "prefixes": [
        "v4",
        "25/29"
    ]
}