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 <rte_ip.h>
 #include <rte_flow.h>
 
-#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(&eth_hdr->dst_addr, &addr);
-	rte_ether_addr_copy(&eth_hdr->src_addr, &eth_hdr->dst_addr);
-	rte_ether_addr_copy(&addr, &eth_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 = ipv4_hdr->src_addr;
-	ipv4_hdr->src_addr = ipv4_hdr->dst_addr;
-	ipv4_hdr->dst_addr = 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 = tcp_hdr->src_port;
-	tcp_hdr->src_port = tcp_hdr->dst_port;
-	tcp_hdr->dst_port = port;
-}
-
-static inline void
-swap_udp(struct rte_udp_hdr *udp_hdr)
-{
-	rte_be16_t port;
-
-	/* Swap dest and src udp port */
-	port = udp_hdr->src_port;
-	udp_hdr->src_port = udp_hdr->dst_port;
-	udp_hdr->dst_port = 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 == 0))
 		return false;
 
-	txp = &ports[fs->tx_port];
-	ol_flags = 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 = 0; i < nb_rx; i++) {
-		if (likely(i < nb_rx - 1))
-			rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1],
-					void *));
-		mb = pkts_burst[i];
-		h.eth = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
-		proto = h.eth->ether_type;
-		swap_mac(h.eth);
-		mb->l2_len = sizeof(struct rte_ether_hdr);
-		h.eth++;
-		while (proto == RTE_BE16(RTE_ETHER_TYPE_VLAN) ||
-		       proto == RTE_BE16(RTE_ETHER_TYPE_QINQ)) {
-			proto = h.vlan->eth_proto;
-			h.vlan++;
-			mb->l2_len += sizeof(struct rte_vlan_hdr);
-		}
-		if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {
-			swap_ipv4(h.ipv4);
-			next_proto = h.ipv4->next_proto_id;
-			mb->l3_len = rte_ipv4_hdr_len(h.ipv4);
-			h.byte += mb->l3_len;
-		} else if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {
-			swap_ipv6(h.ipv6);
-			next_proto = h.ipv6->proto;
-			h.ipv6++;
-			mb->l3_len = sizeof(struct rte_ipv6_hdr);
-		} else {
-			mbuf_field_set(mb, ol_flags);
-			continue;
-		}
-		if (next_proto == IPPROTO_UDP) {
-			swap_udp(h.udp);
-			mb->l4_len = sizeof(struct rte_udp_hdr);
-		} else if (next_proto == IPPROTO_TCP) {
-			swap_tcp(h.tcp);
-			mb->l4_len = (h.tcp->data_off & 0xf0) >> 2;
-		}
-		mbuf_field_set(mb, ol_flags);
-	}
+	do_5tswap(pkts_burst, nb_rx, fs);
+
 	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..974af1aacd
--- /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(&eth_hdr->dst_addr, &addr);
+	rte_ether_addr_copy(&eth_hdr->src_addr, &eth_hdr->dst_addr);
+	rte_ether_addr_copy(&addr, &eth_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 = ipv4_hdr->src_addr;
+	ipv4_hdr->src_addr = ipv4_hdr->dst_addr;
+	ipv4_hdr->dst_addr = 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 = tcp_hdr->src_port;
+	tcp_hdr->src_port = tcp_hdr->dst_port;
+	tcp_hdr->dst_port = port;
+}
+
+static inline void
+swap_udp(struct rte_udp_hdr *udp_hdr)
+{
+	rte_be16_t port;
+
+	/* Swap dest and src udp port */
+	port = udp_hdr->src_port;
+	udp_hdr->src_port = udp_hdr->dst_port;
+	udp_hdr->dst_port = 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 = &ports[fs->tx_port];
+	ol_flags = 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 = 0; i < nb_rx; i++) {
+		if (likely(i < nb_rx - 1))
+			rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i+1],
+						       void *));
+		mb = pkts_burst[i];
+		h.eth = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
+		proto = h.eth->ether_type;
+		swap_mac(h.eth);
+		mb->l2_len = sizeof(struct rte_ether_hdr);
+		h.eth++;
+		while (proto == RTE_BE16(RTE_ETHER_TYPE_VLAN) ||
+		       proto == RTE_BE16(RTE_ETHER_TYPE_QINQ)) {
+			proto = h.vlan->eth_proto;
+			h.vlan++;
+			mb->l2_len += sizeof(struct rte_vlan_hdr);
+		}
+		if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {
+			swap_ipv4(h.ipv4);
+			next_proto = h.ipv4->next_proto_id;
+			mb->l3_len = rte_ipv4_hdr_len(h.ipv4);
+			h.byte += mb->l3_len;
+		} else if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {
+			swap_ipv6(h.ipv6);
+			next_proto = h.ipv6->proto;
+			h.ipv6++;
+			mb->l3_len = sizeof(struct rte_ipv6_hdr);
+		} else {
+			mbuf_field_set(mb, ol_flags);
+			continue;
+		}
+		if (next_proto == IPPROTO_UDP) {
+			swap_udp(h.udp);
+			mb->l4_len = sizeof(struct rte_udp_hdr);
+		} else if (next_proto == IPPROTO_TCP) {
+			swap_tcp(h.tcp);
+			mb->l4_len = (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 <rte_flow.h>
 
 #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 = 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 == 0))
 		return false;
 
-	txp = &ports[fs->tx_port];
-	tx_offloads = txp->dev_conf.txmode.offloads;
-	if (tx_offloads	& RTE_ETH_TX_OFFLOAD_VLAN_INSERT)
-		ol_flags = RTE_MBUF_F_TX_VLAN;
-	if (tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT)
-		ol_flags |= RTE_MBUF_F_TX_QINQ;
-	if (tx_offloads & RTE_ETH_TX_OFFLOAD_MACSEC_INSERT)
-		ol_flags |= RTE_MBUF_F_TX_MACSEC;
-	for (i = 0; i < nb_rx; i++) {
-		if (likely(i < nb_rx - 1))
-			rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
-						       void *));
-		mb = pkts_burst[i];
-		eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
-		rte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
-				&eth_hdr->dst_addr);
-		rte_ether_addr_copy(&ports[fs->tx_port].eth_addr,
-				&eth_hdr->src_addr);
-		mb->ol_flags &= RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERNAL;
-		mb->ol_flags |= ol_flags;
-		mb->l2_len = sizeof(struct rte_ether_hdr);
-		mb->l3_len = sizeof(struct rte_ipv4_hdr);
-		mb->vlan_tci = txp->tx_vlan_id;
-		mb->vlan_tci_outer = 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..69d9dfc64f
--- /dev/null
+++ b/app/test-pmd/macfwd.h
@@ -0,0 +1,45 @@
+/* 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)
+{
+	struct rte_ether_hdr *eth_hdr;
+	uint64_t ol_flags = 0;
+	uint64_t tx_offloads;
+	struct rte_mbuf  *mb;
+	struct rte_port *txp = &ports[fs->tx_port];
+	uint16_t i;
+
+	tx_offloads = txp->dev_conf.txmode.offloads;
+	if (tx_offloads	& RTE_ETH_TX_OFFLOAD_VLAN_INSERT)
+		ol_flags = RTE_MBUF_F_TX_VLAN;
+	if (tx_offloads & RTE_ETH_TX_OFFLOAD_QINQ_INSERT)
+		ol_flags |= RTE_MBUF_F_TX_QINQ;
+	if (tx_offloads & RTE_ETH_TX_OFFLOAD_MACSEC_INSERT)
+		ol_flags |= RTE_MBUF_F_TX_MACSEC;
+	for (i = 0; i < nb_rx; i++) {
+		if (likely(i < nb_rx - 1))
+			rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
+						       void *));
+		mb = pkts_burst[i];
+		eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
+		rte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
+				    &eth_hdr->dst_addr);
+		rte_ether_addr_copy(&ports[fs->tx_port].eth_addr,
+				    &eth_hdr->src_addr);
+		mb->ol_flags &= RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERNAL;
+		mb->ol_flags |= ol_flags;
+		mb->l2_len = sizeof(struct rte_ether_hdr);
+		mb->l3_len = sizeof(struct rte_ipv4_hdr);
+		mb->vlan_tci = txp->tx_vlan_id;
+		mb->vlan_tci_outer = txp->tx_vlan_id_outer;
+	}
+}
+
+#endif /* _MACFWD_H_ */
diff --git a/app/test-pmd/macswap.h b/app/test-pmd/macswap.h
index 29c252bb8f..7fea461e77 100644
--- a/app/test-pmd/macswap.h
+++ b/app/test-pmd/macswap.h
@@ -9,7 +9,7 @@
 
 static inline void
 do_macswap(struct rte_mbuf *pkts[], uint16_t nb,
-		struct rte_port *txp)
+	   struct rte_port *txp)
 {
 	struct rte_ether_hdr *eth_hdr;
 	struct rte_mbuf *mb;
diff --git a/app/test-pmd/macswap_neon.h b/app/test-pmd/macswap_neon.h
index df6c260cd4..91d4cb7c2e 100644
--- a/app/test-pmd/macswap_neon.h
+++ b/app/test-pmd/macswap_neon.h
@@ -14,7 +14,7 @@
 
 static inline void
 do_macswap(struct rte_mbuf *pkts[], uint16_t nb,
-		struct rte_port *txp)
+	   struct rte_port *txp)
 {
 	struct rte_ether_hdr *eth_hdr[4];
 	struct rte_mbuf *mb[4];
diff --git a/app/test-pmd/macswap_sse.h b/app/test-pmd/macswap_sse.h
index 223f87a539..e17cc07be0 100644
--- a/app/test-pmd/macswap_sse.h
+++ b/app/test-pmd/macswap_sse.h
@@ -9,7 +9,7 @@
 
 static inline void
 do_macswap(struct rte_mbuf *pkts[], uint16_t nb,
-		struct rte_port *txp)
+	   struct rte_port *txp)
 {
 	struct rte_ether_hdr *eth_hdr[4];
 	struct rte_mbuf *mb[4];
@@ -29,7 +29,7 @@ do_macswap(struct rte_mbuf *pkts[], uint16_t nb,
 
 	ol_flags = ol_flags_init(txp->dev_conf.txmode.offloads);
 	vlan_qinq_set(pkts, nb, ol_flags,
-			txp->tx_vlan_id, txp->tx_vlan_id_outer);
+		      txp->tx_vlan_id, txp->tx_vlan_id_outer);
 
 	i = 0;
 	r = nb;
diff --git a/app/test-pmd/noisy_vnf.c b/app/test-pmd/noisy_vnf.c
index 2bf90a983c..9b33930cab 100644
--- a/app/test-pmd/noisy_vnf.c
+++ b/app/test-pmd/noisy_vnf.c
@@ -32,6 +32,18 @@
 #include <rte_malloc.h>
 
 #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;
-
 	for (i = 0; i < nb_pkts; i++) {
 		for (j = 0; j < noisy_lkup_num_writes; j++)
 			do_write(ncf->vnf_mem);
@@ -110,15 +119,13 @@ sim_memory_lookups(struct noisy_config *ncf, uint16_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_mbuf **pkts_burst)
 {
 	const uint64_t freq_khz = rte_get_timer_hz() / 1000;
 	struct noisy_config *ncf = 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 = 0;
-	uint16_t nb_rx = 0;
 	uint16_t nb_tx = 0;
 	uint16_t nb_enqd;
 	unsigned int fifo_free;
@@ -126,12 +133,16 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs)
 	bool needs_flush = false;
 	uint64_t now;
 
-	nb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);
-	if (unlikely(nb_rx == 0))
-		goto flush;
+	if (unlikely(nb_rx == 0)) {
+		if (!ncf->do_buffering)
+			goto end;
+		else
+			goto flush;
+	}
 
 	if (!ncf->do_buffering) {
-		sim_memory_lookups(ncf, nb_rx);
+		if (ncf->do_sim)
+			sim_memory_lookups(ncf, nb_rx);
 		nb_tx = common_fwd_stream_transmit(fs, pkts_burst, nb_rx);
 		goto end;
 	}
@@ -150,7 +161,8 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs)
 			nb_tx = common_fwd_stream_transmit(fs, tmp_pkts, nb_deqd);
 	}
 
-	sim_memory_lookups(ncf, nb_enqd);
+	if (ncf->do_sim)
+		sim_memory_lookups(ncf, nb_enqd);
 
 flush:
 	if (ncf->do_flush) {
@@ -169,11 +181,64 @@ pkt_burst_noisy_vnf(struct fwd_stream *fs)
 		ncf->prev_time = 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 = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);
+	nb_tx = 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 = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);
+	if (likely(nb_rx != 0))
+		do_macfwd(pkts_burst, nb_rx, fs);
+	nb_tx = 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;
+	uint16_t nb_tx;
+
+	nb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);
+	if (likely(nb_rx != 0))
+		do_macswap(pkts_burst, nb_rx, &ports[fs->tx_port]);
+	nb_tx = 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;
+	uint16_t nb_tx;
+
+	nb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst);
+	if (likely(nb_rx != 0))
+		do_5tswap(pkts_burst, nb_rx, fs);
+	nb_tx = 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 +291,15 @@ noisy_fwd_begin(portid_t pi)
 			 "--noisy-lkup-memory-size must be > 0\n");
 	}
 
+	if (noisy_fwd_mode == NOISY_FWD_MODE_IO)
+		noisy_vnf_engine.packet_fwd = pkt_burst_io;
+	else if (noisy_fwd_mode == NOISY_FWD_MODE_MAC)
+		noisy_vnf_engine.packet_fwd = pkt_burst_mac;
+	else if (noisy_fwd_mode == NOISY_FWD_MODE_MACSWAP)
+		noisy_vnf_engine.packet_fwd = pkt_burst_macswap;
+	else if (noisy_fwd_mode == NOISY_FWD_MODE_5TSWAP)
+		noisy_vnf_engine.packet_fwd = pkt_brust_5tswap;
+
 	return 0;
 }
 
@@ -233,6 +307,6 @@ struct fwd_engine noisy_vnf_engine = {
 	.fwd_mode_name  = "noisy",
 	.port_fwd_begin = noisy_fwd_begin,
 	.port_fwd_end   = noisy_fwd_end,
-	.stream_init    = common_fwd_stream_init,
-	.packet_fwd     = pkt_burst_noisy_vnf,
+	.stream_init	= common_fwd_stream_init,
+	.packet_fwd     = pkt_burst_io,
 };
diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c
index 3b37809baf..551714cce4 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=N: do N random writes per packet\n");
 	printf("  --noisy-lkup-num-reads=N: do N random reads per packet\n");
 	printf("  --noisy-lkup-num-reads-writes=N: do N random reads and writes per packet\n");
+	printf("  --noisy-fwd-mode=mode: set the fwd mode\n");
 	printf("  --no-iova-contig: mempool memory can be IOVA non contiguous. "
 	       "valid only with --mp-alloc=anon\n");
 	printf("  --rx-mq-mode=0xX: hexadecimal bitmask of RX mq mode can 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-writes must be >= 0\n");
 			}
+			if (!strcmp(lgopts[opt_idx].name,
+				    "noisy-fwd-mode")) {
+				if (!strcmp(optarg, "io"))
+					noisy_fwd_mode = NOISY_FWD_MODE_IO;
+				else if (!strcmp(optarg, "mac"))
+					noisy_fwd_mode = NOISY_FWD_MODE_MAC;
+				else if (!strcmp(optarg, "macswap"))
+					noisy_fwd_mode = NOISY_FWD_MODE_MACSWAP;
+				else if (!strcmp(optarg, "5tswap"))
+					noisy_fwd_mode = NOISY_FWD_MODE_5TSWAP;
+				else
+					rte_exit(EXIT_FAILURE, "noisy-fwd-mode %s invalid -"
+						 " must be a valid noisy-fwd-mode value\n",
+						 optarg);
+			}
 			if (!strcmp(lgopts[opt_idx].name, "no-iova-contig"))
 				mempool_flags = RTE_MEMPOOL_F_NO_IOVA_CONTIG;
 
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 statistics
  * 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 simulation memory buffer to N.
     Only available with the noisy forwarding mode. The default value is 0.
 
+*   ``--noisy-fwd-mode=mode``
+
+    Set the noisy vnf forwarding mode where ``mode`` is one of the following::
+
+       io (the default)
+       mac
+       macswap
+       5tswap
+
 *   ``--no-iova-contig``
 
     Enable to create mempool which is not IOVA contiguous. Valid only with --mp-alloc=anon.
