get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 134866,
    "url": "https://patches.dpdk.org/api/patches/134866/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20231205092710.1375795-3-rkudurumalla@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": "<20231205092710.1375795-3-rkudurumalla@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231205092710.1375795-3-rkudurumalla@marvell.com",
    "date": "2023-12-05T09:27:10",
    "name": "[v4,3/3] app/graph: implement port forward usecase",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ff9ba29242cf6965f48a5b2ddf80b7dae8e7c241",
    "submitter": {
        "id": 2289,
        "url": "https://patches.dpdk.org/api/people/2289/?format=api",
        "name": "Rakesh Kudurumalla",
        "email": "rkudurumalla@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/20231205092710.1375795-3-rkudurumalla@marvell.com/mbox/",
    "series": [
        {
            "id": 30451,
            "url": "https://patches.dpdk.org/api/series/30451/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=30451",
            "date": "2023-12-05T09:27:08",
            "name": "[v4,1/3] node: support to add next node to ethdev Rx node",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/30451/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/134866/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/134866/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 2F5D543676;\n\tTue,  5 Dec 2023 10:27:32 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 23C9C42DFB;\n\tTue,  5 Dec 2023 10:27:25 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174])\n by mails.dpdk.org (Postfix) with ESMTP id A770942DF7\n for <dev@dpdk.org>; Tue,  5 Dec 2023 10:27:23 +0100 (CET)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 3B4NxDDW021825 for <dev@dpdk.org>; Tue, 5 Dec 2023 01:27:22 -0800",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3usrx3hfx1-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Tue, 05 Dec 2023 01:27:22 -0800",
            "from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Tue, 5 Dec 2023 01:27:20 -0800",
            "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.48 via Frontend\n Transport; Tue, 5 Dec 2023 01:27:21 -0800",
            "from localhost.localdomain (unknown [10.28.36.154])\n by maili.marvell.com (Postfix) with ESMTP id 9857C3F70A7;\n Tue,  5 Dec 2023 01:27:17 -0800 (PST)"
        ],
        "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=pfpt0220;\n bh=8r/8GlKCKC6l5rj6C3F69nW6gbYn0y4pVoDB9lqvf3A=;\n b=UdAxeg3yqXBUHcycrcO/KJyIZnpDo2vEaz+VGJCgoU1Il+fgd7IlfNgGOGdzDlfZ5A4k\n RByUc+5imW+0NVTPwHWQYSU42nZd32E8Sfqt7Yaz/3O3VI5NADVw7trjzPegqnQiF0MC\n XnPlY40ATHkPqCGkmmSbx86TbpKxRwbD1GpFRIMi6QhRBc5PGrWlE3hL+7GaTFgtKbDE\n W5ttX9VMhKS9dZim4HTXmzyHIMvGVfqnP7ma+Rnu6zKPjcGs8nbU4f8yGpn9SZ7HhA+x\n ZDyIjTMyVcDyiAko4Ubn4vg4q5jPEIORHNAQiskx2Bib4gr1/iOnnlUROV0f0BiyBifz nQ==",
        "From": "Rakesh Kudurumalla <rkudurumalla@marvell.com>",
        "To": "Sunil Kumar Kori <skori@marvell.com>, Rakesh Kudurumalla\n <rkudurumalla@marvell.com>",
        "CC": "<dev@dpdk.org>, <jerinj@marvell.com>, <ndabilpuram@marvell.com>",
        "Subject": "[PATCH v4 3/3] app/graph: implement port forward usecase",
        "Date": "Tue, 5 Dec 2023 14:57:10 +0530",
        "Message-ID": "<20231205092710.1375795-3-rkudurumalla@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20231205092710.1375795-1-rkudurumalla@marvell.com>",
        "References": "<20231205074645.1370608-1-rkudurumalla@marvell.com>\n <20231205092710.1375795-1-rkudurumalla@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-GUID": "CvTPLphHABomNz8vdlLDjk20K5GpFhM0",
        "X-Proofpoint-ORIG-GUID": "CvTPLphHABomNz8vdlLDjk20K5GpFhM0",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26\n definitions=2023-12-05_04,2023-12-04_01,2023-05-22_02",
        "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": "Added portforward usecase.In this usecase\npackets received Rx port is forwarded to\nrespective Tx port.\n\nSigned-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>\n---\n app/graph/ethdev.c                           |  12 ++\n app/graph/ethdev.h                           |   1 +\n app/graph/examples/l2fwd.cli                 |  41 +++++\n app/graph/examples/l2fwd_pcap.cli            |  37 +++++\n app/graph/graph.c                            |   8 +-\n app/graph/l2fwd.c                            | 148 +++++++++++++++++++\n app/graph/l2fwd.h                            |  11 ++\n app/graph/meson.build                        |   1 +\n app/graph/module_api.h                       |   1 +\n doc/guides/tools/graph.rst                   |  27 ++++\n doc/guides/tools/img/graph-usecase-l2fwd.svg |  84 +++++++++++\n 11 files changed, 370 insertions(+), 1 deletion(-)\n create mode 100644 app/graph/examples/l2fwd.cli\n create mode 100644 app/graph/examples/l2fwd_pcap.cli\n create mode 100644 app/graph/l2fwd.c\n create mode 100644 app/graph/l2fwd.h\n create mode 100644 doc/guides/tools/img/graph-usecase-l2fwd.svg",
    "diff": "diff --git a/app/graph/ethdev.c b/app/graph/ethdev.c\nindex bceee659a2..d048a65555 100644\n--- a/app/graph/ethdev.c\n+++ b/app/graph/ethdev.c\n@@ -77,6 +77,18 @@ ethdev_port_by_id(uint16_t port_id)\n \treturn NULL;\n }\n \n+int16_t\n+find_txport_by_rxport(uint16_t portid_rx)\n+{\n+\tint portid = -EINVAL;\n+\tstruct ethdev *port;\n+\tport = ethdev_port_by_id(portid_rx);\n+\tif (port)\n+\t\tportid = port->config.tx_port_id;\n+\n+\treturn portid;\n+}\n+\n void *\n ethdev_mempool_list_by_portid(uint16_t portid)\n {\ndiff --git a/app/graph/ethdev.h b/app/graph/ethdev.h\nindex 836052046b..946e14d801 100644\n--- a/app/graph/ethdev.h\n+++ b/app/graph/ethdev.h\n@@ -33,6 +33,7 @@ extern uint32_t enabled_port_mask;\n \n void ethdev_start(void);\n void ethdev_stop(void);\n+int16_t find_txport_by_rxport(uint16_t portid_rx);\n void *ethdev_mempool_list_by_portid(uint16_t portid);\n int16_t ethdev_portid_by_ip4(uint32_t ip, uint32_t mask);\n int16_t ethdev_portid_by_ip6(uint8_t *ip, uint8_t *mask);\ndiff --git a/app/graph/examples/l2fwd.cli b/app/graph/examples/l2fwd.cli\nnew file mode 100644\nindex 0000000000..af24a5836a\n--- /dev/null\n+++ b/app/graph/examples/l2fwd.cli\n@@ -0,0 +1,41 @@\n+; SPDX-License-Identifier: BSD-3-Clause\n+; Copyright(c) 2023 Marvell.\n+\n+;\n+; Graph configuration for given usecase\n+;\n+graph l2fwd coremask 0xff bsz 32 tmo 10 model default pcap_enable 1 num_pcap_pkts 100000 pcap_file /tmp/output.pcap\n+\n+;\n+; Mempools to be attached with ethdev\n+;\n+mempool mempool0 size 8192 buffers 4000 cache 256 numa 0\n+\n+;\n+; DPDK devices and configuration.\n+;\n+; Note: Customize the parameters below to match your setup.\n+;\n+ethdev 0002:01:00.1 rxq 1 txq 8 mempool0\n+ethdev 0002:01:00.4 rxq 1 txq 8 mempool0\n+ethdev 0002:01:00.6 rxq 1 txq 8 mempool0\n+ethdev 0002:02:00.0 rxq 1 txq 8 mempool0\n+\n+;\n+; L2 mac forwarding rules\n+;\n+ethdev forward 0002:01:00.4 0002:02:00.0\n+ethdev forward 0002:01:00.1 0002:01:00.6\n+\n+;\n+; Port-Queue-Core mapping for ethdev_rx node\n+;\n+ethdev_rx map port 0002:02:00.0 queue 0 core 1\n+ethdev_rx map port 0002:01:00.6 queue 0 core 2\n+\n+;\n+; Graph start command to create graph.\n+;\n+; Note: No more command should come after this.\n+;\n+graph start\ndiff --git a/app/graph/examples/l2fwd_pcap.cli b/app/graph/examples/l2fwd_pcap.cli\nnew file mode 100644\nindex 0000000000..718347f568\n--- /dev/null\n+++ b/app/graph/examples/l2fwd_pcap.cli\n@@ -0,0 +1,37 @@\n+; SPDX-License-Identifier: BSD-3-Clause\n+; Copyright(c) 2023 Marvell.\n+\n+;\n+; Graph configuration for given usecase\n+;\n+graph l2fwd coremask 0xff bsz 32 tmo 10 model default pcap_enable 1 num_pcap_pkts 100000 pcap_file /tmp/output.pcap\n+\n+;\n+; Mempools to be attached with ethdev\n+;\n+mempool mempool0 size 8192 buffers 4000 cache 256 numa 0\n+\n+;\n+; DPDK devices and configuration.\n+;\n+; Note: Customize the parameters below to match your setup.\n+;\n+ethdev net_pcap0 rxq 1 txq 8 mempool0\n+ethdev net_pcap1 rxq 1 txq 8 mempool0\n+\n+;\n+; L2 mac forwarding rules\n+;\n+ethdev forward net_pcap1 net_pcap0\n+\n+;\n+; Port-Queue-Core mapping for ethdev_rx node\n+;\n+ethdev_rx map port net_pcap0 queue 0 core 1\n+\n+;\n+; Graph start command to create graph.\n+;\n+; Note: No more command should come after this.\n+;\n+graph start\ndiff --git a/app/graph/graph.c b/app/graph/graph.c\nindex a65723a196..4e0441f1a7 100644\n--- a/app/graph/graph.c\n+++ b/app/graph/graph.c\n@@ -24,7 +24,7 @@ cmd_graph_help[] = \"graph <usecases> bsz <size> tmo <ns> coremask <bitmask> \"\n \t\t   \"model <rtc | mcd | default> pcap_enable <0 | 1> num_pcap_pkts <num>\"\n \t\t   \"pcap_file <output_capture_file>\";\n \n-static const char * const supported_usecases[] = {\"l3fwd\"};\n+static const char * const supported_usecases[] = {\"l3fwd\", \"l2fwd\"};\n struct graph_config graph_config;\n bool graph_started;\n \n@@ -273,6 +273,12 @@ cli_graph_start(__rte_unused void *parsed_result, __rte_unused struct cmdline *c\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n+\t\tif (!strcmp(graph_config.usecases[i].name, \"l2fwd\")) {\n+\t\t\tif (graph_config.usecases[i].enabled) {\n+\t\t\t\trc  = usecase_l2fwd_configure(conf, nb_conf, nb_graphs);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n \t}\n \n \tif (!rc)\ndiff --git a/app/graph/l2fwd.c b/app/graph/l2fwd.c\nnew file mode 100644\nindex 0000000000..a780caa394\n--- /dev/null\n+++ b/app/graph/l2fwd.c\n@@ -0,0 +1,148 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Marvell.\n+ */\n+\n+#include <errno.h>\n+#include <stdbool.h>\n+#include <stdint.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+\n+#include <rte_common.h>\n+#include <rte_ethdev.h>\n+#include <rte_graph.h>\n+#include <rte_graph_worker.h>\n+#include <rte_lcore.h>\n+#include <rte_node_eth_api.h>\n+\n+#include \"module_api.h\"\n+\n+static int\n+l2fwd_pattern_configure(void)\n+{\n+\tstruct rte_graph_param graph_conf;\n+\tconst char **node_patterns;\n+\tuint64_t pcap_pkts_count;\n+\tstruct lcore_conf *qconf;\n+\tuint16_t nb_patterns;\n+\tuint8_t pcap_ena;\n+\tchar *pcap_file;\n+\tint lcore_id;\n+\n+\tnb_patterns = 0;\n+\tnode_patterns = malloc((ETHDEV_RX_QUEUE_PER_LCORE_MAX + nb_patterns) *\n+\t\t\tsizeof(*node_patterns));\n+\tif (!node_patterns)\n+\t\treturn -ENOMEM;\n+\n+\tmemset(&graph_conf, 0, sizeof(graph_conf));\n+\tgraph_conf.node_patterns = node_patterns;\n+\n+\t/* Pcap config */\n+\tgraph_pcap_config_get(&pcap_ena, &pcap_pkts_count, &pcap_file);\n+\tgraph_conf.pcap_enable = pcap_ena;\n+\tgraph_conf.num_pkt_to_capture = pcap_pkts_count;\n+\tgraph_conf.pcap_filename = strdup(pcap_file);\n+\n+\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n+\t\trte_graph_t graph_id;\n+\t\trte_edge_t i;\n+\n+\t\tif (rte_lcore_is_enabled(lcore_id) == 0)\n+\t\t\tcontinue;\n+\n+\t\tqconf = &lcore_conf[lcore_id];\n+\n+\t\t/* Skip graph creation if no source exists */\n+\t\tif (!qconf->n_rx_queue)\n+\t\t\tcontinue;\n+\n+\t\t/* Add rx node patterns of this lcore */\n+\t\tfor (i = 0; i < qconf->n_rx_queue; i++) {\n+\t\t\tgraph_conf.node_patterns[nb_patterns + i] =\n+\t\t\t\tqconf->rx_queue_list[i].node_name;\n+\t\t}\n+\n+\t\tgraph_conf.nb_node_patterns = nb_patterns + i;\n+\t\tgraph_conf.socket_id = rte_lcore_to_socket_id(lcore_id);\n+\n+\t\tsnprintf(qconf->name, sizeof(qconf->name), \"worker_%u\",\n+\t\t\t\tlcore_id);\n+\n+\t\tgraph_id = rte_graph_create(qconf->name, &graph_conf);\n+\t\tif (graph_id == RTE_GRAPH_ID_INVALID)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"rte_graph_create(): graph_id invalid\"\n+\t\t\t\t\t\" for lcore %u\\n\", lcore_id);\n+\n+\t\tqconf->graph_id = graph_id;\n+\t\tqconf->graph = rte_graph_lookup(qconf->name);\n+\t\t/* >8 End of graph initialization. */\n+\t\tif (!qconf->graph)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\"rte_graph_lookup(): graph %s not found\\n\",\n+\t\t\t\t\tqconf->name);\n+\t}\n+\n+\t/* Launch per-lcore init on every worker lcore */\n+\trte_eal_mp_remote_launch(graph_walk_start, NULL, SKIP_MAIN);\n+\n+\t/* Accumulate and print stats on main until exit */\n+\tif (rte_graph_has_stats_feature() && app_graph_stats_enabled())\n+\t\tgraph_stats_print();\n+\n+\treturn 0;\n+}\n+\n+static int\n+ethdev_rx_to_tx_node_link(uint32_t lcore_id)\n+{\n+\tchar name[RTE_NODE_NAMESIZE];\n+\tconst char *next_node = name;\n+\tstruct lcore_conf *qconf;\n+\tuint16_t queue, port_id;\n+\trte_node_t rx_id;\n+\tint16_t txport;\n+\tint rc;\n+\n+\tqconf = &lcore_conf[lcore_id];\n+\n+\tfor (queue = 0; queue < qconf->n_rx_queue; ++queue) {\n+\t\tport_id = qconf->rx_queue_list[queue].port_id;\n+\t\ttxport = find_txport_by_rxport(port_id);\n+\t\tif (txport) {\n+\t\t\trx_id = rte_node_from_name(qconf->rx_queue_list[queue].node_name);\n+\t\t\tsnprintf(name, sizeof(name), \"ethdev_tx-%u\", txport);\n+\t\t\trte_node_edge_update(rx_id, RTE_EDGE_ID_INVALID, &next_node, 1);\n+\t\t\trc = rte_node_ethdev_rx_next_update(rx_id, name);\n+\t\t\tif (rc)\n+\t\t\t\treturn rc;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+\n+int\n+usecase_l2fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs)\n+{\n+\tuint32_t lcore_id;\n+\tint rc;\n+\n+\trc = rte_node_eth_config(conf, nb_confs, nb_graphs);\n+\tif (rc)\n+\t\trte_exit(EXIT_FAILURE, \"rte_node_eth_config: err=%d\\n\", rc);\n+\n+\tfor (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {\n+\t\trc = ethdev_rx_to_tx_node_link(lcore_id);\n+\t\tif (rc)\n+\t\t\trte_exit(EXIT_FAILURE, \"rte_node_eth_config: err=%d\\n\", rc);\n+\t}\n+\n+\trc = l2fwd_pattern_configure();\n+\tif (rc)\n+\t\trte_exit(EXIT_FAILURE, \"l2fwd_pattern_failure: err=%d\\n\", rc);\n+\n+\treturn rc;\n+}\ndiff --git a/app/graph/l2fwd.h b/app/graph/l2fwd.h\nnew file mode 100644\nindex 0000000000..3486ce52b2\n--- /dev/null\n+++ b/app/graph/l2fwd.h\n@@ -0,0 +1,11 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Marvell.\n+ */\n+\n+#ifndef APP_GRAPH_L2FWD_H\n+#define APP_GRAPH_L2FWD_H\n+\n+int usecase_l2fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_conf,\n+\t\t\t    uint16_t nb_graphs);\n+\n+#endif\ndiff --git a/app/graph/meson.build b/app/graph/meson.build\nindex 5b0f966d99..edd6b17ebc 100644\n--- a/app/graph/meson.build\n+++ b/app/graph/meson.build\n@@ -17,6 +17,7 @@ sources = files(\n         'graph.c',\n         'ip4_route.c',\n         'ip6_route.c',\n+        'l2fwd.c',\n         'l3fwd.c',\n         'main.c',\n         'mempool.c',\ndiff --git a/app/graph/module_api.h b/app/graph/module_api.h\nindex 7193e0b616..c80eeb704c 100644\n--- a/app/graph/module_api.h\n+++ b/app/graph/module_api.h\n@@ -13,6 +13,7 @@\n #include \"ethdev.h\"\n #include \"ethdev_rx.h\"\n #include \"graph.h\"\n+#include \"l2fwd.h\"\n #include \"l3fwd.h\"\n #include \"mempool.h\"\n #include \"neigh.h\"\ndiff --git a/doc/guides/tools/graph.rst b/doc/guides/tools/graph.rst\nindex 1855d12891..33b5e750b2 100644\n--- a/doc/guides/tools/graph.rst\n+++ b/doc/guides/tools/graph.rst\n@@ -77,6 +77,13 @@ This use case is supported for both H/W and PCAP vdev network devices.\n To demonstrate, corresponding ``.cli`` files are available at ``app/graph/examples/``\n named as ``l3fwd.cli`` and ``l3fwd_pcap.cli`` respectively.\n \n+l2fwd\n+~~~~~\n+\n+This use case is supported for both H/W and PCAP vdev network devices.\n+To demonstrate, corresponding ``.cli`` files are available at ``app/graph/examples/``\n+named as ``l2fwd.cli`` and ``l2fwd_pcap.cli`` respectively.\n+\n Example Commands\n ^^^^^^^^^^^^^^^^\n For H/W devices\n@@ -86,6 +93,9 @@ For H/W devices\n    ./dpdk-graph -c 0xff -a 0002:02:00.0 -a 0002:03:00.0 --\n                 -s <dpdk_root_dir>/app/graph/examples/l3fwd.cli\n \n+   ./dpdk-graph -c 0xff -a 0002:02:00.0 -a 0002:03:00.0 --\n+                -s <dpdk_root_dir>/app/graph/examples/l2fwd.cli\n+\n For net_pcapX devices\n \n .. code-block:: console\n@@ -94,6 +104,10 @@ For net_pcapX devices\n                         --vdev=net_pcap1,rx_pcap=in_net_pcap1.pcap,tx_pcap=out_net_pcap0.pcap\n                         -- -s <dpdk_root_dir>/app/graph/examples/l3fwd_pcap.cli\n \n+   ./dpdk-graph -c 0xff --vdev=net_pcap0,rx_pcap=in_net_pcap0.pcap,tx_pcap=out_net_pcap1.pcap\n+                        --vdev=net_pcap1,rx_pcap=in_net_pcap1.pcap,tx_pcap=out_net_pcap0.pcap\n+                        -- -s <dpdk_root_dir>/app/graph/examples/l2fwd_pcap.cli\n+\n Verifying traffic\n ^^^^^^^^^^^^^^^^^\n \n@@ -110,6 +124,12 @@ For current use case, following routing table is used:\n On the successful execution of ``l3fwd.cli`` or ``l3fwd_pcap.cli``,\n user needs to send traffic with mentioned DIP.\n \n+``l2fwd.cli`` and ``l2fwd_pcap.cli`` creates setup with two network ports.\n+Packet received on one port is forwarded to other port.\n+\n+On the successful execution of ``l2fwd.cli`` or ``l2fwd_pcap.cli``,\n+user needs to send traffic on RX port.\n+\n For net_pcapX devices, required pcap file should be created and passed to application.\n These pcap files can be created in several ways.\n Scapy is one of the method to get the same:\n@@ -321,3 +341,10 @@ l3fwd\n .. _figure_l3fwd_graph:\n \n .. figure:: img/graph-usecase-l3fwd.*\n+\n+l2fwd\n+~~~~~\n+\n+.. _figure_l2fwd_graph:\n+\n+.. figure:: img/graph-usecase-l2fwd.*\ndiff --git a/doc/guides/tools/img/graph-usecase-l2fwd.svg b/doc/guides/tools/img/graph-usecase-l2fwd.svg\nnew file mode 100644\nindex 0000000000..6b70af3380\n--- /dev/null\n+++ b/doc/guides/tools/img/graph-usecase-l2fwd.svg\n@@ -0,0 +1,84 @@\n+<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n+<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n+ \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n+<!-- Generated by graphviz version 2.43.0 (0)\n+ -->\n+<!-- SPDX-License-Identifier: BSD-3-Clause -->\n+<!-- Copyright(C) 2023 Marvell. -->\n+<!--\n+\n+Generated with following command\n+dot -Tsvg dot.dot -o doc/guides/tools/img/graph-usecase-l2fwd.svg\n+\n+cat dot.dot\n+digraph dpdk_app_graph_l2fwd_nodes_flow {\n+    ingress_port [shape=rect]\n+    ethdev_rx\n+    ethdev_tx\n+    pkt_drop\n+    egress_port  [shape=rect]\n+\n+    ingress_port -> ethdev_rx [label=\"ingress packet\"]\n+\n+    ethdev_rx -> ethdev_tx\n+    ethdev_rx -> pkt_drop [color=\"green\"]\n+}\n+\n+ -->\n+<!-- Title: dpdk_app_graph_l2fwd_nodes_flow Pages: 1 -->\n+<svg width=\"299pt\" height=\"204pt\"\n+ viewBox=\"0.00 0.00 299.40 204.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n+<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 200)\">\n+<title>dpdk_app_graph_l2fwd_nodes_flow</title>\n+<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-200 295.4,-200 295.4,4 -4,4\"/>\n+<!-- ingress_port -->\n+<g id=\"node1\" class=\"node\">\n+<title>ingress_port</title>\n+<polygon fill=\"none\" stroke=\"black\" points=\"171.9,-196 65.9,-196 65.9,-160 171.9,-160 171.9,-196\"/>\n+<text text-anchor=\"middle\" x=\"118.9\" y=\"-174.3\" font-family=\"Times,serif\" font-size=\"14.00\">ingress_port</text>\n+</g>\n+<!-- ethdev_rx -->\n+<g id=\"node2\" class=\"node\">\n+<title>ethdev_rx</title>\n+<ellipse fill=\"none\" stroke=\"black\" cx=\"118.9\" cy=\"-91\" rx=\"56.59\" ry=\"18\"/>\n+<text text-anchor=\"middle\" x=\"118.9\" y=\"-87.3\" font-family=\"Times,serif\" font-size=\"14.00\">ethdev_rx</text>\n+</g>\n+<!-- ingress_port&#45;&gt;ethdev_rx -->\n+<g id=\"edge1\" class=\"edge\">\n+<title>ingress_port&#45;&gt;ethdev_rx</title>\n+<path fill=\"none\" stroke=\"black\" d=\"M118.9,-159.8C118.9,-148.16 118.9,-132.55 118.9,-119.24\"/>\n+<polygon fill=\"black\" stroke=\"black\" points=\"122.4,-119.18 118.9,-109.18 115.4,-119.18 122.4,-119.18\"/>\n+<text text-anchor=\"middle\" x=\"171.4\" y=\"-130.8\" font-family=\"Times,serif\" font-size=\"14.00\">ingress packet</text>\n+</g>\n+<!-- ethdev_tx -->\n+<g id=\"node3\" class=\"node\">\n+<title>ethdev_tx</title>\n+<ellipse fill=\"none\" stroke=\"black\" cx=\"55.9\" cy=\"-18\" rx=\"55.79\" ry=\"18\"/>\n+<text text-anchor=\"middle\" x=\"55.9\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">ethdev_tx</text>\n+</g>\n+<!-- ethdev_rx&#45;&gt;ethdev_tx -->\n+<g id=\"edge2\" class=\"edge\">\n+<title>ethdev_rx&#45;&gt;ethdev_tx</title>\n+<path fill=\"none\" stroke=\"black\" d=\"M104.28,-73.53C96.37,-64.61 86.43,-53.41 77.62,-43.49\"/>\n+<polygon fill=\"black\" stroke=\"black\" points=\"80.12,-41.03 70.87,-35.87 74.88,-45.67 80.12,-41.03\"/>\n+</g>\n+<!-- pkt_drop -->\n+<g id=\"node4\" class=\"node\">\n+<title>pkt_drop</title>\n+<ellipse fill=\"none\" stroke=\"black\" cx=\"181.9\" cy=\"-18\" rx=\"51.99\" ry=\"18\"/>\n+<text text-anchor=\"middle\" x=\"181.9\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">pkt_drop</text>\n+</g>\n+<!-- ethdev_rx&#45;&gt;pkt_drop -->\n+<g id=\"edge3\" class=\"edge\">\n+<title>ethdev_rx&#45;&gt;pkt_drop</title>\n+<path fill=\"none\" stroke=\"green\" d=\"M133.51,-73.53C141.54,-64.48 151.65,-53.09 160.55,-43.06\"/>\n+<polygon fill=\"green\" stroke=\"green\" points=\"163.34,-45.18 167.36,-35.38 158.11,-40.53 163.34,-45.18\"/>\n+</g>\n+<!-- egress_port -->\n+<g id=\"node5\" class=\"node\">\n+<title>egress_port</title>\n+<polygon fill=\"none\" stroke=\"black\" points=\"291.4,-196 190.4,-196 190.4,-160 291.4,-160 291.4,-196\"/>\n+<text text-anchor=\"middle\" x=\"240.9\" y=\"-174.3\" font-family=\"Times,serif\" font-size=\"14.00\">egress_port</text>\n+</g>\n+</g>\n+</svg>\n",
    "prefixes": [
        "v4",
        "3/3"
    ]
}