From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2992742B9F; Fri, 26 May 2023 19:33:02 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C252940DDA; Fri, 26 May 2023 19:33:01 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id 60CBE4068E for ; Fri, 26 May 2023 19:33:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685122379; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1A55uIgM+Y7J5RJQc6HYFbwoXxkyU5thdnhXCXX5vzE=; b=WsHQqURWcmKulkRoovCOHe2R6FpttXVeFBNjXVCzqJN0AREhQ/r7hY8Vx4VpJ7TcTlD/X7 e8OGVDeeMGuu/q7S19I3iqOQIHXpYlHFT2zx23Zh7tRvB/7dtSzUUabUIYVnz2ieCBLSqg Pe2un5YRPH1OebrMk0eswGVv3epPlk0= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-74-bE-A8Dl5OWu5B80EaXpfLg-1; Fri, 26 May 2023 13:32:58 -0400 X-MC-Unique: bE-A8Dl5OWu5B80EaXpfLg-1 Received: by mail-ej1-f71.google.com with SMTP id a640c23a62f3a-96f4f1bb838so96400266b.3 for ; Fri, 26 May 2023 10:32:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685122377; x=1687714377; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1A55uIgM+Y7J5RJQc6HYFbwoXxkyU5thdnhXCXX5vzE=; b=KkVr1mbFtUi361h291BXnwef3ANWT+H10BtCKgG5nlMxyl7wU7iO58O8dryMokAvuk ogynhio3EXTKhb+dfxRV5vV0+3N7DAqoyX24Rg65SLQmiiEElIhknTbrnjogBtii1gEl /9cGpZ3Gkilx2duw2eqyjSU3pL133KfqpSEo0lylb4Mh6Z/kk39OYZar3uUbSruLUD2q XpIvRuj+Xu0A9VPzGTd1wP9Sm8+truy5QlNp6WjzsAUu27ADxCyjP59Xh7GG797ysaDK 1C4dlNVZ1BGFprMp5oI1sOvquzytXRc24PLhVoFvNQNi8XF8NcxaHf2wZ7dYBKrVLaro xyaA== X-Gm-Message-State: AC+VfDySHSpyCISPFy+FlbizqRjzxmbijIFF6UQm30OOKGMQNNkwrAw4 Cx3Ivk4vGnOUf+x9nmEpAX1GQjQ2Xaol/q2+Hq6z1Zq1/OaoLIxXlUCbSE+xcvzh15jdEU2dJTj nLsgeCdxy6gS0bdRh1lnYpcYhr+PJJw== X-Received: by 2002:a17:907:25c9:b0:969:cbf4:98fa with SMTP id ae9-20020a17090725c900b00969cbf498famr2711199ejc.65.1685122376689; Fri, 26 May 2023 10:32:56 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7BBaPyd1nVy1hXqb02Yj/5iWwofz1Sd51LpeId+bPE/+Y3k2dRxyQOe9r0vl0vWvYjILcWZpsz2n+0pZyQBII= X-Received: by 2002:a17:907:25c9:b0:969:cbf4:98fa with SMTP id ae9-20020a17090725c900b00969cbf498famr2711168ejc.65.1685122376188; Fri, 26 May 2023 10:32:56 -0700 (PDT) MIME-Version: 1.0 References: <20230417185536.1817578-1-mkp@redhat.com> <303c7549-6aa5-18d5-fdb4-42b8df1d0dc5@redhat.com> In-Reply-To: <303c7549-6aa5-18d5-fdb4-42b8df1d0dc5@redhat.com> From: Mike Pattrick Date: Fri, 26 May 2023 13:32:44 -0400 Message-ID: Subject: Re: [PATCH v3] app/testpmd: expand noisy neighbour forward mode support To: Kevin Traynor Cc: Aman Singh , Yuying Zhang , dev@dpdk.org, Ferruh Yigit , David Marchand X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On Fri, May 26, 2023 at 11:34=E2=80=AFAM Kevin Traynor wrote: > > On 17/04/2023 19:55, Mike Pattrick wrote: > > Previously the noisy neighbour vnf simulation would only operate in io > > mode, forwarding packets as is. However, this limited the usefulness of > > noisy neighbour simulation. > > > > This feature has now been expanded to supporting mac, macswap, and > > 5tswap modes. To facilitate adding this support, some new header files > > were added. > > > > Hi Mike, > > I think it makes sense to allow these functionalities to be combined. It > does seem like that noisy neighbour shouldn't have been added as a > standalone fowarding option in the first place, as it's not mutually > exclusive with the other fwding modes. Now it's forcing a user to set a > fwding mode within a fwding mode to combine the functionality :/ > > The approach is to allow the fwding modes to expose their forwarding > method so noisy can call them. Did you consider to expose the noisy > functionality and allow the other forwarding modes to call that when the > --noisy-* flags are set? Personally I like this approach more, and that was the strategy I took with the previous version. However, that change didn't seem popular at the time. http://patches.dpdk.org/project/dpdk/patch/20230126045516.176917-1-mkp@redh= at.com/#157095 > For example, a user sets fwding mode as normal 'fwd=3Dmacfwd' but then if > the user adds the --noisy-* params, the macfwd'ing mode calls some > functions exposed to add the noise, which seems a bit more intuitive. > > Also, if someone adds a new fwding mode, they can just call the noisy > functions and don't have update noisy fwding mode to add the new mode. > > I'm not sure if it's better, just throwing it out there as an > alternative idea. > > On the downside, it would break backwards compatibility because > previously those --noisy-* params would have had no effect with say > macfwd mode, but now they will. So maybe that's enough to prohibit it. > > In the past, I would have had all the params set and just changed > fwdmode to enable/disable noisy vnf. That would behaviour would now be > changed with this approach. > > What do you think? > > Few comments on the code below. > > thanks, > Kevin. > > > Signed-off-by: Mike Pattrick > > --- > > v2: Reverted changes to random memory lookup > > v3: Refactored entire patch > > --- > > app/test-pmd/5tswap.c | 118 +---------------------- > > app/test-pmd/5tswap.h | 130 +++++++++++++++++++++++++= + > > app/test-pmd/macfwd.c | 33 +------ > > app/test-pmd/macfwd.h | 46 +++++++++ > > app/test-pmd/noisy_vnf.c | 92 +++++++++++++++--- > > app/test-pmd/parameters.c | 17 ++++ > > app/test-pmd/testpmd.c | 5 + > > app/test-pmd/testpmd.h | 8 ++ > > doc/guides/testpmd_app_ug/run_app.rst | 9 ++ > > 9 files changed, 299 insertions(+), 159 deletions(-) > > create mode 100644 app/test-pmd/5tswap.h > > create mode 100644 app/test-pmd/macfwd.h > > > > diff --git a/app/test-pmd/5tswap.c b/app/test-pmd/5tswap.c > > index ff8c2dcde5..8e8de2557a 100644 > > --- a/app/test-pmd/5tswap.c > > +++ b/app/test-pmd/5tswap.c > > @@ -17,64 +17,8 @@ > > #include > > #include > > > > -#include "macswap_common.h" > > #include "testpmd.h" > > - > > - > > -static inline void > > -swap_mac(struct rte_ether_hdr *eth_hdr) > > -{ > > - struct rte_ether_addr addr; > > - > > - /* Swap dest and src mac addresses. */ > > - rte_ether_addr_copy(ð_hdr->dst_addr, &addr); > > - rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr); > > - rte_ether_addr_copy(&addr, ð_hdr->src_addr); > > -} > > - > > -static inline void > > -swap_ipv4(struct rte_ipv4_hdr *ipv4_hdr) > > -{ > > - rte_be32_t addr; > > - > > - /* Swap dest and src ipv4 addresses. */ > > - addr =3D ipv4_hdr->src_addr; > > - ipv4_hdr->src_addr =3D ipv4_hdr->dst_addr; > > - ipv4_hdr->dst_addr =3D addr; > > -} > > - > > -static inline void > > -swap_ipv6(struct rte_ipv6_hdr *ipv6_hdr) > > -{ > > - uint8_t addr[16]; > > - > > - /* Swap dest and src ipv6 addresses. */ > > - memcpy(&addr, &ipv6_hdr->src_addr, 16); > > - memcpy(&ipv6_hdr->src_addr, &ipv6_hdr->dst_addr, 16); > > - memcpy(&ipv6_hdr->dst_addr, &addr, 16); > > -} > > - > > -static inline void > > -swap_tcp(struct rte_tcp_hdr *tcp_hdr) > > -{ > > - rte_be16_t port; > > - > > - /* Swap dest and src tcp port. */ > > - port =3D tcp_hdr->src_port; > > - tcp_hdr->src_port =3D tcp_hdr->dst_port; > > - tcp_hdr->dst_port =3D port; > > -} > > - > > -static inline void > > -swap_udp(struct rte_udp_hdr *udp_hdr) > > -{ > > - rte_be16_t port; > > - > > - /* Swap dest and src udp port */ > > - port =3D udp_hdr->src_port; > > - udp_hdr->src_port =3D udp_hdr->dst_port; > > - udp_hdr->dst_port =3D port; > > -} > > +#include "5tswap.h" > > > > /* > > * 5 tuple swap forwarding mode: Swap the source and the destination = of layers > > @@ -85,22 +29,7 @@ static bool > > pkt_burst_5tuple_swap(struct fwd_stream *fs) > > { > > struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > - struct rte_port *txp; > > - struct rte_mbuf *mb; > > - uint16_t next_proto; > > - uint64_t ol_flags; > > - uint16_t proto; > > uint16_t nb_rx; > > - int i; > > - union { > > - struct rte_ether_hdr *eth; > > - struct rte_vlan_hdr *vlan; > > - struct rte_ipv4_hdr *ipv4; > > - struct rte_ipv6_hdr *ipv6; > > - struct rte_tcp_hdr *tcp; > > - struct rte_udp_hdr *udp; > > - uint8_t *byte; > > - } h; > > > > /* > > * Receive a burst of packets and forward them. > > @@ -109,49 +38,8 @@ pkt_burst_5tuple_swap(struct fwd_stream *fs) > > if (unlikely(nb_rx =3D=3D 0)) > > return false; > > > > - txp =3D &ports[fs->tx_port]; > > - ol_flags =3D ol_flags_init(txp->dev_conf.txmode.offloads); > > - vlan_qinq_set(pkts_burst, nb_rx, ol_flags, > > - txp->tx_vlan_id, txp->tx_vlan_id_outer); > > - for (i =3D 0; i < nb_rx; i++) { > > - if (likely(i < nb_rx - 1)) > > - rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1], > > - void *)); > > - mb =3D pkts_burst[i]; > > - h.eth =3D rte_pktmbuf_mtod(mb, struct rte_ether_hdr *); > > - proto =3D h.eth->ether_type; > > - swap_mac(h.eth); > > - mb->l2_len =3D sizeof(struct rte_ether_hdr); > > - h.eth++; > > - while (proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_VLAN) || > > - proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_QINQ)) { > > - proto =3D h.vlan->eth_proto; > > - h.vlan++; > > - mb->l2_len +=3D sizeof(struct rte_vlan_hdr); > > - } > > - if (proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_IPV4)) { > > - swap_ipv4(h.ipv4); > > - next_proto =3D h.ipv4->next_proto_id; > > - mb->l3_len =3D rte_ipv4_hdr_len(h.ipv4); > > - h.byte +=3D mb->l3_len; > > - } else if (proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_IPV6)) { > > - swap_ipv6(h.ipv6); > > - next_proto =3D h.ipv6->proto; > > - h.ipv6++; > > - mb->l3_len =3D sizeof(struct rte_ipv6_hdr); > > - } else { > > - mbuf_field_set(mb, ol_flags); > > - continue; > > - } > > - if (next_proto =3D=3D IPPROTO_UDP) { > > - swap_udp(h.udp); > > - mb->l4_len =3D sizeof(struct rte_udp_hdr); > > - } else if (next_proto =3D=3D IPPROTO_TCP) { > > - swap_tcp(h.tcp); > > - mb->l4_len =3D (h.tcp->data_off & 0xf0) >> 2; > > - } > > - mbuf_field_set(mb, ol_flags); > > - } > > + do_5tswap(pkts_burst, nb_rx, fs); > > + > > this simplification is nice. > > > common_fwd_stream_transmit(fs, pkts_burst, nb_rx); > > > > return true; > > diff --git a/app/test-pmd/5tswap.h b/app/test-pmd/5tswap.h > > new file mode 100644 > > index 0000000000..48da9236dc > > --- /dev/null > > +++ b/app/test-pmd/5tswap.h > > @@ -0,0 +1,130 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright(c) 2018 Intel Corporation > > + */ > > + > > +#ifndef _5TSWAP_H_ > > +#define _5TSWAP_H_ > > + > > +#include "macswap_common.h" > > + > > +static inline void > > +swap_mac(struct rte_ether_hdr *eth_hdr) > > +{ > > + struct rte_ether_addr addr; > > + > > + /* Swap dest and src mac addresses. */ > > + rte_ether_addr_copy(ð_hdr->dst_addr, &addr); > > + rte_ether_addr_copy(ð_hdr->src_addr, ð_hdr->dst_addr); > > + rte_ether_addr_copy(&addr, ð_hdr->src_addr); > > +} > > + > > +static inline void > > +swap_ipv4(struct rte_ipv4_hdr *ipv4_hdr) > > +{ > > + rte_be32_t addr; > > + > > + /* Swap dest and src ipv4 addresses. */ > > + addr =3D ipv4_hdr->src_addr; > > + ipv4_hdr->src_addr =3D ipv4_hdr->dst_addr; > > + ipv4_hdr->dst_addr =3D addr; > > +} > > + > > +static inline void > > +swap_ipv6(struct rte_ipv6_hdr *ipv6_hdr) > > +{ > > + uint8_t addr[16]; > > + > > + /* Swap dest and src ipv6 addresses. */ > > + memcpy(&addr, &ipv6_hdr->src_addr, 16); > > + memcpy(&ipv6_hdr->src_addr, &ipv6_hdr->dst_addr, 16); > > + memcpy(&ipv6_hdr->dst_addr, &addr, 16); > > +} > > + > > +static inline void > > +swap_tcp(struct rte_tcp_hdr *tcp_hdr) > > +{ > > + rte_be16_t port; > > + > > + /* Swap dest and src tcp port. */ > > + port =3D tcp_hdr->src_port; > > + tcp_hdr->src_port =3D tcp_hdr->dst_port; > > + tcp_hdr->dst_port =3D port; > > +} > > + > > +static inline void > > +swap_udp(struct rte_udp_hdr *udp_hdr) > > +{ > > + rte_be16_t port; > > + > > + /* Swap dest and src udp port */ > > + port =3D udp_hdr->src_port; > > + udp_hdr->src_port =3D udp_hdr->dst_port; > > + udp_hdr->dst_port =3D port; > > +} > > + > > +static inline void > > +do_5tswap(struct rte_mbuf *pkts_burst[], uint16_t nb_rx, > > + struct fwd_stream *fs) > > +{ > > + struct rte_port *txp; > > + struct rte_mbuf *mb; > > + uint16_t next_proto; > > + uint64_t ol_flags; > > + uint16_t proto; > > + int i; > > + union { > > + struct rte_ether_hdr *eth; > > + struct rte_vlan_hdr *vlan; > > + struct rte_ipv4_hdr *ipv4; > > + struct rte_ipv6_hdr *ipv6; > > + struct rte_tcp_hdr *tcp; > > + struct rte_udp_hdr *udp; > > + uint8_t *byte; > > + } h; > > + > > + txp =3D &ports[fs->tx_port]; > > + ol_flags =3D ol_flags_init(txp->dev_conf.txmode.offloads); > > + vlan_qinq_set(pkts_burst, nb_rx, ol_flags, > > + txp->tx_vlan_id, txp->tx_vlan_id_outer); > > + for (i =3D 0; i < nb_rx; i++) { > > + if (likely(i < nb_rx - 1)) > > + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1], > > + void *)); > > + mb =3D pkts_burst[i]; > > + h.eth =3D rte_pktmbuf_mtod(mb, struct rte_ether_hdr *); > > + proto =3D h.eth->ether_type; > > + swap_mac(h.eth); > > + mb->l2_len =3D sizeof(struct rte_ether_hdr); > > + h.eth++; > > + while (proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_VLAN) || > > + proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_QINQ)) { > > + proto =3D h.vlan->eth_proto; > > + h.vlan++; > > + mb->l2_len +=3D sizeof(struct rte_vlan_hdr); > > + } > > + if (proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_IPV4)) { > > + swap_ipv4(h.ipv4); > > + next_proto =3D h.ipv4->next_proto_id; > > + mb->l3_len =3D rte_ipv4_hdr_len(h.ipv4); > > + h.byte +=3D mb->l3_len; > > + } else if (proto =3D=3D RTE_BE16(RTE_ETHER_TYPE_IPV6)) { > > + swap_ipv6(h.ipv6); > > + next_proto =3D h.ipv6->proto; > > + h.ipv6++; > > + mb->l3_len =3D sizeof(struct rte_ipv6_hdr); > > + } else { > > + mbuf_field_set(mb, ol_flags); > > + continue; > > + } > > + if (next_proto =3D=3D IPPROTO_UDP) { > > + swap_udp(h.udp); > > + mb->l4_len =3D sizeof(struct rte_udp_hdr); > > + } else if (next_proto =3D=3D IPPROTO_TCP) { > > + swap_tcp(h.tcp); > > + mb->l4_len =3D (h.tcp->data_off & 0xf0) >> 2; > > + } > > + mbuf_field_set(mb, ol_flags); > > + } > > +} > > + > > +#endif /* _5TSWAP_H_ */ > > diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c > > index 7316d73315..d19ace7395 100644 > > --- a/app/test-pmd/macfwd.c > > +++ b/app/test-pmd/macfwd.c > > @@ -35,6 +35,7 @@ > > #include > > > > #include "testpmd.h" > > +#include "macfwd.h" > > > > /* > > * Forwarding of packets in MAC mode. > > @@ -45,13 +46,7 @@ static bool > > pkt_burst_mac_forward(struct fwd_stream *fs) > > { > > struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > - struct rte_port *txp; > > - struct rte_mbuf *mb; > > - struct rte_ether_hdr *eth_hdr; > > uint16_t nb_rx; > > - uint16_t i; > > - uint64_t ol_flags =3D 0; > > - uint64_t tx_offloads; > > > > /* > > * Receive a burst of packets and forward them. > > @@ -60,31 +55,7 @@ pkt_burst_mac_forward(struct fwd_stream *fs) > > if (unlikely(nb_rx =3D=3D 0)) > > return false; > > > > - txp =3D &ports[fs->tx_port]; > > - tx_offloads =3D txp->dev_conf.txmode.offloads; > > - if (tx_offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) > > - ol_flags =3D RTE_MBUF_F_TX_VLAN; > > - if (tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT) > > - ol_flags |=3D RTE_MBUF_F_TX_QINQ; > > - if (tx_offloads & RTE_ETH_TX_OFFLOAD_MACSEC_INSERT) > > - ol_flags |=3D RTE_MBUF_F_TX_MACSEC; > > - for (i =3D 0; i < nb_rx; i++) { > > - if (likely(i < nb_rx - 1)) > > - rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], > > - void *)); > > - mb =3D pkts_burst[i]; > > - eth_hdr =3D rte_pktmbuf_mtod(mb, struct rte_ether_hdr *); > > - rte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr], > > - ð_hdr->dst_addr); > > - rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, > > - ð_hdr->src_addr); > > - mb->ol_flags &=3D RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERN= AL; > > - mb->ol_flags |=3D ol_flags; > > - mb->l2_len =3D sizeof(struct rte_ether_hdr); > > - mb->l3_len =3D sizeof(struct rte_ipv4_hdr); > > - mb->vlan_tci =3D txp->tx_vlan_id; > > - mb->vlan_tci_outer =3D txp->tx_vlan_id_outer; > > - } > > + do_macfwd(pkts_burst, nb_rx, fs); > > > > common_fwd_stream_transmit(fs, pkts_burst, nb_rx); > > > > diff --git a/app/test-pmd/macfwd.h b/app/test-pmd/macfwd.h > > new file mode 100644 > > index 0000000000..3f3e7189e1 > > --- /dev/null > > +++ b/app/test-pmd/macfwd.h > > @@ -0,0 +1,46 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright(c) 2018 Intel Corporation > > + */ > > + > > +#ifndef _MACFWD_H_ > > +#define _MACFWD_H_ > > + > > +static inline void > > +do_macfwd(struct rte_mbuf *pkts_burst[], uint16_t nb_rx, > > + struct fwd_stream *fs) > > nit: indent/alignment is a little off here. There is some extra spaces. > Same with other do_*() > > > +{ > > + struct rte_ether_hdr *eth_hdr; > > + uint64_t ol_flags =3D 0; > > + uint64_t tx_offloads; > > + struct rte_mbuf *mb; > > + struct rte_port *txp =3D &ports[fs->tx_port]; > > + uint16_t i; > > + > > + > > can remove addition blank line > > > + tx_offloads =3D txp->dev_conf.txmode.offloads; > > + if (tx_offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) > > + ol_flags =3D RTE_MBUF_F_TX_VLAN; > > + if (tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT) > > + ol_flags |=3D RTE_MBUF_F_TX_QINQ; > > + if (tx_offloads & RTE_ETH_TX_OFFLOAD_MACSEC_INSERT) > > + ol_flags |=3D RTE_MBUF_F_TX_MACSEC; > > + for (i =3D 0; i < nb_rx; i++) { > > + if (likely(i < nb_rx - 1)) > > + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], > > + void *)); > > + mb =3D pkts_burst[i]; > > + eth_hdr =3D rte_pktmbuf_mtod(mb, struct rte_ether_hdr *); > > + rte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr], > > + ð_hdr->dst_addr); > > + rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, > > + ð_hdr->src_addr); > > + mb->ol_flags &=3D RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERN= AL; > > + mb->ol_flags |=3D ol_flags; > > + mb->l2_len =3D sizeof(struct rte_ether_hdr); > > + mb->l3_len =3D sizeof(struct rte_ipv4_hdr); > > + mb->vlan_tci =3D txp->tx_vlan_id; > > + mb->vlan_tci_outer =3D txp->tx_vlan_id_outer; > > + } > > +} > > + > > +#endif /* _MACFWD_H_ */ > > diff --git a/app/test-pmd/noisy_vnf.c b/app/test-pmd/noisy_vnf.c > > index 2bf90a983c..1d5a2e470a 100644 > > --- a/app/test-pmd/noisy_vnf.c > > +++ b/app/test-pmd/noisy_vnf.c > > @@ -32,6 +32,18 @@ > > #include > > > > #include "testpmd.h" > > +#include "5tswap.h" > > +#include "macfwd.h" > > +#if defined(RTE_ARCH_X86) > > +#include "macswap_sse.h" > > +#elif defined(__ARM_NEON) > > +#include "macswap_neon.h" > > +#else > > +#include "macswap.h" > > +#endif > > + > > +#define NOISY_STRSIZE 256 > > +#define NOISY_RING "noisy_ring_%d\n" > > > > struct noisy_config { > > struct rte_ring *f; > > @@ -80,9 +92,6 @@ sim_memory_lookups(struct noisy_config *ncf, uint16_t= nb_pkts) > > { > > uint16_t i, j; > > > > - if (!ncf->do_sim) > > - return; > > - > > Why is this removed? It's not checked before all calls to this function > > > for (i =3D 0; i < nb_pkts; i++) { > > for (j =3D 0; j < noisy_lkup_num_writes; j++) > > do_write(ncf->vnf_mem); > > @@ -110,15 +119,13 @@ sim_memory_lookups(struct noisy_config *ncf, uint= 16_t nb_pkts) > > * out of the FIFO > > * 4. Cases 2 and 3 combined > > */ > > -static bool > > -pkt_burst_noisy_vnf(struct fwd_stream *fs) > > +static uint16_t > > +noisy_eth_tx_burst(struct fwd_stream *fs, uint16_t nb_rx, struct rte_m= buf **pkts_burst) > > { > > const uint64_t freq_khz =3D rte_get_timer_hz() / 1000; > > struct noisy_config *ncf =3D noisy_cfg[fs->rx_port]; > > - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > struct rte_mbuf *tmp_pkts[MAX_PKT_BURST]; > > uint16_t nb_deqd =3D 0; > > - uint16_t nb_rx =3D 0; > > uint16_t nb_tx =3D 0; > > uint16_t nb_enqd; > > unsigned int fifo_free; > > @@ -126,12 +133,12 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs) > > bool needs_flush =3D false; > > uint64_t now; > > > > - nb_rx =3D common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_bu= rst); > > if (unlikely(nb_rx =3D=3D 0)) > > goto flush; > > > > if (!ncf->do_buffering) { > > - sim_memory_lookups(ncf, nb_rx); > > + if (ncf->do_sim) > > + sim_memory_lookups(ncf, nb_rx); > > nb_tx =3D common_fwd_stream_transmit(fs, pkts_burst, nb_r= x); > > goto end; > > } > > @@ -169,11 +176,61 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs) > > ncf->prev_time =3D rte_get_timer_cycles(); > > } > > end: > > + return nb_tx; > > +} > > + > > +static bool > > +pkt_burst_io(struct fwd_stream *fs) > > +{ > > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > + uint16_t nb_rx; > > + uint16_t nb_tx; > > + > > + nb_rx =3D common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_bu= rst); > > + nb_tx =3D noisy_eth_tx_burst(fs, nb_rx, pkts_burst); > > + > > return nb_rx > 0 || nb_tx > 0; > > } > > > > -#define NOISY_STRSIZE 256 > > -#define NOISY_RING "noisy_ring_%d\n" > > +static bool > > +pkt_burst_mac(struct fwd_stream *fs) > > +{ > > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > + uint16_t nb_rx; > > + uint16_t nb_tx; > > + > > + nb_rx =3D common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_bu= rst); > > Similar to macfwd.c, you can add check for unlikely(nb_rx =3D=3D 0) at th= is > point in these fns. That's true. I removed it because I'll have to call noisy_eth_tx_burst() regardless, but we could avoid the middle call in these locations. I agree with the other suggestions. Thanks, M > > > + do_macfwd(pkts_burst, nb_rx, fs); > > + nb_tx =3D noisy_eth_tx_burst(fs, nb_rx, pkts_burst); > > + > > + return nb_rx > 0 || nb_tx > 0; > > +} > > +static bool > > +pkt_burst_macswap(struct fwd_stream *fs) > > +{ > > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > + uint16_t nb_rx =3D 0; > > + uint16_t nb_tx =3D 0; > > nit: these are not assigned in the other functions > > > + > > + nb_rx =3D common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_bu= rst); > > + do_macswap(pkts_burst, nb_rx, &ports[fs->tx_port]); > > + nb_tx =3D noisy_eth_tx_burst(fs, nb_rx, pkts_burst); > > + > > + return nb_rx > 0 || nb_tx > 0; > > +} > > +static bool > > +pkt_brust_5tswap(struct fwd_stream *fs) > > +{ > > + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; > > + uint16_t nb_rx =3D 0; > > + uint16_t nb_tx =3D 0; > > + > > + nb_rx =3D common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_bu= rst); > > + do_5tswap(pkts_burst, nb_rx, fs); > > + nb_tx =3D noisy_eth_tx_burst(fs, nb_rx, pkts_burst); > > + > > + return nb_rx > 0 || nb_tx > 0; > > +} > > > > static void > > noisy_fwd_end(portid_t pi) > > @@ -226,6 +283,15 @@ noisy_fwd_begin(portid_t pi) > > "--noisy-lkup-memory-size must be > 0\n"); > > } > > > > + if (noisy_fwd_mode =3D=3D NOISY_FWD_MODE_IO) > > + noisy_vnf_engine.packet_fwd =3D pkt_burst_io; > > + else if (noisy_fwd_mode =3D=3D NOISY_FWD_MODE_MAC) > > + noisy_vnf_engine.packet_fwd =3D pkt_burst_mac; > > + else if (noisy_fwd_mode =3D=3D NOISY_FWD_MODE_MACSWAP) > > + noisy_vnf_engine.packet_fwd =3D pkt_burst_macswap; > > + else if (noisy_fwd_mode =3D=3D NOISY_FWD_MODE_5TSWAP) > > + noisy_vnf_engine.packet_fwd =3D pkt_brust_5tswap; > > + > > return 0; > > } > > > > @@ -233,6 +299,6 @@ struct fwd_engine noisy_vnf_engine =3D { > > .fwd_mode_name =3D "noisy", > > .port_fwd_begin =3D noisy_fwd_begin, > > .port_fwd_end =3D noisy_fwd_end, > > - .stream_init =3D common_fwd_stream_init, > > - .packet_fwd =3D pkt_burst_noisy_vnf, > > + .stream_init =3D common_fwd_stream_init, > > + .packet_fwd =3D pkt_burst_io, > > }; > > diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c > > index 3b37809baf..129c55c0ad 100644 > > --- a/app/test-pmd/parameters.c > > +++ b/app/test-pmd/parameters.c > > @@ -196,6 +196,7 @@ usage(char* progname) > > printf(" --noisy-lkup-num-writes=3DN: do N random writes per pac= ket\n"); > > printf(" --noisy-lkup-num-reads=3DN: do N random reads per packe= t\n"); > > printf(" --noisy-lkup-num-reads-writes=3DN: do N random reads an= d writes per packet\n"); > > + printf(" --noisy-fwd-mode=3Dmode: set the fwd mode\n"); > > printf(" --no-iova-contig: mempool memory can be IOVA non contig= uous. " > > "valid only with --mp-alloc=3Danon\n"); > > printf(" --rx-mq-mode=3D0xX: hexadecimal bitmask of RX mq mode c= an be " > > @@ -704,6 +705,7 @@ launch_args_parse(int argc, char** argv) > > { "noisy-lkup-num-writes", 1, 0, 0 }, > > { "noisy-lkup-num-reads", 1, 0, 0 }, > > { "noisy-lkup-num-reads-writes", 1, 0, 0 }, > > + { "noisy-fwd-mode", 1, 0, 0 }, > > { "no-iova-contig", 0, 0, 0 }, > > { "rx-mq-mode", 1, 0, 0 }, > > { "record-core-cycles", 0, 0, 0 }, > > @@ -1444,6 +1446,21 @@ launch_args_parse(int argc, char** argv) > > rte_exit(EXIT_FAILURE, > > "noisy-lkup-num-reads-wr= ites must be >=3D 0\n"); > > } > > + if (!strcmp(lgopts[opt_idx].name, > > + "noisy-fwd-mode")) { > > + if (!strcmp(optarg, "io")) > > + noisy_fwd_mode =3D NOISY_FWD_MODE= _IO; > > + else if (!strcmp(optarg, "mac")) > > + noisy_fwd_mode =3D NOISY_FWD_MODE= _MAC; > > + else if (!strcmp(optarg, "macswap")) > > + noisy_fwd_mode =3D NOISY_FWD_MODE= _MACSWAP; > > + else if (!strcmp(optarg, "5tswap")) > > + noisy_fwd_mode =3D NOISY_FWD_MODE= _5TSWAP; > > + else > > + rte_exit(EXIT_FAILURE, "noisy-fwd= -mode %s invalid -" > > + " must b a valid fwd mod= e\n", > > typo "be" > > I would specify "..must be a valid noisy-fwd-mode value" to avoid > confusion with the full set of general fwd modes and easier for user to > search them in docs. > > > + optarg); > > + } > > if (!strcmp(lgopts[opt_idx].name, "no-iova-contig= ")) > > mempool_flags =3D RTE_MEMPOOL_F_NO_IOVA_C= ONTIG; > > > > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c > > index 5cb6f92523..92784873ff 100644 > > --- a/app/test-pmd/testpmd.c > > +++ b/app/test-pmd/testpmd.c > > @@ -364,6 +364,11 @@ uint64_t noisy_lkup_num_reads; > > */ > > uint64_t noisy_lkup_num_reads_writes; > > > > +/* > > + * Configurable forwarding mode in VNF simulation. > > + */ > > +int noisy_fwd_mode; > > + > > /* > > * Receive Side Scaling (RSS) configuration. > > */ > > diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h > > index bdfbfd36d3..f70397ad26 100644 > > --- a/app/test-pmd/testpmd.h > > +++ b/app/test-pmd/testpmd.h > > @@ -116,6 +116,13 @@ enum { > > QUEUE_JOB_TYPE_ACTION_QUERY, > > }; > > > > +enum { > > + NOISY_FWD_MODE_IO, > > + NOISY_FWD_MODE_MAC, > > + NOISY_FWD_MODE_MACSWAP, > > + NOISY_FWD_MODE_5TSWAP > > +}; > > + > > /** > > * The data structure associated with RX and TX packet burst statisti= cs > > * that are recorded for each forwarding stream. > > @@ -561,6 +568,7 @@ extern uint64_t noisy_lkup_mem_sz; > > extern uint64_t noisy_lkup_num_writes; > > extern uint64_t noisy_lkup_num_reads; > > extern uint64_t noisy_lkup_num_reads_writes; > > +extern int noisy_fwd_mode; > > > > extern uint8_t dcb_config; > > > > diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd= _app_ug/run_app.rst > > index 57b23241cf..fcca3e8921 100644 > > --- a/doc/guides/testpmd_app_ug/run_app.rst > > +++ b/doc/guides/testpmd_app_ug/run_app.rst > > @@ -519,6 +519,15 @@ The command line options are: > > Set the number of r/w accesses to be done in noisy neighbor simul= ation memory buffer to N. > > Only available with the noisy forwarding mode. The default value = is 0. > > > > +* ``--noisy-fwd-mode=3Dmode`` > > + > > + Set the noisy vnf forwarding mode where ``mode`` is one of the fol= lowing:: > > + > > + io (the default) > > + mac > > + macswap > > + 5tswap > > + > > * ``--no-iova-contig`` > > > > Enable to create mempool which is not IOVA contiguous. Valid only= with --mp-alloc=3Danon. >