get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 128423,
    "url": "https://patches.dpdk.org/api/patches/128423/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20230608133144.567391-1-mkp@redhat.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": "<20230608133144.567391-1-mkp@redhat.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230608133144.567391-1-mkp@redhat.com",
    "date": "2023-06-08T13:31:44",
    "name": "[v7] app/testpmd: expand noisy neighbour forward mode support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "7880fdeff325d7f0f4272221d2f0fea6aad53a4e",
    "submitter": {
        "id": 2561,
        "url": "https://patches.dpdk.org/api/people/2561/?format=api",
        "name": "Mike Pattrick",
        "email": "mkp@redhat.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20230608133144.567391-1-mkp@redhat.com/mbox/",
    "series": [
        {
            "id": 28420,
            "url": "https://patches.dpdk.org/api/series/28420/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=28420",
            "date": "2023-06-08T13:31:44",
            "name": "[v7] app/testpmd: expand noisy neighbour forward mode support",
            "version": 7,
            "mbox": "https://patches.dpdk.org/series/28420/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/128423/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/128423/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 15E2842C5E;\n\tThu,  8 Jun 2023 15:31:58 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 93B4240A84;\n\tThu,  8 Jun 2023 15:31:57 +0200 (CEST)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by mails.dpdk.org (Postfix) with ESMTP id 0310440042\n for <dev@dpdk.org>; Thu,  8 Jun 2023 15:31:55 +0200 (CEST)",
            "from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com\n [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n us-mta-630-wP4Ro35FNFO8--6b2eKzBA-1; Thu, 08 Jun 2023 09:31:54 -0400",
            "from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com\n [10.11.54.5])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6A93F8007D9;\n Thu,  8 Jun 2023 13:31:53 +0000 (UTC)",
            "from mpattric.remote.csb (unknown [10.22.8.151])\n by smtp.corp.redhat.com (Postfix) with ESMTP id DABF39E90;\n Thu,  8 Jun 2023 13:31:52 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1686231115;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=KcPHC9AU+7F1mwdvBZxAbBPBmI0nDMJAVEqwHU26FCI=;\n b=EzEVT4Mud85KjL8IaRz1W9GlQSnHmsCYQ/G6oQ6YZBe9cRUkASSuDpe0kjwYiTrA2E/B8z\n RRMg9HmM4FJPE4kizUnTZ03UeSs0Tw31HnSyxi+hI/3KOpXgwbhKahKaEUwvxqvUNfokc5\n cOZ5nkB3oonADPrFeceornf5IkC0CVk=",
        "X-MC-Unique": "wP4Ro35FNFO8--6b2eKzBA-1",
        "From": "Mike Pattrick <mkp@redhat.com>",
        "To": "Aman Singh <aman.deep.singh@intel.com>,\n Yuying Zhang <yuying.zhang@intel.com>",
        "Cc": "ktraynor@redhat.com,\n\tdev@dpdk.org,\n\tMike Pattrick <mkp@redhat.com>",
        "Subject": "[PATCH v7] app/testpmd: expand noisy neighbour forward mode support",
        "Date": "Thu,  8 Jun 2023 09:31:44 -0400",
        "Message-Id": "<20230608133144.567391-1-mkp@redhat.com>",
        "In-Reply-To": "<20230608095907.557698-1-mkp@redhat.com>",
        "References": "<20230608095907.557698-1-mkp@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.1 on 10.11.54.5",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "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 noisy neighbour vnf simulation would only operate in io\nmode, forwarding packets as is. However, this limited the usefulness of\nnoisy neighbour simulation.\n\nThis feature has now been expanded to supporting mac, macswap, and\n5tswap modes. To facilitate adding this support, some new header files\nwere added.\n\nSigned-off-by: Mike Pattrick <mkp@redhat.com>\n ---\n v2: Reverted changes to random memory lookup\n v3: Refactored entire patch\n v4: Implemented recommended formatting changes\n v5: Corrected copyright statement and formatting changes\n v6: Reordered some variables, preserved noisy subtype for display\n v7: Made fwd engine status generic across all modules\n---\n app/test-pmd/5tswap.c                 | 118 +----------------------\n app/test-pmd/5tswap.h                 | 130 ++++++++++++++++++++++++++\n app/test-pmd/config.c                 |  18 +++-\n app/test-pmd/macfwd.c                 |  33 +------\n app/test-pmd/macfwd.h                 |  45 +++++++++\n app/test-pmd/noisy_vnf.c              | 113 ++++++++++++++++++----\n app/test-pmd/parameters.c             |  15 +++\n app/test-pmd/testpmd.c                |  14 +++\n app/test-pmd/testpmd.h                |  11 +++\n doc/guides/testpmd_app_ug/run_app.rst |   9 ++\n 10 files changed, 342 insertions(+), 164 deletions(-)\n create mode 100644 app/test-pmd/5tswap.h\n create mode 100644 app/test-pmd/macfwd.h",
    "diff": "diff --git a/app/test-pmd/5tswap.c b/app/test-pmd/5tswap.c\nindex ff8c2dcde5..8e8de2557a 100644\n--- a/app/test-pmd/5tswap.c\n+++ b/app/test-pmd/5tswap.c\n@@ -17,64 +17,8 @@\n #include <rte_ip.h>\n #include <rte_flow.h>\n \n-#include \"macswap_common.h\"\n #include \"testpmd.h\"\n-\n-\n-static inline void\n-swap_mac(struct rte_ether_hdr *eth_hdr)\n-{\n-\tstruct rte_ether_addr addr;\n-\n-\t/* Swap dest and src mac addresses. */\n-\trte_ether_addr_copy(&eth_hdr->dst_addr, &addr);\n-\trte_ether_addr_copy(&eth_hdr->src_addr, &eth_hdr->dst_addr);\n-\trte_ether_addr_copy(&addr, &eth_hdr->src_addr);\n-}\n-\n-static inline void\n-swap_ipv4(struct rte_ipv4_hdr *ipv4_hdr)\n-{\n-\trte_be32_t addr;\n-\n-\t/* Swap dest and src ipv4 addresses. */\n-\taddr = ipv4_hdr->src_addr;\n-\tipv4_hdr->src_addr = ipv4_hdr->dst_addr;\n-\tipv4_hdr->dst_addr = addr;\n-}\n-\n-static inline void\n-swap_ipv6(struct rte_ipv6_hdr *ipv6_hdr)\n-{\n-\tuint8_t addr[16];\n-\n-\t/* Swap dest and src ipv6 addresses. */\n-\tmemcpy(&addr, &ipv6_hdr->src_addr, 16);\n-\tmemcpy(&ipv6_hdr->src_addr, &ipv6_hdr->dst_addr, 16);\n-\tmemcpy(&ipv6_hdr->dst_addr, &addr, 16);\n-}\n-\n-static inline void\n-swap_tcp(struct rte_tcp_hdr *tcp_hdr)\n-{\n-\trte_be16_t port;\n-\n-\t/* Swap dest and src tcp port. */\n-\tport = tcp_hdr->src_port;\n-\ttcp_hdr->src_port = tcp_hdr->dst_port;\n-\ttcp_hdr->dst_port = port;\n-}\n-\n-static inline void\n-swap_udp(struct rte_udp_hdr *udp_hdr)\n-{\n-\trte_be16_t port;\n-\n-\t/* Swap dest and src udp port */\n-\tport = udp_hdr->src_port;\n-\tudp_hdr->src_port = udp_hdr->dst_port;\n-\tudp_hdr->dst_port = port;\n-}\n+#include \"5tswap.h\"\n \n /*\n  * 5 tuple swap forwarding mode: Swap the source and the destination of layers\n@@ -85,22 +29,7 @@ static bool\n pkt_burst_5tuple_swap(struct fwd_stream *fs)\n {\n \tstruct rte_mbuf  *pkts_burst[MAX_PKT_BURST];\n-\tstruct rte_port  *txp;\n-\tstruct rte_mbuf *mb;\n-\tuint16_t next_proto;\n-\tuint64_t ol_flags;\n-\tuint16_t proto;\n \tuint16_t nb_rx;\n-\tint i;\n-\tunion {\n-\t\tstruct rte_ether_hdr *eth;\n-\t\tstruct rte_vlan_hdr *vlan;\n-\t\tstruct rte_ipv4_hdr *ipv4;\n-\t\tstruct rte_ipv6_hdr *ipv6;\n-\t\tstruct rte_tcp_hdr *tcp;\n-\t\tstruct rte_udp_hdr *udp;\n-\t\tuint8_t *byte;\n-\t} h;\n \n \t/*\n \t * Receive a burst of packets and forward them.\n@@ -109,49 +38,8 @@ pkt_burst_5tuple_swap(struct fwd_stream *fs)\n \tif (unlikely(nb_rx == 0))\n \t\treturn false;\n \n-\ttxp = &ports[fs->tx_port];\n-\tol_flags = ol_flags_init(txp->dev_conf.txmode.offloads);\n-\tvlan_qinq_set(pkts_burst, nb_rx, ol_flags,\n-\t\t\ttxp->tx_vlan_id, txp->tx_vlan_id_outer);\n-\tfor (i = 0; i < nb_rx; i++) {\n-\t\tif (likely(i < nb_rx - 1))\n-\t\t\trte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1],\n-\t\t\t\t\tvoid *));\n-\t\tmb = pkts_burst[i];\n-\t\th.eth = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);\n-\t\tproto = h.eth->ether_type;\n-\t\tswap_mac(h.eth);\n-\t\tmb->l2_len = sizeof(struct rte_ether_hdr);\n-\t\th.eth++;\n-\t\twhile (proto == RTE_BE16(RTE_ETHER_TYPE_VLAN) ||\n-\t\t       proto == RTE_BE16(RTE_ETHER_TYPE_QINQ)) {\n-\t\t\tproto = h.vlan->eth_proto;\n-\t\t\th.vlan++;\n-\t\t\tmb->l2_len += sizeof(struct rte_vlan_hdr);\n-\t\t}\n-\t\tif (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {\n-\t\t\tswap_ipv4(h.ipv4);\n-\t\t\tnext_proto = h.ipv4->next_proto_id;\n-\t\t\tmb->l3_len = rte_ipv4_hdr_len(h.ipv4);\n-\t\t\th.byte += mb->l3_len;\n-\t\t} else if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {\n-\t\t\tswap_ipv6(h.ipv6);\n-\t\t\tnext_proto = h.ipv6->proto;\n-\t\t\th.ipv6++;\n-\t\t\tmb->l3_len = sizeof(struct rte_ipv6_hdr);\n-\t\t} else {\n-\t\t\tmbuf_field_set(mb, ol_flags);\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (next_proto == IPPROTO_UDP) {\n-\t\t\tswap_udp(h.udp);\n-\t\t\tmb->l4_len = sizeof(struct rte_udp_hdr);\n-\t\t} else if (next_proto == IPPROTO_TCP) {\n-\t\t\tswap_tcp(h.tcp);\n-\t\t\tmb->l4_len = (h.tcp->data_off & 0xf0) >> 2;\n-\t\t}\n-\t\tmbuf_field_set(mb, ol_flags);\n-\t}\n+\tdo_5tswap(pkts_burst, nb_rx, fs);\n+\n \tcommon_fwd_stream_transmit(fs, pkts_burst, nb_rx);\n \n \treturn true;\ndiff --git a/app/test-pmd/5tswap.h b/app/test-pmd/5tswap.h\nnew file mode 100644\nindex 0000000000..345c08b4d0\n--- /dev/null\n+++ b/app/test-pmd/5tswap.h\n@@ -0,0 +1,130 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2014-2020 Mellanox Technologies, Ltd\n+ */\n+\n+#ifndef _5TSWAP_H_\n+#define _5TSWAP_H_\n+\n+#include \"macswap_common.h\"\n+\n+static inline void\n+swap_mac(struct rte_ether_hdr *eth_hdr)\n+{\n+\tstruct rte_ether_addr addr;\n+\n+\t/* Swap dest and src mac addresses. */\n+\trte_ether_addr_copy(&eth_hdr->dst_addr, &addr);\n+\trte_ether_addr_copy(&eth_hdr->src_addr, &eth_hdr->dst_addr);\n+\trte_ether_addr_copy(&addr, &eth_hdr->src_addr);\n+}\n+\n+static inline void\n+swap_ipv4(struct rte_ipv4_hdr *ipv4_hdr)\n+{\n+\trte_be32_t addr;\n+\n+\t/* Swap dest and src ipv4 addresses. */\n+\taddr = ipv4_hdr->src_addr;\n+\tipv4_hdr->src_addr = ipv4_hdr->dst_addr;\n+\tipv4_hdr->dst_addr = addr;\n+}\n+\n+static inline void\n+swap_ipv6(struct rte_ipv6_hdr *ipv6_hdr)\n+{\n+\tuint8_t addr[16];\n+\n+\t/* Swap dest and src ipv6 addresses. */\n+\tmemcpy(&addr, &ipv6_hdr->src_addr, 16);\n+\tmemcpy(&ipv6_hdr->src_addr, &ipv6_hdr->dst_addr, 16);\n+\tmemcpy(&ipv6_hdr->dst_addr, &addr, 16);\n+}\n+\n+static inline void\n+swap_tcp(struct rte_tcp_hdr *tcp_hdr)\n+{\n+\trte_be16_t port;\n+\n+\t/* Swap dest and src tcp port. */\n+\tport = tcp_hdr->src_port;\n+\ttcp_hdr->src_port = tcp_hdr->dst_port;\n+\ttcp_hdr->dst_port = port;\n+}\n+\n+static inline void\n+swap_udp(struct rte_udp_hdr *udp_hdr)\n+{\n+\trte_be16_t port;\n+\n+\t/* Swap dest and src udp port */\n+\tport = udp_hdr->src_port;\n+\tudp_hdr->src_port = udp_hdr->dst_port;\n+\tudp_hdr->dst_port = port;\n+}\n+\n+static inline void\n+do_5tswap(struct rte_mbuf *pkts_burst[], uint16_t nb_rx,\n+\t  struct fwd_stream *fs)\n+{\n+\tstruct rte_port  *txp;\n+\tstruct rte_mbuf *mb;\n+\tuint16_t next_proto;\n+\tuint64_t ol_flags;\n+\tuint16_t proto;\n+\tint i;\n+\tunion {\n+\t\tstruct rte_ether_hdr *eth;\n+\t\tstruct rte_vlan_hdr *vlan;\n+\t\tstruct rte_ipv4_hdr *ipv4;\n+\t\tstruct rte_ipv6_hdr *ipv6;\n+\t\tstruct rte_tcp_hdr *tcp;\n+\t\tstruct rte_udp_hdr *udp;\n+\t\tuint8_t *byte;\n+\t} h;\n+\n+\ttxp = &ports[fs->tx_port];\n+\tol_flags = ol_flags_init(txp->dev_conf.txmode.offloads);\n+\tvlan_qinq_set(pkts_burst, nb_rx, ol_flags,\n+\t\t      txp->tx_vlan_id, txp->tx_vlan_id_outer);\n+\tfor (i = 0; i < nb_rx; i++) {\n+\t\tif (likely(i < nb_rx - 1))\n+\t\t\trte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1],\n+\t\t\t\t\t\t       void *));\n+\t\tmb = pkts_burst[i];\n+\t\th.eth = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);\n+\t\tproto = h.eth->ether_type;\n+\t\tswap_mac(h.eth);\n+\t\tmb->l2_len = sizeof(struct rte_ether_hdr);\n+\t\th.eth++;\n+\t\twhile (proto == RTE_BE16(RTE_ETHER_TYPE_VLAN) ||\n+\t\t       proto == RTE_BE16(RTE_ETHER_TYPE_QINQ)) {\n+\t\t\tproto = h.vlan->eth_proto;\n+\t\t\th.vlan++;\n+\t\t\tmb->l2_len += sizeof(struct rte_vlan_hdr);\n+\t\t}\n+\t\tif (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {\n+\t\t\tswap_ipv4(h.ipv4);\n+\t\t\tnext_proto = h.ipv4->next_proto_id;\n+\t\t\tmb->l3_len = rte_ipv4_hdr_len(h.ipv4);\n+\t\t\th.byte += mb->l3_len;\n+\t\t} else if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {\n+\t\t\tswap_ipv6(h.ipv6);\n+\t\t\tnext_proto = h.ipv6->proto;\n+\t\t\th.ipv6++;\n+\t\t\tmb->l3_len = sizeof(struct rte_ipv6_hdr);\n+\t\t} else {\n+\t\t\tmbuf_field_set(mb, ol_flags);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (next_proto == IPPROTO_UDP) {\n+\t\t\tswap_udp(h.udp);\n+\t\t\tmb->l4_len = sizeof(struct rte_udp_hdr);\n+\t\t} else if (next_proto == IPPROTO_TCP) {\n+\t\t\tswap_tcp(h.tcp);\n+\t\t\tmb->l4_len = (h.tcp->data_off & 0xf0) >> 2;\n+\t\t}\n+\t\tmbuf_field_set(mb, ol_flags);\n+\t}\n+}\n+\n+#endif /* _5TSWAP_H_ */\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 096c218c12..d55212bbad 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -4052,9 +4052,16 @@ rxtx_config_display(void)\n {\n \tportid_t pid;\n \tqueueid_t qid;\n+\tchar buf[32];\n+\n+\tif (cur_fwd_eng->status)\n+\t\tsnprintf(buf, sizeof(buf), \" (%s)\", cur_fwd_eng->status);\n+\telse\n+\t\tbuf[0] = '\\0';\n \n-\tprintf(\"  %s packet forwarding%s packets/burst=%d\\n\",\n+\tprintf(\"  %s%s packet forwarding%s packets/burst=%d\\n\",\n \t       cur_fwd_eng->fwd_mode_name,\n+\t       buf,\n \t       retry_enabled == 0 ? \"\" : \" with retry\",\n \t       nb_pkt_per_burst);\n \n@@ -4816,10 +4823,17 @@ pkt_fwd_config_display(struct fwd_config *cfg)\n \tstruct fwd_stream *fs;\n \tlcoreid_t  lc_id;\n \tstreamid_t sm_id;\n+\tchar buf[32];\n+\n+\tif (cfg->fwd_eng->status)\n+\t\tsnprintf(buf, sizeof(buf), \" (%s)\", cfg->fwd_eng->status);\n+\telse\n+\t\tbuf[0] = '\\0';\n \n-\tprintf(\"%s packet forwarding%s - ports=%d - cores=%d - streams=%d - \"\n+\tprintf(\"%s%s packet forwarding%s - ports=%d - cores=%d - streams=%d - \"\n \t\t\"NUMA support %s, MP allocation mode: %s\\n\",\n \t\tcfg->fwd_eng->fwd_mode_name,\n+\t\tbuf,\n \t\tretry_enabled == 0 ? \"\" : \" with retry\",\n \t\tcfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams,\n \t\tnuma_support == 1 ? \"enabled\" : \"disabled\",\ndiff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c\nindex 7316d73315..d19ace7395 100644\n--- a/app/test-pmd/macfwd.c\n+++ b/app/test-pmd/macfwd.c\n@@ -35,6 +35,7 @@\n #include <rte_flow.h>\n \n #include \"testpmd.h\"\n+#include \"macfwd.h\"\n \n /*\n  * Forwarding of packets in MAC mode.\n@@ -45,13 +46,7 @@ static bool\n pkt_burst_mac_forward(struct fwd_stream *fs)\n {\n \tstruct rte_mbuf  *pkts_burst[MAX_PKT_BURST];\n-\tstruct rte_port  *txp;\n-\tstruct rte_mbuf  *mb;\n-\tstruct rte_ether_hdr *eth_hdr;\n \tuint16_t nb_rx;\n-\tuint16_t i;\n-\tuint64_t ol_flags = 0;\n-\tuint64_t tx_offloads;\n \n \t/*\n \t * Receive a burst of packets and forward them.\n@@ -60,31 +55,7 @@ pkt_burst_mac_forward(struct fwd_stream *fs)\n \tif (unlikely(nb_rx == 0))\n \t\treturn false;\n \n-\ttxp = &ports[fs->tx_port];\n-\ttx_offloads = txp->dev_conf.txmode.offloads;\n-\tif (tx_offloads\t& RTE_ETH_TX_OFFLOAD_VLAN_INSERT)\n-\t\tol_flags = RTE_MBUF_F_TX_VLAN;\n-\tif (tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT)\n-\t\tol_flags |= RTE_MBUF_F_TX_QINQ;\n-\tif (tx_offloads & RTE_ETH_TX_OFFLOAD_MACSEC_INSERT)\n-\t\tol_flags |= RTE_MBUF_F_TX_MACSEC;\n-\tfor (i = 0; i < nb_rx; i++) {\n-\t\tif (likely(i < nb_rx - 1))\n-\t\t\trte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],\n-\t\t\t\t\t\t       void *));\n-\t\tmb = pkts_burst[i];\n-\t\teth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);\n-\t\trte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr],\n-\t\t\t\t&eth_hdr->dst_addr);\n-\t\trte_ether_addr_copy(&ports[fs->tx_port].eth_addr,\n-\t\t\t\t&eth_hdr->src_addr);\n-\t\tmb->ol_flags &= RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERNAL;\n-\t\tmb->ol_flags |= ol_flags;\n-\t\tmb->l2_len = sizeof(struct rte_ether_hdr);\n-\t\tmb->l3_len = sizeof(struct rte_ipv4_hdr);\n-\t\tmb->vlan_tci = txp->tx_vlan_id;\n-\t\tmb->vlan_tci_outer = txp->tx_vlan_id_outer;\n-\t}\n+\tdo_macfwd(pkts_burst, nb_rx, fs);\n \n \tcommon_fwd_stream_transmit(fs, pkts_burst, nb_rx);\n \ndiff --git a/app/test-pmd/macfwd.h b/app/test-pmd/macfwd.h\nnew file mode 100644\nindex 0000000000..ae2346e589\n--- /dev/null\n+++ b/app/test-pmd/macfwd.h\n@@ -0,0 +1,45 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2010-2014 Intel Corporation\n+ */\n+\n+#ifndef _MACFWD_H_\n+#define _MACFWD_H_\n+\n+static inline void\n+do_macfwd(struct rte_mbuf *pkts_burst[], uint16_t nb_rx,\n+\t  struct fwd_stream *fs)\n+{\n+\tstruct rte_ether_hdr *eth_hdr;\n+\tuint64_t ol_flags = 0;\n+\tuint64_t tx_offloads;\n+\tstruct rte_mbuf  *mb;\n+\tstruct rte_port *txp = &ports[fs->tx_port];\n+\tuint16_t i;\n+\n+\ttx_offloads = txp->dev_conf.txmode.offloads;\n+\tif (tx_offloads\t& RTE_ETH_TX_OFFLOAD_VLAN_INSERT)\n+\t\tol_flags = RTE_MBUF_F_TX_VLAN;\n+\tif (tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT)\n+\t\tol_flags |= RTE_MBUF_F_TX_QINQ;\n+\tif (tx_offloads & RTE_ETH_TX_OFFLOAD_MACSEC_INSERT)\n+\t\tol_flags |= RTE_MBUF_F_TX_MACSEC;\n+\tfor (i = 0; i < nb_rx; i++) {\n+\t\tif (likely(i < nb_rx - 1))\n+\t\t\trte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],\n+\t\t\t\t\t\t       void *));\n+\t\tmb = pkts_burst[i];\n+\t\teth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);\n+\t\trte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr],\n+\t\t\t\t    &eth_hdr->dst_addr);\n+\t\trte_ether_addr_copy(&ports[fs->tx_port].eth_addr,\n+\t\t\t\t    &eth_hdr->src_addr);\n+\t\tmb->ol_flags &= RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERNAL;\n+\t\tmb->ol_flags |= ol_flags;\n+\t\tmb->l2_len = sizeof(struct rte_ether_hdr);\n+\t\tmb->l3_len = sizeof(struct rte_ipv4_hdr);\n+\t\tmb->vlan_tci = txp->tx_vlan_id;\n+\t\tmb->vlan_tci_outer = txp->tx_vlan_id_outer;\n+\t}\n+}\n+\n+#endif /* _MACFWD_H_ */\ndiff --git a/app/test-pmd/noisy_vnf.c b/app/test-pmd/noisy_vnf.c\nindex 2bf90a983c..81d1187cfe 100644\n--- a/app/test-pmd/noisy_vnf.c\n+++ b/app/test-pmd/noisy_vnf.c\n@@ -32,6 +32,18 @@\n #include <rte_malloc.h>\n \n #include \"testpmd.h\"\n+#include \"5tswap.h\"\n+#include \"macfwd.h\"\n+#if defined(RTE_ARCH_X86)\n+#include \"macswap_sse.h\"\n+#elif defined(__ARM_NEON)\n+#include \"macswap_neon.h\"\n+#else\n+#include \"macswap.h\"\n+#endif\n+\n+#define NOISY_STRSIZE 256\n+#define NOISY_RING \"noisy_ring_%d\\n\"\n \n struct noisy_config {\n \tstruct rte_ring *f;\n@@ -80,9 +92,6 @@ sim_memory_lookups(struct noisy_config *ncf, uint16_t nb_pkts)\n {\n \tuint16_t i, j;\n \n-\tif (!ncf->do_sim)\n-\t\treturn;\n-\n \tfor (i = 0; i < nb_pkts; i++) {\n \t\tfor (j = 0; j < noisy_lkup_num_writes; j++)\n \t\t\tdo_write(ncf->vnf_mem);\n@@ -110,15 +119,13 @@ sim_memory_lookups(struct noisy_config *ncf, uint16_t nb_pkts)\n  *    out of the FIFO\n  * 4. Cases 2 and 3 combined\n  */\n-static bool\n-pkt_burst_noisy_vnf(struct fwd_stream *fs)\n+static uint16_t\n+noisy_eth_tx_burst(struct fwd_stream *fs, uint16_t nb_rx, struct rte_mbuf **pkts_burst)\n {\n \tconst uint64_t freq_khz = rte_get_timer_hz() / 1000;\n \tstruct noisy_config *ncf = noisy_cfg[fs->rx_port];\n-\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n \tstruct rte_mbuf *tmp_pkts[MAX_PKT_BURST];\n \tuint16_t nb_deqd = 0;\n-\tuint16_t nb_rx = 0;\n \tuint16_t nb_tx = 0;\n \tuint16_t nb_enqd;\n \tunsigned int fifo_free;\n@@ -126,12 +133,16 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs)\n \tbool needs_flush = false;\n \tuint64_t now;\n \n-\tnb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);\n-\tif (unlikely(nb_rx == 0))\n-\t\tgoto flush;\n+\tif (unlikely(nb_rx == 0)) {\n+\t\tif (!ncf->do_buffering)\n+\t\t\tgoto end;\n+\t\telse\n+\t\t\tgoto flush;\n+\t}\n \n \tif (!ncf->do_buffering) {\n-\t\tsim_memory_lookups(ncf, nb_rx);\n+\t\tif (ncf->do_sim)\n+\t\t\tsim_memory_lookups(ncf, nb_rx);\n \t\tnb_tx = common_fwd_stream_transmit(fs, pkts_burst, nb_rx);\n \t\tgoto end;\n \t}\n@@ -150,7 +161,8 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs)\n \t\t\tnb_tx = common_fwd_stream_transmit(fs, tmp_pkts, nb_deqd);\n \t}\n \n-\tsim_memory_lookups(ncf, nb_enqd);\n+\tif (ncf->do_sim)\n+\t\tsim_memory_lookups(ncf, nb_enqd);\n \n flush:\n \tif (ncf->do_flush) {\n@@ -169,11 +181,66 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs)\n \t\tncf->prev_time = rte_get_timer_cycles();\n \t}\n end:\n+\treturn nb_tx;\n+}\n+\n+static bool\n+pkt_burst_io(struct fwd_stream *fs)\n+{\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tuint16_t nb_rx;\n+\tuint16_t nb_tx;\n+\n+\tnb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);\n+\tnb_tx = noisy_eth_tx_burst(fs, nb_rx, pkts_burst);\n+\n \treturn nb_rx > 0 || nb_tx > 0;\n }\n \n-#define NOISY_STRSIZE 256\n-#define NOISY_RING \"noisy_ring_%d\\n\"\n+static bool\n+pkt_burst_mac(struct fwd_stream *fs)\n+{\n+\tstruct rte_mbuf  *pkts_burst[MAX_PKT_BURST];\n+\tuint16_t nb_rx;\n+\tuint16_t nb_tx;\n+\n+\tnb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);\n+\tif (likely(nb_rx != 0))\n+\t\tdo_macfwd(pkts_burst, nb_rx, fs);\n+\tnb_tx = noisy_eth_tx_burst(fs, nb_rx, pkts_burst);\n+\n+\treturn nb_rx > 0 || nb_tx > 0;\n+}\n+\n+static bool\n+pkt_burst_macswap(struct fwd_stream *fs)\n+{\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tuint16_t nb_rx;\n+\tuint16_t nb_tx;\n+\n+\tnb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);\n+\tif (likely(nb_rx != 0))\n+\t\tdo_macswap(pkts_burst, nb_rx, &ports[fs->tx_port]);\n+\tnb_tx = noisy_eth_tx_burst(fs, nb_rx, pkts_burst);\n+\n+\treturn nb_rx > 0 || nb_tx > 0;\n+}\n+\n+static bool\n+pkt_burst_5tswap(struct fwd_stream *fs)\n+{\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tuint16_t nb_rx;\n+\tuint16_t nb_tx;\n+\n+\tnb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);\n+\tif (likely(nb_rx != 0))\n+\t\tdo_5tswap(pkts_burst, nb_rx, fs);\n+\tnb_tx = noisy_eth_tx_burst(fs, nb_rx, pkts_burst);\n+\n+\treturn nb_rx > 0 || nb_tx > 0;\n+}\n \n static void\n noisy_fwd_end(portid_t pi)\n@@ -226,6 +293,20 @@ noisy_fwd_begin(portid_t pi)\n \t\t\t \"--noisy-lkup-memory-size must be > 0\\n\");\n \t}\n \n+\tif (noisy_fwd_mode == NOISY_FWD_MODE_IO)\n+\t\tnoisy_vnf_engine.packet_fwd = pkt_burst_io;\n+\telse if (noisy_fwd_mode == NOISY_FWD_MODE_MAC)\n+\t\tnoisy_vnf_engine.packet_fwd = pkt_burst_mac;\n+\telse if (noisy_fwd_mode == NOISY_FWD_MODE_MACSWAP)\n+\t\tnoisy_vnf_engine.packet_fwd = pkt_burst_macswap;\n+\telse if (noisy_fwd_mode == NOISY_FWD_MODE_5TSWAP)\n+\t\tnoisy_vnf_engine.packet_fwd = pkt_burst_5tswap;\n+\telse\n+\t\trte_exit(EXIT_FAILURE,\n+\t\t\t \" Invalid noisy_fwd_mode specified\\n\");\n+\n+\tnoisy_vnf_engine.status = noisy_fwd_mode_desc[noisy_fwd_mode];\n+\n \treturn 0;\n }\n \n@@ -233,6 +314,6 @@ struct fwd_engine noisy_vnf_engine = {\n \t.fwd_mode_name  = \"noisy\",\n \t.port_fwd_begin = noisy_fwd_begin,\n \t.port_fwd_end   = noisy_fwd_end,\n-\t.stream_init    = common_fwd_stream_init,\n-\t.packet_fwd     = pkt_burst_noisy_vnf,\n+\t.stream_init\t= common_fwd_stream_init,\n+\t.packet_fwd     = pkt_burst_io,\n };\ndiff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c\nindex 3b37809baf..b676f2c6ae 100644\n--- a/app/test-pmd/parameters.c\n+++ b/app/test-pmd/parameters.c\n@@ -190,6 +190,7 @@ usage(char* progname)\n \t       \"    anon: use regular DPDK memory to create and anonymous memory to populate mempool\\n\"\n \t       \"    xmem: use anonymous memory to create and populate mempool\\n\"\n \t       \"    xmemhuge: use anonymous hugepage memory to create and populate mempool\\n\");\n+\tprintf(\"  --noisy-forward-mode=<io|mac|macswap|5tswap>: set the sub-fwd mode, defaults to io\\n\");\n \tprintf(\"  --noisy-tx-sw-buffer-size=N: size of FIFO buffer\\n\");\n \tprintf(\"  --noisy-tx-sw-buffer-flushtime=N: flush FIFO after N ms\\n\");\n \tprintf(\"  --noisy-lkup-memory=N: allocate N MB of VNF memory\\n\");\n@@ -698,6 +699,7 @@ launch_args_parse(int argc, char** argv)\n \t\t{ \"mp-alloc\",\t\t\t1, 0, 0 },\n \t\t{ \"tx-ip\",\t\t\t1, 0, 0 },\n \t\t{ \"tx-udp\",\t\t\t1, 0, 0 },\n+\t\t{ \"noisy-forward-mode\",\t\t1, 0, 0 },\n \t\t{ \"noisy-tx-sw-buffer-size\",\t1, 0, 0 },\n \t\t{ \"noisy-tx-sw-buffer-flushtime\", 1, 0, 0 },\n \t\t{ \"noisy-lkup-memory\",\t\t1, 0, 0 },\n@@ -1444,6 +1446,19 @@ launch_args_parse(int argc, char** argv)\n \t\t\t\t\trte_exit(EXIT_FAILURE,\n \t\t\t\t\t\t \"noisy-lkup-num-reads-writes must be >= 0\\n\");\n \t\t\t}\n+\t\t\tif (!strcmp(lgopts[opt_idx].name,\n+\t\t\t\t    \"noisy-forward-mode\")) {\n+\t\t\t\tint i;\n+\t\t\t\tfor (i = 0; i < NOISY_FWD_MODE_MAX; i++)\n+\t\t\t\t\tif (!strcmp(optarg, noisy_fwd_mode_desc[i])) {\n+\t\t\t\t\t\tnoisy_fwd_mode = i;\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t\t}\n+\t\t\t\tif (i == NOISY_FWD_MODE_MAX)\n+\t\t\t\t\trte_exit(EXIT_FAILURE, \"noisy-forward-mode %s invalid,\"\n+\t\t\t\t\t\t \" must be a valid noisy-forward-mode value\\n\",\n+\t\t\t\t\t\t optarg);\n+\t\t\t}\n \t\t\tif (!strcmp(lgopts[opt_idx].name, \"no-iova-contig\"))\n \t\t\t\tmempool_flags = RTE_MEMPOOL_F_NO_IOVA_CONTIG;\n \ndiff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c\nindex 5cb6f92523..c6ad9b18bf 100644\n--- a/app/test-pmd/testpmd.c\n+++ b/app/test-pmd/testpmd.c\n@@ -330,6 +330,20 @@ int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;\n  */\n int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;\n \n+/*\n+ * Configurable sub-forwarding mode for the noisy_vnf forwarding mode.\n+ */\n+enum noisy_fwd_mode noisy_fwd_mode;\n+\n+/* String version of enum noisy_fwd_mode */\n+const char * const noisy_fwd_mode_desc[] = {\n+\t[NOISY_FWD_MODE_IO] = \"io\",\n+\t[NOISY_FWD_MODE_MAC] = \"mac\",\n+\t[NOISY_FWD_MODE_MACSWAP] = \"macswap\",\n+\t[NOISY_FWD_MODE_5TSWAP] = \"5tswap\",\n+\t[NOISY_FWD_MODE_MAX] = NULL,\n+};\n+\n /*\n  * Configurable value of buffered packets before sending.\n  */\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex bdfbfd36d3..2f18cf20a2 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -116,6 +116,14 @@ enum {\n \tQUEUE_JOB_TYPE_ACTION_QUERY,\n };\n \n+enum noisy_fwd_mode {\n+\tNOISY_FWD_MODE_IO,\n+\tNOISY_FWD_MODE_MAC,\n+\tNOISY_FWD_MODE_MACSWAP,\n+\tNOISY_FWD_MODE_5TSWAP,\n+\tNOISY_FWD_MODE_MAX,\n+};\n+\n /**\n  * The data structure associated with RX and TX packet burst statistics\n  * that are recorded for each forwarding stream.\n@@ -391,6 +399,7 @@ struct fwd_engine {\n \tport_fwd_end_t   port_fwd_end;   /**< NULL if nothing special to do. */\n \tstream_init_t    stream_init;    /**< NULL if nothing special to do. */\n \tpacket_fwd_t     packet_fwd;     /**< Mandatory. */\n+\tconst char       *status;        /**< NULL if nothing to display. */\n };\n \n void common_fwd_stream_init(struct fwd_stream *fs);\n@@ -555,6 +564,8 @@ extern int8_t rx_drop_en;\n extern int16_t tx_free_thresh;\n extern int16_t tx_rs_thresh;\n \n+extern enum noisy_fwd_mode noisy_fwd_mode;\n+extern const char * const noisy_fwd_mode_desc[];\n extern uint16_t noisy_tx_sw_bufsz;\n extern uint16_t noisy_tx_sw_buf_flush_time;\n extern uint64_t noisy_lkup_mem_sz;\ndiff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst\nindex 57b23241cf..8319a30968 100644\n--- a/doc/guides/testpmd_app_ug/run_app.rst\n+++ b/doc/guides/testpmd_app_ug/run_app.rst\n@@ -487,6 +487,15 @@ The command line options are:\n     * xmemhuge: create and populate mempool using externally and anonymously\n       allocated hugepage area\n \n+*   ``--noisy-forward-mode=mode``\n+\n+    Set the noisy vnf forwarding mode where ``mode`` is one of the following::\n+\n+       io (the default)\n+       mac\n+       macswap\n+       5tswap\n+\n *   ``--noisy-tx-sw-buffer-size``\n \n     Set the number of maximum elements  of the FIFO queue to be created\n",
    "prefixes": [
        "v7"
    ]
}