[3/3] test/softnic: updated softnic test suite as per dpdk 22.11 changes

Message ID 20221108150636.2459852-4-yogesh.jangra@intel.com (mailing list archive)
State Accepted
Headers
Series update testsuites that uses softnic driver |

Checks

Context Check Description
ci/Intel-dts-doc-test success Testing OK
ci/Intel-dts-format-test success Testing OK
ci/Intel-dts-pylama-test success Testing OK

Commit Message

Yogesh Jangra Nov. 8, 2022, 3:06 p.m. UTC
  From dpdk 22.11 release, Soft NIC driver has started to use rte_swx_pipeline_xxx
library. This changes the CLI format of the Soft NIC. To accomodate those changes,
updating the test suite.

Signed-off-by: Yogesh Jangra <yogesh.jangra@intel.com>
---
 dep/softnic/rx_tx/pcap_files/in.txt  |  12 +
 dep/softnic/rx_tx/pcap_files/out.txt |  12 +
 dep/softnic/rx_tx/readme.txt         |   8 +
 dep/softnic/rx_tx/rx_tx.cli          |  21 ++
 dep/softnic/rx_tx/rx_tx.spec         |  19 ++
 dep/softnic/rx_tx/rx_tx_1.io         |  30 ++
 dep/softnic/rx_tx/rx_tx_2.io         |  30 ++
 test_plans/softnic_test_plan.rst     | 137 ++++-----
 tests/TestSuite_softnic.py           | 414 ++++++++++++++-------------
 9 files changed, 416 insertions(+), 267 deletions(-)
 create mode 100644 dep/softnic/rx_tx/pcap_files/in.txt
 create mode 100644 dep/softnic/rx_tx/pcap_files/out.txt
 create mode 100644 dep/softnic/rx_tx/readme.txt
 create mode 100644 dep/softnic/rx_tx/rx_tx.cli
 create mode 100644 dep/softnic/rx_tx/rx_tx.spec
 create mode 100644 dep/softnic/rx_tx/rx_tx_1.io
 create mode 100644 dep/softnic/rx_tx/rx_tx_2.io
  

Patch

diff --git a/dep/softnic/rx_tx/pcap_files/in.txt b/dep/softnic/rx_tx/pcap_files/in.txt
new file mode 100644
index 00000000..9b37ef2e
--- /dev/null
+++ b/dep/softnic/rx_tx/pcap_files/in.txt
@@ -0,0 +1,12 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 Intel Corporation
+#
+
+# text to pcap: text2pcap packet.txt packet.pcap
+# pcap to text: tcpdump -r packet.pcap -xx
+
+# Packet 0
+000000  00 11 22 33 44 55 00 66 77 88 99 aa 08 00 45 00
+000010  00 2e 00 01 00 00 40 06 4e b5 64 00 00 0a c8 00
+000020  00 0a 00 64 00 c8 00 00 00 00 00 00 00 00 50 02
+000030  20 00 59 93 00 00 58 58 58 58 58 58
\ No newline at end of file
diff --git a/dep/softnic/rx_tx/pcap_files/out.txt b/dep/softnic/rx_tx/pcap_files/out.txt
new file mode 100644
index 00000000..9b37ef2e
--- /dev/null
+++ b/dep/softnic/rx_tx/pcap_files/out.txt
@@ -0,0 +1,12 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 Intel Corporation
+#
+
+# text to pcap: text2pcap packet.txt packet.pcap
+# pcap to text: tcpdump -r packet.pcap -xx
+
+# Packet 0
+000000  00 11 22 33 44 55 00 66 77 88 99 aa 08 00 45 00
+000010  00 2e 00 01 00 00 40 06 4e b5 64 00 00 0a c8 00
+000020  00 0a 00 64 00 c8 00 00 00 00 00 00 00 00 50 02
+000030  20 00 59 93 00 00 58 58 58 58 58 58
\ No newline at end of file
diff --git a/dep/softnic/rx_tx/readme.txt b/dep/softnic/rx_tx/readme.txt
new file mode 100644
index 00000000..906bb615
--- /dev/null
+++ b/dep/softnic/rx_tx/readme.txt
@@ -0,0 +1,8 @@ 
+Test Case: rx_tx
+-----------------------
+Description:
+    This test is to verify packet transmission by the Soft NIC driver. In this test we have two pipeline connected using ring
+    port. First pipeline takes packet from physical port and put the packet in ring port. And second pipeline takes packet
+    from ring port and send the packet out to the physical port.
+Verification:
+    The received packets should be same as the transmitted packets.
diff --git a/dep/softnic/rx_tx/rx_tx.cli b/dep/softnic/rx_tx/rx_tx.cli
new file mode 100644
index 00000000..cbc0c58a
--- /dev/null
+++ b/dep/softnic/rx_tx/rx_tx.cli
@@ -0,0 +1,21 @@ 
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2022 Intel Corporation
+
+;
+; Pipeline code generation & shared object library build.
+;
+pipeline codegen /tmp/softnic/rx_tx/rx_tx.spec /tmp/firmware.c
+pipeline libbuild /tmp/firmware.c /tmp/firmware.so
+
+;
+; List of pipelines.
+;
+pipeline RX build lib /tmp/firmware.so io /tmp/softnic/rx_tx/rx_tx_1.io numa 0
+pipeline TX build lib /tmp/firmware.so io /tmp/softnic/rx_tx/rx_tx_2.io numa 0
+
+;
+; Pipelines-to-threads mapping. For the Soft NIC devices, the pipelines can be mapped to any of the
+; application service cores (see the -s <core_mask> argument):
+;
+thread 2 pipeline RX enable
+thread 2 pipeline TX enable
\ No newline at end of file
diff --git a/dep/softnic/rx_tx/rx_tx.spec b/dep/softnic/rx_tx/rx_tx.spec
new file mode 100644
index 00000000..106caae7
--- /dev/null
+++ b/dep/softnic/rx_tx/rx_tx.spec
@@ -0,0 +1,19 @@ 
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2022 Intel Corporation
+
+//
+// Meta-data.
+//
+struct metadata_t {
+	bit<32> port
+}
+
+metadata instanceof metadata_t
+
+//
+// Pipeline.
+//
+apply {
+	rx m.port
+	tx m.port
+}
diff --git a/dep/softnic/rx_tx/rx_tx_1.io b/dep/softnic/rx_tx/rx_tx_1.io
new file mode 100644
index 00000000..731f672c
--- /dev/null
+++ b/dep/softnic/rx_tx/rx_tx_1.io
@@ -0,0 +1,30 @@ 
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2022 Intel Corporation
+
+;
+; Pipeline input ports.
+;
+; Syntax:
+;
+;    port in <port_id> ethdev <ethdev_name> rxq <queue_id> bsz <burst_size>
+;    port in <port_id> ring <ring_name> bsz <burst_size>
+;    port in <port_id> source mempool <mempool_name> file <file_name> loop <n_loops> packets <n_pkts_max>
+;    port in <port_id> fd <file_descriptor> mtu <mtu> mempool <mempool_name> bsz <burst_size>
+;
+; Note: Customize the parameters below to match your setup.
+;
+port in 0 ethdev 0000:af:00.1 rxq 0 bsz 32
+
+;
+; Pipeline output ports.
+;
+; Syntax:
+;
+;    port out <port_id> ethdev <ethdev_name> txq <queue_id> bsz <burst_size>
+;    port out <port_id> ring <ring_name> bsz <burst_size>
+;    port out <port_id> sink file <file_name> | none
+;    port out <port_id> fd <file_descriptor> bsz <burst_size>
+;
+; Note: Customize the parameters below to match your setup.
+;
+port out 0 ring RXQ0 bsz 32
diff --git a/dep/softnic/rx_tx/rx_tx_2.io b/dep/softnic/rx_tx/rx_tx_2.io
new file mode 100644
index 00000000..d8c9ccbd
--- /dev/null
+++ b/dep/softnic/rx_tx/rx_tx_2.io
@@ -0,0 +1,30 @@ 
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2022 Intel Corporation
+
+;
+; Pipeline input ports.
+;
+; Syntax:
+;
+;    port in <port_id> ethdev <ethdev_name> rxq <queue_id> bsz <burst_size>
+;    port in <port_id> ring <ring_name> bsz <burst_size>
+;    port in <port_id> source mempool <mempool_name> file <file_name> loop <n_loops> packets <n_pkts_max>
+;    port in <port_id> fd <file_descriptor> mtu <mtu> mempool <mempool_name> bsz <burst_size>
+;
+; Note: Customize the parameters below to match your setup.
+;
+port in 0 ring TXQ0 bsz 32
+
+;
+; Pipeline output ports.
+;
+; Syntax:
+;
+;    port out <port_id> ethdev <ethdev_name> txq <queue_id> bsz <burst_size>
+;    port out <port_id> ring <ring_name> bsz <burst_size>
+;    port out <port_id> sink file <file_name> | none
+;    port out <port_id> fd <file_descriptor> bsz <burst_size>
+;
+; Note: Customize the parameters below to match your setup.
+;
+port out 0 ethdev 0000:af:00.1 txq 0 bsz 32
diff --git a/test_plans/softnic_test_plan.rst b/test_plans/softnic_test_plan.rst
index 84d34f63..a6f8348a 100644
--- a/test_plans/softnic_test_plan.rst
+++ b/test_plans/softnic_test_plan.rst
@@ -12,95 +12,84 @@  is configurable through firmware (DPDK Packet Framework script).
 
 Prerequisites
 =============
-1. The DUT must have one 10G Ethernet port connected to a port on tester
-   that are controlled by the traffic generator::
+The DUT must have atleast one 10G Ethernet ports connected to one port on
+Tester.::
 
     dut_port_0 <---> tester_port_0
 
-   Assume the DUT 10G Ethernet port's pci device id is as the following::
+Assume DUT 10G Ethernet ports' pci device id is as the following::
 
-    dut_port_0 : "0000:05:00.0"
+    dut_port_0 : "0000:af:00.1"
 
-   Bind it to dpdk igb_uio driver::
+Bind them to dpdk vfio-pci driver::
 
-    ./usertools/dpdk-devbind.py -b igb_uio 05:00.0
+    ./usertools/dpdk-devbind.py -b vfio-pci 0000:af:00.1
 
-2. Change ./drivers/net/softnic/firmware.cli to meet the specific test environment.
-   Change the DUT port info to the actual port info in your test environment::
-
-    link LINK dev 0000:05:00.0
-
-3. Start softnic with following command line::
-
-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \
-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/firmware.cli,cpu_id=1,conn_port=8086' \
-    -- -i --forward-mode=softnic --portmask=0x2
-    testpmd> start
-
-   Set the thread id consistent to the service core::
-
-    thread 2 pipeline PIPELINE0 enable
-
-Test Case 1: softnic performance
-================================
-1. Start softnic::
-
-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \
-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/firmware.cli,cpu_id=1,conn_port=8086' \
-    -- -i --forward-mode=softnic --portmask=0x2
-    testpmd> start
-
-2. Send packet at line rate from traffic generator (IXIA or other) with packet size from 64~1518B.
-3. Check performance number is same as the physical NIC's performance number, no performance drop.
-
-Test Case 2: shaping for pipe
-=============================
-1. The specifications of the default Hierarchical Scheduler are as follows:
-
-    Root node (x1, level 0)
-    Subport node (x1, level 1)
-    Pipe node (x4096, level 2)
-    Traffic Class node (x16348, level 3)
-    Queue node (x65536, level 4)
-
-2. Start softnic with the default hierarchy Qos::
-
-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \
-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/tm_firmware.cli,cpu_id=1,conn_port=8086' \
-    -- -i --forward-mode=softnic --portmask=0x2
-    testpmd> start
-
-3. Send per flow traffic with 100% line rate, verify output flow rate is 1/4096 subport rate.
-
-Test Case 3: NAT
+Supporting Files
 ================
-1. Set SNAT with proto tcp test, edit nat_firmware.cli to change "table action" as below::
-
-    table action profile AP0 ipv4 offset 270 fwd nat src proto tcp
-
-(a). Start softnic::
-
-    ./x86_64-native-linuxapp-gcc/app/dpdk-testpmd -c 0x7 -s 0x4 -n 4 \
-    --vdev 'net_softnic0,firmware=./drivers/net/softnic/nat_firmware.cli,cpu_id=1,conn_port=8086' \
-    -- -i --forward-mode=softnic --portmask=0x2
+All the supporting files for this test suite are maintained inside softnic folder, and softnic folder
+is present in the {DTS_SRC_DIR}/dep directory.
+
+Directory Structure of Each Test Case
+=====================================
+Within {DTS_SRC_DIR}/dep/softnic, all files related to a particular test case are maintained
+in a separate directory of which the directory structure is shown below::
+
+    test_case_name [directory]
+        test_case_name.spec
+        test_case_name_x.io [x: 1 to n; depending on the test case]
+        test_case_name.cli
+        table.txt [applicable for test cases requiring it]
+        readme.txt
+        pcap_files [subdirectory]
+            in.txt
+            out.txt
+
+For an example, files related to rx_tx test case are maintained as shown below::
+
+    rx_tx [directory]
+        rx_tx.spec
+        rx_tx_1.io
+        rx_tx_2.io
+        rx_tx.cli
+        readme.txt
+        pcap_files [subdirectory]
+            in.txt
+            out.txt
+
+Template of each Test Case
+===========================
+1. Edit test_case_name/test_case_name.io:
+   change pci device id of port in and port out to pci device id of dut_port_0
+
+2. Run softnic driver as the following::
+
+    x86_64-native-linuxapp-gcc/app/dpdk-testpmd -l 0-2 -n 4  --file-prefix=dpdk_2374972_20221107140937   -s 0x4 -a 0000:af:00.1 \
+    --vdev 'net_softnic0,firmware=/tmp/softnic/rx_tx/firmware.cli,cpu_id=1,conn_port=8086' -- -i --portmask=0x2
     testpmd> start
 
-(b). Sent packet, verify the received packet's ipaddr and port was changed as expected.
+3. Send packets at tester side using scapy. The packets to be sent are maintained in softnic/test_case_name/pcap_files/in.txt
 
-2. Set DNAT with proto tcp test, edit nat_firmware.cli to change "table action" as below::
+4. Verify the packets received using tcpdump. The expected packets are maintained in softnic/test_case_name/pcap_files/out.txt
 
-    table action profile AP0 ipv4 offset 270 fwd nat dst proto tcp
+5. Test case is considered as successful if the received packets and the expected packets match for all the port combinations used.
 
-   Then re-run step (a) & step (b).
-
-3. Set SNAT with proto udp test, edit nat_firmware.cli to change "table action" as below::
+Example Test Case : rx_tx
+================================
+1. Edit rx_tx/rx_tx_1.io:
+   change pci device id of port in to pci device id of dut_port_0
+   Edit rx_tx/rx_tx_2.io:
+   change pci device id of port out to pci device id of dut_port_0
 
-    table action profile AP0 ipv4 offset 270 fwd nat src proto udp
+2. Start softnic::
 
-   Then re-run step (a) & step (b).
+    x86_64-native-linuxapp-gcc/app/dpdk-testpmd -l 0-2 -n 4  --file-prefix=dpdk_2374972_20221107140937 \
+    -s 0x4 -a 0000:af:00.1 --vdev 'net_softnic0,firmware=/tmp/softnic/rx_tx/firmware.cli,cpu_id=1, \
+    conn_port=8086' -- -i --portmask=0x2
+    testpmd> start
 
-4. Set DNAT with proto udp test, edit nat_firmware.cli to change "table action" as below::
+3. Send packets at tester side using scapy. The packets to be sent are maintained in softnic/rx_tx/pcap_files/in.txt
 
-    table action profile AP0 ipv4 offset 270 fwd nat dst proto udp
+4. Verify the packets received using tcpdump. The expected packets are maintained in softnic/rx_tx/pcap_files/out.txt
 
-   Then re-run step (a) & step (b).
+5. Test rx_tx is considered as successful if the received packets and the expected packets match for all port combinations used.
\ No newline at end of file
diff --git a/tests/TestSuite_softnic.py b/tests/TestSuite_softnic.py
index e379125d..94814bd7 100644
--- a/tests/TestSuite_softnic.py
+++ b/tests/TestSuite_softnic.py
@@ -7,233 +7,263 @@  DPDK Test suite.
 Test softnic API in DPDK.
 """
 
+import itertools
 import os
 import re
 import string
 import time
+import traceback
+from time import sleep
+
+import scapy.layers.inet
+from scapy.arch import get_if_hwaddr
+from scapy.packet import Raw, bind_layers
+from scapy.route import *
+from scapy.sendrecv import sendp, sniff
+from scapy.utils import hexstr, rdpcap, wrpcap
 
 import framework.utils as utils
-from framework.pktgen import PacketGeneratorHelper
 from framework.pmd_output import PmdOutput
-from framework.settings import HEADER_SIZE
 from framework.test_case import TestCase
 
 
 class TestSoftnic(TestCase):
-    def set_up_all(self):
+    def pair_hex_digits(self, iterable, count, fillvalue=None):
+        args = [iter(iterable)] * count
+        return itertools.zip_longest(*args, fillvalue=fillvalue)
+
+    def get_flow_direction_param_of_tcpdump(self):
+        """
+        get flow dirction param depend on tcpdump version
+        """
+        param = ""
+        direct_param = r"(\s+)\[ (\S+) in\|out\|inout \]"
+        out = self.tester.send_expect("tcpdump -h", "# ", trim_whitespace=False)
+        for line in out.split("\n"):
+            m = re.match(direct_param, line)
+            if m:
+                opt = re.search("-Q", m.group(2))
+                if opt:
+                    param = "-Q" + " in"
+                else:
+                    opt = re.search("-P", m.group(2))
+                    if opt:
+                        param = "-P" + " in"
+        if len(param) == 0:
+            self.logger.info("tcpdump not support direction choice!!!")
+        return param
+
+    def tcpdump_start_sniff(self, interface, filters=""):
+        """
+        Starts tcpdump in the background to sniff packets that received by interface.
+        """
+        cmd = "rm -f /tmp/tcpdump_{0}.pcap".format(interface)
+        self.tester.send_expect(cmd, "#")
+        cmd = "tcpdump -nn -e {0} -w /tmp/tcpdump_{1}.pcap -i {1} {2} -Q in 2>/tmp/tcpdump_{1}.out &".format(
+            self.param_flow_dir, interface, filters
+        )
+        self.tester.send_expect(cmd, "# ")
+
+    def tcpdump_stop_sniff(self):
+        """
+        Stops the tcpdump process running in the background.
+        """
+        self.tester.send_expect("killall tcpdump", "# ")
+        # For the [pid]+ Done tcpdump... message after killing the process
+        sleep(1)
+        self.tester.send_expect('echo "Cleaning buffer"', "# ")
+        sleep(1)
+
+    def compare_packets(self, in_file, out_file, all_pkts):
+        """
+        Flag all_pkt is zero, then it compares small packet(size upto 48 bytes).
+        Flag all_pkt is non-zero, then it compares all packets of out_file.
+        """
+        if all_pkts == 0:
+            cmd = "diff -sqw <(head -n 11 {}) <(head -n 11 {})".format(
+                in_file, out_file
+            )
+        else:
+            cmd = "diff -sqw {} {}".format(in_file, out_file)
+        return self.tester.send_command(cmd, timeout=0.5)
+
+    def convert_tcpdump_to_text2pcap(self, in_filename, out_filename):
+        with open(in_filename) as input, open(out_filename, "w") as output:
+            output.write("# SPDX-License-Identifier: BSD-3-Clause\n")
+            output.write("# Copyright(c) 2022 Intel Corporation\n")
+            output.write("#\n\n")
+            output.write("# text to pcap: text2pcap packet.txt packet.pcap\n")
+            output.write("# pcap to text: tcpdump -r packet.pcap -xx\n\n")
+
+            i = 0
+            for line in input:
+                time = self.pkt_timestamp.match(line)
+                if time:
+                    output.write("# Packet {}\n".format(i))
+                    i += 1
+                    continue
+                payload = self.pkt_content.match(line)
+                if payload:
+                    address = payload.group(1)
+                    hex_data = payload.group(2).replace(" ", "")
+                    hex_data = " ".join(
+                        "".join(part) for part in self.pair_hex_digits(hex_data, 2, " ")
+                    )
+                    output.write("{:0>6}  {:<47}\n".format(address, hex_data))
+
+    def send_and_sniff(
+        self, from_port, to_port, in_pcap, out_pcap, filters, all_pkts=0
+    ):
+        self.tester.send_expect("rm -f /tmp/*.txt /tmp/*.pcap /tmp/*.out", "# ")
+        tx_count = len(from_port)
+        rx_count = len(to_port)
+        tx_port, rx_port, tx_inf, rx_inf = ([] for i in range(4))
+
+        for i in range(tx_count):
+            tx_port.append(self.tester.get_local_port(self.dut_ports[from_port[i]]))
+            tx_inf.append(self.tester.get_interface(tx_port[i]).strip())
+
+        for i in range(rx_count):
+            rx_port.append(self.tester.get_local_port(self.dut_ports[to_port[i]]))
+            rx_inf.append(self.tester.get_interface(rx_port[i]).strip())
+            self.tcpdump_start_sniff(rx_inf[i], filters[i])
+
+        self.tester.scapy_foreground()
+        for i in range(tx_count):
+            self.tester.send_expect(
+                "text2pcap -q {} /tmp/tx_{}.pcap".format(
+                    self.src_path + in_pcap[i], tx_inf[i]
+                ),
+                "# ",
+            )
+            self.tester.scapy_append(
+                'pkt = rdpcap("/tmp/tx_{}.pcap")'.format(tx_inf[i])
+            )
+
+            self.tester.scapy_append(
+                'sendp(pkt, iface="{}", count=32)'.format(tx_inf[i])
+            )
+
+        self.tester.scapy_execute()
+        self.tcpdump_stop_sniff()
+        mismatch_count = 0
+
+        for i in range(rx_count):
+            self.tester.send_expect(
+                "tcpdump -n -r /tmp/tcpdump_{}.pcap -xx > /tmp/packet_rx.txt".format(
+                    rx_inf[i]
+                ),
+                "# ",
+            )
+            self.convert_tcpdump_to_text2pcap(
+                "/tmp/packet_rx.txt", "/tmp/packet_rx_rcv_{}.txt".format(rx_inf[i])
+            )
+            out = self.compare_packets(
+                "/tmp/packet_rx_rcv_{}.txt".format(rx_inf[i]),
+                self.src_path + out_pcap[i],
+                all_pkts,
+            )
+            if "are identical" not in out:
+                return False
+        return True
 
+    def set_up_all(self):
         # Based on h/w type, choose how many ports to use
-        ports = self.dut.get_ports()
-        self.dut_ports = self.dut.get_ports(self.nic)
+        self.dut_ports = self.dut.get_ports()
 
         # Verify that enough ports are available
-        self.verify(len(ports) >= 1, "Insufficient ports for testing")
-        self.def_driver = self.dut.ports_info[ports[0]]["port"].get_nic_driver()
-        self.ports_socket = self.dut.get_numa_id(ports[0])
+        self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing")
+        self.def_driver = self.dut.ports_info[self.dut_ports[0]][
+            "port"
+        ].get_nic_driver()
+        self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])
         # Verify that enough threads are available
         cores = self.dut.get_core_list("1S/1C/1T")
         self.verify(cores is not None, "Insufficient cores for speed testing")
-        global P0
-        P0 = ports[0]
-
-        self.txItf = self.tester.get_interface(self.tester.get_local_port(P0))
-        self.dmac = self.dut.get_mac_address(P0)
-        self.headers_size = HEADER_SIZE["eth"] + HEADER_SIZE["ip"] + HEADER_SIZE["udp"]
-
-        # need change config files
-        self.root_path = "/tmp/"
-        self.firmware = r"dep/firmware.cli"
-        self.tm_firmware = r"dep/tm_firmware.cli"
-        self.nat_firmware = r"dep/nat_firmware.cli"
-        self.dut.session.copy_file_to(self.firmware, self.root_path)
-        self.dut.session.copy_file_to(self.tm_firmware, self.root_path)
-        self.dut.session.copy_file_to(self.nat_firmware, self.root_path)
-        self.eal_param = " -a %s" % self.dut.ports_info[0]["pci"]
+        self.param_flow_dir = self.get_flow_direction_param_of_tcpdump()
+
+        # setting up source and destination location
+        self.dst_path = "/tmp/"
+        FILE_DIR = os.path.dirname(os.path.abspath(__file__)).split(os.path.sep)
+        self.src_path = os.path.sep.join(FILE_DIR[:-1]) + "/dep/"
+        SOFTNIC_TAR_FOLDER = self.src_path + "softnic"
+
+        # copy dependancies to the DUT
+        self.tester.send_expect("rm -rf /tmp/softnic.tar.gz", "# ")
+        self.tester.send_expect(
+            "tar -zcf /tmp/softnic.tar.gz --absolute-names {}".format(self.src_path),
+            "# ",
+            20,
+        )
+        self.dut.send_expect("rm -rf /tmp/softnic.tar.gz /tmp/softnic", "# ", 20)
+        self.dut.session.copy_file_to("/tmp/softnic.tar.gz", self.dst_path)
+        self.dut.send_expect(
+            "tar -zxf /tmp/softnic.tar.gz --strip-components={} --absolute-names --directory /tmp".format(
+                SOFTNIC_TAR_FOLDER.count("/") - 1
+            ),
+            "# ",
+            20,
+        )
+
+        self.eal_param = " ".join(
+            " -a " + port_info["pci"] for port_info in self.dut.ports_info
+        )
         self.path = self.dut.apps_name["test-pmd"]
         self.pmdout = PmdOutput(self.dut)
+
+        # create packet matching regular expression
+        self.pkt_timestamp = re.compile(r"\d{2}\:\d{2}\:\d{2}\.\d{6}")
+        self.pkt_content = re.compile(r"\t0x([0-9a-fA-F]+):  ([0-9a-fA-F ]+)")
+
         # get dts output path
         if self.logger.log_path.startswith(os.sep):
             self.output_path = self.logger.log_path
         else:
             cur_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
             self.output_path = os.sep.join([cur_path, self.logger.log_path])
-        # create an instance to set stream field setting
-        self.pktgen_helper = PacketGeneratorHelper()
-        self.dut.bind_interfaces_linux(self.drivername, [ports[0]])
+        # bind the ports
+        self.dut.bind_interfaces_linux(self.drivername, [self.dut_ports[0]])
 
     def set_up(self):
         """
         Run before each test case.
         """
 
-    def change_config_file(self, file_name):
-        self.dut.send_expect(
-            "sed -i -e '4c link LINK0 dev %s' %s"
-            % (self.dut.ports_info[0]["pci"], self.root_path + file_name),
-            "#",
-        )
-        self.dut.send_expect(
-            "sed -i -e 's/thread [0-9]/thread 2/g' %s" % self.root_path + file_name, "#"
-        )
+    def run_test_pmd(self, file_name):
+        try:
+            cmd = 'test -f {} && echo "File exists!"'.format(file_name)
+            self.dut.send_expect(cmd, "File exists!", 1)
 
-    def test_perf_softnic_performance(self):
-        self.frame_size = [64, 128, 256, 512, 1024, 1280, 1518]
-        self.change_config_file("firmware.cli")
-        # 10G nic pps(M)
-        expect_pps = [14, 8, 4, 2, 1, 0.9, 0.8]
-
-        self.pmdout.start_testpmd(
-            list(range(3)),
-            "--forward-mode=softnic --portmask=0x2",
-            eal_param="-s 0x4 %s --vdev 'net_softnic0,firmware=/tmp/%s,cpu_id=1,conn_port=8086'"
-            % (self.eal_param, "firmware.cli"),
-        )
-        self.dut.send_expect("start", "testpmd>")
-        rx_port = self.tester.get_local_port(0)
-        tx_port = self.tester.get_local_port(0)
-        n = 0
-        for frame in self.frame_size:
-            payload_size = frame - self.headers_size
-            tgen_input = []
-            pcap = os.sep.join([self.output_path, "test.pcap"])
-            pkt = "Ether(dst='%s')/IP()/UDP()/Raw(load='x'*%d)" % (
-                self.dmac,
-                payload_size,
+            self.pmdout.start_testpmd(
+                list(range(3)),
+                "--portmask=0x2",
+                eal_param="-s 0x4 %s --vdev 'net_softnic0,firmware=%s,cpu_id=1,conn_port=8086'"
+                % (self.eal_param, file_name),
             )
-            self.tester.scapy_append('wrpcap("%s", [%s])' % (pcap, pkt))
-            tgen_input.append((tx_port, rx_port, pcap))
-            self.tester.scapy_execute()
-            # clear streams before add new streams
-            self.tester.pktgen.clear_streams()
-            # run packet generator
-            streams = self.pktgen_helper.prepare_stream_from_tginput(
-                tgen_input, 100, None, self.tester.pktgen
-            )
-            _, pps = self.tester.pktgen.measure_throughput(stream_ids=streams)
-            pps = pps / 1000000.0
-            self.verify(pps > 0, "No traffic detected")
-            self.verify(pps > expect_pps[n], "No traffic detected")
-            n = n + 1
-
-    def test_perf_shaping_for_pipe(self):
-        self.change_config_file("tm_firmware.cli")
-        self.pmdout.start_testpmd(
-            list(range(3)),
-            "--forward-mode=softnic --portmask=0x2",
-            eal_param="-s 0x4 %s --vdev 'net_softnic0,firmware=/tmp/%s,cpu_id=1,conn_port=8086'"
-            % (self.eal_param, "tm_firmware.cli"),
-        )
+        except Exception:
+            trace = traceback.format_exc()
+            self.logger.error("Error while running testpmd:\n" + trace)
+
+    def test_rx_tx(self):
+        cli_file = "/tmp/softnic/rx_tx/rx_tx.cli"
+        self.run_test_pmd(cli_file)
+        sleep(5)
         self.dut.send_expect("start", "testpmd>")
-        rx_port = self.tester.get_local_port(0)
-        pkts = [
-            "Ether(dst='%s')/IP(dst='100.0.0.0')/UDP()/Raw(load='x'*(64 - %s))",
-            "Ether(dst='%s')/IP(dst='100.0.15.255')/UDP()/Raw(load='x'*(64 - %s))",
-            "Ether(dst='%s')/IP(dst='100.0.4.0')/UDP()/Raw(load='x'*(64 - %s))",
-        ]
-        except_bps_range = [1700000, 2000000]
-
-        for i in range(3):
-            tgen_input = []
-            pcap = os.sep.join([self.output_path, "test.pcap"])
-            pkt = pkts[i] % (self.dmac, self.headers_size)
-            self.tester.scapy_append('wrpcap("%s", [%s])' % (pcap, pkt))
-            self.tester.scapy_execute()
-            if i == 2:
-                for j in range(16):
-                    pk = (
-                        "Ether(dst='%s')/IP(dst='100.0.15.%d')/UDP()/Raw(load='x'*(64 - %s))"
-                        % (self.dmac, j, self.headers_size)
-                    )
-                    self.tester.scapy_append(
-                        'wrpcap("%s/test_%d.pcap", [%s])' % (self.output_path, j, pk)
-                    )
-                    self.tester.scapy_execute()
-                    tgen_input.append(
-                        (rx_port, rx_port, "%s/test_%d.pcap" % (self.output_path, j))
-                    )
-            else:
-                tgen_input.append((rx_port, rx_port, pcap))
-            # clear streams before add new streams
-            self.tester.pktgen.clear_streams()
-            # run packet generator
-            streams = self.pktgen_helper.prepare_stream_from_tginput(
-                tgen_input, 100, None, self.tester.pktgen
-            )
-            bps, pps = self.tester.pktgen.measure_throughput(stream_ids=streams)
-            if i == 2:
-                self.verify(
-                    except_bps_range[1] * 16 > bps > except_bps_range[0] * 16,
-                    "No traffic detected",
-                )
-            else:
-                self.verify(
-                    except_bps_range[1] > bps > except_bps_range[0],
-                    "No traffic detected",
-                )
-
-    def test_nat(self):
-        self.change_config_file("nat_firmware.cli")
-        expect_ips = ["192.168.0.1.5000", "192.168.0.2.5001"]
-        ips = ["100.0.0.1", "100.0.0.2"]
-        pkt_location = ["src", "dst"]
-        pkt_type = ["tcp", "udp"]
-        for t in pkt_type:
-            for i in range(2):
-                self.dut.send_expect(
-                    "sed -i -e '12c table action profile AP0 ipv4 offset 270 fwd nat %s proto %s' %s"
-                    % (pkt_location[i], t, self.root_path + "nat_firmware.cli"),
-                    "#",
-                )
-                self.pmdout.start_testpmd(
-                    list(range(3)),
-                    "--forward-mode=softnic --portmask=0x2",
-                    eal_param="-s 0x4 %s --vdev 'net_softnic0,firmware=/tmp/%s,cpu_id=1,conn_port=8086'"
-                    % (self.eal_param, "nat_firmware.cli"),
-                )
-                if self.nic in [
-                    "ICE_100G-E810C_QSFP",
-                    "ICE_25G-E810C_SFP",
-                    "ICE_25G-E810_XXV_SFP",
-                ]:
-                    self.dut.send_expect("set fwd mac", "testpmd>")
-                self.dut.send_expect("start", "testpmd>")
-                # src ip tcp
-                for j in range(2):
-                    out = self.scapy_send_packet(pkt_location[i], ips[j], t)
-                    self.verify(expect_ips[j] in out, "fail to receive expect packet")
-                self.dut.send_expect("quit", "# ")
-                time.sleep(1)
-
-    def scapy_send_packet(self, pkt_location, ip, pkt_type):
-        self.tester.scapy_foreground()
-        pkt = "Ether(dst='%s')/IP(dst='%s')/" % (self.dmac, ip)
-        if pkt_type == "tcp":
-            pkt = pkt + "TCP()/Raw(load='x'*20)"
-        else:
-            pkt = pkt + "UDP()/Raw(load='x'*20)"
 
-        self.tester.scapy_append('sendp([%s], iface="%s")' % (pkt, self.txItf))
-        self.start_tcpdump(self.txItf)
-        self.tester.scapy_execute()
-        out = self.get_tcpdump_package()
-        return out
-
-    def get_tcpdump_package(self):
-        time.sleep(4)
-        self.tester.send_expect("killall tcpdump", "#")
-        out = self.tester.send_expect(
-            "tcpdump -A -nn -e -vv -r getPackageByTcpdump.cap |grep '192.168'", "#"
-        )
-        return out
+        in_pcap = ["softnic/rx_tx/pcap_files/in.txt"]
+        out_pcap = ["softnic/rx_tx/pcap_files/out.txt"]
+        filters = ["tcp"]
+        tx_port = [0]
+        rx_port = [0]
+        result = self.send_and_sniff(tx_port, rx_port, in_pcap, out_pcap, filters)
+        if result:
+            self.dut.send_expect("stop", "testpmd>")
+        else:
+            self.verify(False, "Output pcap files mismatch error")
 
-    def start_tcpdump(self, rxItf):
-        self.tester.send_expect("rm -rf getPackageByTcpdump.cap", "#")
-        self.tester.send_expect(
-            "tcpdump -A -nn -e -vv -w getPackageByTcpdump.cap -i %s 2> /dev/null& "
-            % self.txItf,
-            "#",
-        )
-        time.sleep(4)
+        """
+        Add new test cases here.
+        """
 
     def tear_down(self):
         """
@@ -245,6 +275,4 @@  class TestSoftnic(TestCase):
         """
         Run after each test suite.
         """
-        self.dut.bind_interfaces_linux(
-            driver=self.def_driver, nics_to_bind=self.dut.get_ports()
-        )
+        self.dut.kill_all()