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 1DDE8A034C; Wed, 21 Dec 2022 07:30:34 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F1DCE40698; Wed, 21 Dec 2022 07:30:33 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id 1D5FD40684 for ; Wed, 21 Dec 2022 07:30:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1671604230; x=1703140230; h=from:to:cc:subject:date:message-id; bh=Iuh9H0i9EQlYC1sazm2lgV+2WpAXVrcBmePD8T9hiC8=; b=Qj+0c8ud8AEthw7NK0m+Xk9UHqQWfo966bKmxqWED4s0hmnbi3eBwrbA 9lSS+N1FCukzehDg3WQ9CmUByLpvHnXXhHNYECZWcZVtXnRGmf3QZ4FZz LPRvjMnf0NRDkDlXFtQBf8cIW+fLbl3qs2g57MdjKaNVYpTCL/lA+kJ3a K62N/uO+NUa9J9BdVb30JFXH3WXSZt3DMn1zzp2iXSseW0prW1J5Gz8VN PtrPwaLd2tgXM00SI+4cHDShX0R8IliMSVj36V3bHFNpB4l3MtFl2tfuM ig4Kop/o8PQPeVXljqCNas8aSHXSO1k8msYy16nychM851eIe5XXrWwQC w==; X-IronPort-AV: E=McAfee;i="6500,9779,10567"; a="319854006" X-IronPort-AV: E=Sophos;i="5.96,261,1665471600"; d="scan'208";a="319854006" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2022 22:30:28 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10567"; a="825533417" X-IronPort-AV: E=Sophos;i="5.96,261,1665471600"; d="scan'208";a="825533417" Received: from unknown (HELO localhost.localdomain) ([10.239.252.99]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2022 22:30:26 -0800 From: Lingli Chen To: dts@dpdk.org Cc: zhiminx.huang@intel.com, Lingli Chen Subject: [dts][PATCH V1] tests/kni: removed suit from DPDK 22.11 Date: Wed, 21 Dec 2022 00:32:35 -0500 Message-Id: <20221221053235.21806-1-linglix.chen@intel.com> X-Mailer: git-send-email 2.17.1 X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org The KNI example application has been removed from DPDK 22.11. according to dpdk commit: 3aaa469 (examples/kni: remove deprecated example) Signed-off-by: Lingli Chen --- test_plans/index.rst | 1 - test_plans/kni_test_plan.rst | 587 ------------- tests/TestSuite_kni.py | 1568 ---------------------------------- 3 files changed, 2156 deletions(-) delete mode 100644 test_plans/kni_test_plan.rst delete mode 100644 tests/TestSuite_kni.py diff --git a/test_plans/index.rst b/test_plans/index.rst index 4e0e8133..d8c23bfb 100644 --- a/test_plans/index.rst +++ b/test_plans/index.rst @@ -91,7 +91,6 @@ The following are the test plans for the DPDK DTS automated test system. ipv4_reassembly_test_plan ixgbe_vf_get_extra_queue_information_test_plan jumboframes_test_plan - kni_test_plan l2fwd_cryptodev_func_test_plan l2fwd_test_plan l2tp_esp_coverage_test_plan diff --git a/test_plans/kni_test_plan.rst b/test_plans/kni_test_plan.rst deleted file mode 100644 index bf69e590..00000000 --- a/test_plans/kni_test_plan.rst +++ /dev/null @@ -1,587 +0,0 @@ -.. SPDX-License-Identifier: BSD-3-Clause - Copyright(c) 2010-2017 Intel Corporation - -================================ -Kernel NIC Interface (KNI) Tests -================================ - -Description -=========== - -This document provides the plan for testing the Kernel NIC Interface -application with support of rte_kni kernel module. -Kernel NIC Interface is a DPDK alternative solution to the existing linux -tun-tap interface for the exception path. Kernel NIC Interface allows the -standard Linux net tools(ethtool/ifconfig/tcpdump) to facilitate managing the -DPDK port. At the same time, it add an interface with the kernel net stack. -The test supports Multi-Thread KNI. - -All kni model parameter detail info on user guides:http://dpdk.org/doc/guides/sample_app_ug/kernel_nic_interface.html - -The ``rte_kni`` kernel module can be installed by a ``lo_mode`` parameter. - -loopback disabled:: - - insmod rte_kni.ko - insmod rte_kni.ko "lo_mode=lo_mode_none" - insmod rte_kni.ko "lo_mode=unsupported string" - -loopback mode=lo_mode_ring enabled:: - - insmod rte_kni.ko "lo_mode=lo_mode_ring" - -loopback mode=lo_mode_ring_skb enabled:: - - insmod rte_kni.ko "lo_mode=lo_mode_ring_skb" - -The ``rte_kni`` kernel module can also be installed by a ``kthread_mode`` -parameter. This parameter is ``single`` by default. - -kthread single:: - - insmod rte_kni.ko - insmod rte_kni.ko "kthread_mode=single" - -kthread multiple:: - - insmod rte_kni.ko - insmod rte_kni.ko "kthread_mode=multiple" - - -The ``kni`` application is run with EAL parameters and parameters for the -application itself. For details about the EAL parameters, see the relevant -DPDK **Getting Started Guide**. This application supports two parameters for -itself. - -- ``--config="(port id, rx lcore, tx lcore, kthread lcore, kthread lcore, ...)"``: - Port and cores selection. Kernel threads are ignored if ``kthread_mode`` - is not ``multiple``. - -ports cores:: - - e.g.: - - --config="(0,1,2),(1,3,4)" No kernel thread specified. - --config="(0,1,2,21),(1,3,4,23)" One kernel thread in use. - --config="(0,1,2,21,22),(1,3,4,23,25) Two kernel threads in use. - -- ``-P``: Promiscuous mode. This is off by default. - -Prerequisites -============= - -If using vfio the kernel must be >= 3.6+ and VT-d must be enabled in bios.When -using vfio, use the following commands to load the vfio driver and bind it -to the device under test:: - - modprobe vfio - modprobe vfio-pci - usertools/dpdk-devbind.py --bind=vfio-pci device_bus_id - -The DUT has at least 2 DPDK supported IXGBE/I40E/ICE/IGC NIC ports. - -The DUT has to be able to install rte_kni kernel module and launch kni -application with a default configuration (This configuration may change form a -system to another):: - - rmmod rte_kni - rmmod igb_uio - insmod ./x86_64-default-linuxapp-gcc/kmod/igb_uio.ko - insmod ./x86_64-default-linuxapp-gcc/kmod/rte_kni.ko - .//examples/dpdk-kni -c 0xa0001e -n 4 -- -P -p 0x3 --config="(0,1,2,21),(1,3,4,23)" & - -Case config:: - - For enable KNI features, need build DPDK with '-Denable_kmods=True'. - -Test Case: ifconfig testing -=========================== - -Launch the KNI application. Assume that ``port 2 and 3`` are used to this -application. Cores 1 and 2 are used to read from NIC, cores 2 and 4 are used -to write to NIC, threads 21 and 23 are used by the kernel. - -As the kernel module is installed using ``"kthread_mode=single"`` the core -affinity is set using ``taskset``:: - - .//examples/dpdk-kni -c 0xa0001e -n 4 -- -P -p 0xc --config="(2,1,2,21),(3,3,4,23)" - - -Verify whether the interface has been added:: - - ifconfig -a - - -If the application is launched successfully, it will add two interfaces in -kernel net stack named ``vEth2_0``, ``vEth3_0``. - -Interface name start with ``vEth`` followed by the port number and an -additional incremental number depending on the number of kernel threads:: - - vEth2_0: flags=4098 mtu 1500 - ether 00:00:00:00:00:00 txqueuelen 1000 (Ethernet) - RX packets 14 bytes 2098 (2.0 KiB) - RX errors 0 dropped 10 overruns 0 frame 0 - TX packets 0 bytes 0 (0.0 B) - TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - - vEth3_0: flags=4098 mtu 1500 - ether 00:00:00:00:00:00 txqueuelen 1000 (Ethernet) - RX packets 13 bytes 1756 (1.7 KiB) - RX errors 0 dropped 10 overruns 0 frame 0 - TX packets 0 bytes 0 (0.0 B) - TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - - - -Verify whether ifconfig can set Kernel NIC Interface up:: - - ifconfig vEth2_0 up - -Now ``vEth2_0`` is up and has IPv6 address:: - - vEth2_0: flags=4163 mtu 1500 - inet6 fe80::92e2:baff:fe37:92f8 prefixlen 64 scopeid 0x20 - ether 90:e2:ba:37:92:f8 txqueuelen 1000 (Ethernet) - RX packets 30 bytes 4611 (4.5 KiB) - RX errors 0 dropped 21 overruns 0 frame 0 - TX packets 6 bytes 468 (468.0 B) - TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - - -Verify whether ifconfig can add an ipv6 address:: - - ifconfig vEth2_0 add fe80::1 - -``vEth2_0`` has added ipv6 address:: - - 29: vEth2_0: mtu 1500 qlen 1000 - inet6 fe80::1/128 scope link - valid_lft forever preferred_lft forever - inet6 fe80::92e2:baff:fe37:92f8/64 scope link - valid_lft forever preferred_lft forever - - -Delete the IPv6 address:: - - ifconfig vEth2_0 del fe80::1 - -The port deletes it:: - - 29: vEth2_0: mtu 1500 qlen 1000 - inet6 fe80::92e2:baff:fe37:92f8/64 scope link - valid_lft forever preferred_lft forever - -Set MTU parameter:: - - ifconfig vEth2_0 mtu 1300 - -``vEth2_0`` changes the mtu parameter:: - - 29: vEth2_0: mtu 1300 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 1000 - link/ether 90:e2:ba:37:92:f8 brd ff:ff:ff:ff:ff:ff - -Verify whether ifconfig can set ip address:: - - ifconfig vEth2_0 192.168.2.1 netmask 255.255.255.192 - ip -family inet address show dev vEth2_0 - -``vEth2_0`` has IP address and netmask now:: - - 29: vEth2_0: mtu 1300 qdisc pfifo_fast state UNKNOWN qlen 1000 - inet 192.168.2.1/26 brd 192.168.2.63 scope global vEth2_0 - -Verify whether ifconfig can set ``vEth2_0`` down:: - - ifconfig vEth2_0 down - ifconfig vEth2_0 - -``vEth2_0`` is down and no ipv6 address:: - - vEth2_0: flags=4098 mtu 1300 - inet 192.168.2.1 netmask 255.255.255.192 broadcast 192.168.2.63 - ether 90:e2:ba:37:92:f8 txqueuelen 1000 (Ethernet) - RX packets 70 bytes 12373 (12.0 KiB) - RX errors 0 dropped 43 overruns 0 frame 0 - TX packets 25 bytes 4132 (4.0 KiB) - TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - - -Repeat all the steps for interface ``vEth3_0`` - -Test Case: Ping and Ping6 testing -================================= - -If the application is launched successfully, it will add two interfaces in -kernel net stack named ``vEth2_0``, ``vEth3_0``. - -Assume the link status of ``vEth2_0`` is up and set ip address is ``192.168.2.1`` -and ``vEth3_0`` is up and set ip address is ``192.168.3.1``. Verify the -command ping:: - - ping -w 1 -I vEth2_0 192.168.2.1 - -it can receive all packets and no packet loss:: - - PING 192.168.2.1 (192.168.2.1) from 192.168.2.1 vEth2_0: 56(84) bytes of data. - 64 bytes from 192.168.2.1: icmp_req=1 ttl=64 time=0.040 ms - - --- 192.168.2.1 ping statistics --- - 1 packets transmitted, 1 received, 0% packet loss, time 0ms - rtt min/avg/max/mdev = 0.040/0.040/0.040/0.000 ms - -Assume ``port A`` on tester is linked with ``port 2`` on DUT. Verify the -command ping from tester:: - - ping -w 1 -I "port A" 192.168.2.1 - -it can receive all packets and no packet loss. - -Verify a wrong address:: - - ping -w 1 -I vEth2_0 192.168.0.123 - -no packets is received:: - - PING 192.168.0.123 (192.168.0.123) from 192.168.0.1 vEth2_0: 56(84) bytes of data. - - --- 192.168.0.123 ping statistics --- - 1 packets transmitted, 0 received, 100% packet loss, time 0ms - -Verify the command ping6:: - - ping6 -w 1 -I vEth2_0 "Eth2_0's ipv6 address" - -it can receive all packets and no packet loss:: - - PING fe80::92e2:baff:fe08:d6f0(fe80::92e2:baff:fe08:d6f0) from fe80::92e2:baff:fe08:d6f0 vEth2_0: 56 data bytes - 64 bytes from fe80::92e2:baff:fe08:d6f0: icmp_seq=1 ttl=64 time=0.070 ms - - --- fe80::92e2:baff:fe08:d6f0 ping statistics --- - 1 packets transmitted, 1 received, 0% packet loss, time 0ms - rtt min/avg/max/mdev = 0.070/0.070/0.070/0.000 ms - -Verify the command ping6 from tester:: - - ping6 -w 1 -I "port A" "Eth2_0's ipv6 address" - -it can receive all packets and no packet loss. - -Verify a wrong ipv6 address:: - - ping6 -w 1 -I vEth2_0 "random ipv6 address" - -no packets is received:: - - PING fe80::92e2:baff:fe08:d6f1(fe80::92e2:baff:fe08:d6f1) from fe80::92e2:baff:fe08:d6f0 vEth2_0: 56 data bytes - - --- fe80::92e2:baff:fe08:d6f1 ping statistics --- - 1 packets transmitted, 0 received, 100% packet loss, time 0ms - -Repeat all the steps for interface ``vEth3_0`` - -Test Case: Tcpdump testing -========================== - -Assume ``port A and B`` on packet generator connects to NIC ``port 2 and 3``. -Trigger the packet generator of bursting packets from ``port A and B`, then -check if tcpdump can capture all packets. The packets should include -``tcp`` packets, ``udp`` packets, ``icmp`` packets, ``ip`` packets, -``ether+vlan tag+ip`` packets, ``ether`` packets. - -Verify whether tcpdump can capture packets:: - - tcpdump -i vEth2_0 - tcpdump -i vEth3_0 - - -Test Case: Ethtool testing -========================== - -In this time, KNI can only support ethtool commands which is to get information. -So all below commands are to show information commands. - -Verify whether ethtool can show Kernel NIC Interface's standard information:: - - ethtool vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's driver information:: - - ethtool -i vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's statistics:: - - ethtool -S vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's pause parameters:: - - ethtool -a vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's offload parameters:: - - ethtool -k vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's RX/TX ring parameters:: - - ethtool -g vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's Coalesce parameters. -It is not currently supported:: - - ethtool -c vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's MAC registers:: - - ethtool -d vEth2_0 - -Verify whether ethtool can show Kernel NIC Interface's EEPROM dump:: - - ethtool -e vEth2_0 - -Repeat all the steps for interface ``vEth3_0`` - -Test Case: Packets statistics testing -===================================== - -Install the kernel module with loopback parameter ``lo_mode=lo_mode_ring_skb`` -and launch the KNI application. - -Assume that ``port 2 and 3`` are used by this application:: - - rmmod kni - insmod ./kmod/rte_kni.ko "lo_mode=lo_mode_ring_skb" - .//examples/dpdk-kni -c 0xff -n 3 -- -p 0xf -i 0xf -o 0xf0 - -Assume ``port A and B`` on tester connects to NIC ``port 2 and 3``. - -Get the RX packets count and TX packets count:: - - ifconfig vEth2_0 - -Send 5 packets from tester. And check whether both RX and TX packets of -``vEth2_0`` have increased 5. - -Repeat for interface ``vEth3_0`` - -Test Case: Stress testing -========================= - -Insert the rte_kni kernel module 50 times while changing the parameters. -Iterate through lo_mode and kthread_mode values sequentially, include wrong -values. After each insertion check whether kni application can be launched -successfully. - -Insert the kernel module 50 times while changing randomly the parameters. -Iterate through lo_mode and kthread_mode values randomly, include wrong -values. After each insertion check whether kni application can be launched -successfully:: - - rmmod rte_kni - insmod ./kmod/rte_kni.ko - .//examples/dpdk-kni -c 0xa0001e -n 4 -- -P -p 0xc --config="(2,1,2,21),(3,3,4,23)" - - -Using ``dmesg`` to check whether kernel module is loaded with the specified -parameters. Some permutations, those with wrong values, must fail to -success. For permutations with valid parameter values, verify the application can be -successfully launched and then close the application using CTRL+C. - -Test Case: loopback mode performance testing -============================================ - -Compare performance results for loopback mode using: - - - lo_mode: lo_mode_fifo and lo_mode_fifo_skb. - - kthread_mode: single and multiple. - - Number of ports: 1 and 2. - - Number of virtual interfaces per port: 1 and 2 - - Frame sizes: 64 and 256. - - Cores combinations: - - - Different cores for Rx, Tx and Kernel. - - Shared core between Rx and Kernel. - - Shared cores between Rx and Tx. - - Shared cores between Rx, Tx and Kernel. - - Multiple cores for Kernel, implies multiple virtual interfaces per port. - -:: - - insmod ./x86_64-default-linuxapp-gcc/kmod/igb_uio.ko - insmod ./x86_64-default-linuxapp-gcc/kmod/rte_kni.ko - .//examples/dpdk-kni -c -n 4 -- -P -p --config="" & - - -At this point, the throughput is measured and recorded for the different -frame sizes. After this, the application is closed using CTRL+C. - -The measurements are presented in a table format. - -+------------------+--------------+-------+-----------------+--------+--------+ -| lo_mode | kthread_mode | Ports | Config | 64 | 256 | -+==================+==============+=======+=================+========+========+ -| | | | | | | -+------------------+--------------+-------+-----------------+--------+--------+ - - -Test Case: bridge mode performance testing -========================================== - -Compare performance results for bridge mode using: - - - kthread_mode: single and multiple. - - Number of ports: 2 - - Number of ports: 1 and 2. - - Number of flows per port: 1 and 2 - - Number of virtual interfaces per port: 1 and 2 - - Frame size: 64. - - Cores combinations: - - - Different cores for Rx, Tx and Kernel. - - Shared core between Rx and Kernel. - - Shared cores between Rx and Tx. - - Shared cores between Rx, Tx and Kernel. - - Multiple cores for Kernel, implies multiple virtual interfaces per port. - -The application is launched and the bridge is setup using the commands below:: - - insmod ./x86_64-default-linuxapp-gcc/kmod/rte_kni.ko - .//examples/dpdk-kni -c -n 4 -- -P -p --config="" & - - ifconfig vEth2_0 up - ifconfig vEth3_0 up - brctl addbr "br_kni" - brctl addif br_kni vEth2_0 - brctl addif br_kni vEth3_0 - ifconfig br_kni up - - -At this point, the throughput is measured and recorded. After this, the -application is closed using CTRL+C and the bridge deleted:: - - ifconfig br_kni down - brctl delbr br_kni - - -The measurements are presented in a table format. - -+--------------+-------+-----------------------------+-------+ -| kthread_mode | Flows | Config | 64 | -+==============+=======+=============================+=======+ -| | | | | -+--------------+-------+-----------------------------+-------+ - -Test Case: bridge mode without KNI performance testing -====================================================== - -Compare performance results for bridge mode using only Kernel bridge, no DPDK -support. Use: - - - Number of ports: 2 - - Number of flows per port: 1 and 2 - - Frame size: 64. - -Set up the interfaces and the bridge:: - - rmmod rte_kni - ifconfig vEth2_0 up - ifconfig vEth3_0 up - brctl addbr "br1" - brctl addif br1 vEth2_0 - brctl addif br1 vEth3_0 - ifconfig br1 up - - -At this point, the throughput is measured and recorded. After this, the -application is closed using CTRL+C and the bridge deleted:: - - ifconfig br1 down - brctl delbr br1 - - -The measurements are presented in a table format. - -+-------+-------+ -| Flows | 64 | -+=======+=======+ -| 1 | | -+-------+-------+ -| 2 | | -+-------+-------+ - -Test Case: routing mode performance testing -=========================================== - -Compare performance results for routing mode using: - - - kthread_mode: single and multiple. - - Number of ports: 2 - - Number of ports: 1 and 2. - - Number of virtual interfaces per port: 1 and 2 - - Frame size: 64 and 256. - - Cores combinations: - - - Different cores for Rx, Tx and Kernel. - - Shared core between Rx and Kernel. - - Shared cores between Rx and Tx. - - Shared cores between Rx, Tx and Kernel. - - Multiple cores for Kernel, implies multiple virtual interfaces per port. - -The application is launched and the bridge is setup using the commands below:: - - echo 1 > /proc/sys/net/ipv4/ip_forward - - insmod ./x86_64-default-linuxapp-gcc/kmod/rte_kni.ko - .//examples/dpdk-kni -c -n 4 -- -P -p --config="" & - - ifconfig vEth2_0 192.170.2.1 - ifconfig vEth3_0 192.170.3.1 - route add -net 192.170.2.0 netmask 255.255.255.0 gw 192.170.2.1 - route add -net 192.170.3.0 netmask 255.255.255.0 gw 192.170.3.1 - arp -s 192.170.2.2 vEth2_0 - arp -s 192.170.3.2 vEth3_0 - -At this point, the throughput is measured and recorded. After this, the -application is closed using CTRL+C. - -The measurements are presented in a table format. - -+--------------+-------+-----------------------------+-------+-------+ -| kthread_mode | Ports | Config | 64 | 256 | -+==============+=======+=============================+=======+=======+ -| | | | | | -+--------------+-------+-----------------------------+-------+-------+ - - -Test Case: routing mode without KNI performance testing -======================================================= - -Compare performance results for routing mode using only Kernel, no DPDK -support. Use: - - - Number of ports: 2 - - Frame size: 64 and 256 - -Set up the interfaces and the bridge:: - - - echo 1 > /proc/sys/net/ipv4/ip_forward - rmmod rte_kni - ifconfig vEth2_0 192.170.2.1 - ifconfig vEth3_0 192.170.3.1 - route add -net 192.170.2.0 netmask 255.255.255.0 gw 192.170.2.1 - route add -net 192.170.3.0 netmask 255.255.255.0 gw 192.170.3.1 - arp -s 192.170.2.2 vEth2_0 - arp -s 192.170.3.2 vEth3_0 - -At this point, the throughput is measured and recorded. After this, the -application is closed using CTRL+C. - -The measurements are presented in a table format. - -+-------+-------+-------+ -| Ports | 64 | 256 | -+=======+=======+=======+ -| 1 | | | -+-------+-------+-------+ -| 2 | | | -+-------+-------+-------+ diff --git a/tests/TestSuite_kni.py b/tests/TestSuite_kni.py deleted file mode 100644 index 0a8c3009..00000000 --- a/tests/TestSuite_kni.py +++ /dev/null @@ -1,1568 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2010-2019 Intel Corporation -# - -""" -DPDK Test suite. - -Test Kernel NIC Interface. -""" - -import os -import re -import time -from random import randint - -import framework.packet as packet -import framework.utils as utils -from framework.pktgen import PacketGeneratorHelper -from framework.test_case import TestCase - -dut_ports = [] -port_virtual_interaces = [] - -ports_without_kni = 2 -flows_without_kni = 2 - -packet_sizes_loopback = [64, 256] -packet_sizes_routing = [64, 256] - -ports_cores_template = ( - "\(P([0123]),(C\{\d.\d.\d\}),(C\{\d.\d.\d\}),(C\{\d.\d.\d\}),?(C\{\d.\d.\d\})?\),?" -) - -default_1_port_cores_config = "(P0,C{1.0.0},C{1.1.0},C{1.2.0})" -default_2_port_cores_config = ( - "(P0,C{1.0.0},C{1.1.0},C{1.2.0}),(P1,C{1.3.0},C{1.4.0},C{1.5.0})" -) - -stress_test_iterations = 50 -stress_test_random_iterations = 50 - -routing_performance_steps = [ - {"kthread_mode": "single", "config": "(P0,C{1.0.0},C{1.1.0},C{1.0.1})"}, - {"kthread_mode": "single", "config": "(P0,C{1.0.0},C{1.0.1},C{1.1.0})"}, - {"kthread_mode": "single", "config": "(P0,C{1.0.0},C{1.1.0},C{1.2.0})"}, - { - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.0.1})", - }, - { - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.4.0})", - }, - { - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.2.0})", - }, - { - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.0.1})", - }, - { - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.4.0})", - }, - { - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.2.0})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.3.0})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.3.0})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.2.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.2.1})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.5.0})", - }, - { - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0},C{1.6.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0},C{1.7.0})", - }, -] - -bridge_performance_steps = [ - { - "flows": 1, - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.0.1})", - }, - { - "flows": 1, - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.4.0})", - }, - { - "flows": 1, - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.2.0})", - }, - { - "flows": 2, - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.0.1})", - }, - { - "flows": 2, - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.4.0})", - }, - { - "flows": 2, - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.2.0})", - }, - { - "flows": 1, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1})", - }, - { - "flows": 1, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.3.0})", - }, - { - "flows": 1, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0})", - }, - { - "flows": 2, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1})", - }, - { - "flows": 2, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.3.0})", - }, - { - "flows": 2, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0})", - }, - { - "flows": 1, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.2.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.2.1})", - }, - { - "flows": 1, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.5.0})", - }, - { - "flows": 1, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0},C{1.6.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0},C{1.7.0})", - }, - { - "flows": 2, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.2.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.2.1})", - }, - { - "flows": 2, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.5.0})", - }, - { - "flows": 2, - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0},C{1.6.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0},C{1.7.0})", - }, -] - -loopback_performance_steps = [ - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.0.1})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.1.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.2.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.0.1})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.4.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.2.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.0.1})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.1.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.2.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.3.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.2.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.3.1})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.1.1},C{1.5.0})", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0},C{1.6.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0},C{1.7.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.0.1})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.1.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.2.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.0.1})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.4.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "single", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.2.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.0.1})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.1.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.1.0},C{1.2.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.0.1}),(P1,C{1.1.0},C{1.3.0},C{1.1.1})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.0.1},C{1.2.0}),(P1,C{1.1.0},C{1.1.1},C{1.3.0})", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "config": "(P0,C{1.0.0},C{1.2.0},C{1.4.0}),(P1,C{1.1.0},C{1.3.0},C{1.5.0})", - }, -] - -loopback_perf_results_header = ["lo_mode", "kthread_mode", "Ports", "Config"] -bridge_perf_results_header = ["kthread_mode", "Flows", "Config", "64 Mpps"] -bridge_perf_no_kni_results_header = ["Flows", "64 Mpps"] -routing_perf_results_header = ["kthread_mode", "Ports", "Config"] -routing_perf_no_kni_results_header = ["Ports"] - -stress_modes_output = [ - { - "lo_mode": None, - "kthread_mode": None, - "output": "loopback disabled.*DPDK kni module loaded.*Single kernel thread", - }, - { - "lo_mode": "lo_mode_none", - "kthread_mode": None, - "output": "loopback disabled.*DPDK kni module loaded.*Single kernel thread", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": None, - "output": "loopback mode=lo_mode_fifo enabled.*Single kernel thread", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": None, - "output": "loopback mode=lo_mode_fifo_skb enabled.*Single kernel thread", - }, - { - "lo_mode": "lo_mode_random", - "kthread_mode": None, - "output": "Incognizant parameter, loopback disabled.*DPDK kni module loaded.*Single kernel thread", - }, - { - "lo_mode": None, - "kthread_mode": "single", - "output": "loopback disabled.*DPDK kni module loaded.*Single kernel thread", - }, - { - "lo_mode": None, - "kthread_mode": "multiple", - "output": "loopback disabled.*DPDK kni module loaded.*Multiple kernel thread", - }, - { - "lo_mode": None, - "kthread_mode": "singlemulti", - "output": "KNI.* Invalid parameter for kthread_mode", - }, - { - "lo_mode": "lo_mode_fifo", - "kthread_mode": "multiple", - "output": "loopback mode=lo_mode_fifo enabled.*Multiple kernel thread", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "multiple", - "output": "loopback mode=lo_mode_fifo_skb enabled.*Multiple kernel thread", - }, - { - "lo_mode": "lo_mode_fifo_skb", - "kthread_mode": "singlemulti", - "output": "Invalid parameter for kthread_mode", - }, - { - "lo_mode": "lo_mode_random", - "kthread_mode": "multiple", - "output": "KNI.* Incognizant parameter, loopback disabled", - }, -] - -# -# -# Test class. -# - - -class TestKni(TestCase): - - # - # - # Utility methods and other non-test code. - # - # Insert or move non-test functions here. - - def set_up_all(self): - """ - Run at the start of each test suite. - - KNI Prerequisites - """ - out = self.dut.send_expect("which brctl", "# ") - self.verify( - "no brctl" not in out, - "The linux tool brctl is needed to run this test suite", - ) - - out = self.dut.build_dpdk_apps("./examples/kni") - self.app_kni_path = self.dut.apps_name["kni"] - self.verify("Error" not in out, "Compilation failed") - p0_pci = self.dut.ports_info[0]["pci"] - numa_node = int( - self.dut.send_expect( - "cat /sys/bus/pci/devices/%s/numa_node" % p0_pci, "# ", 30 - ) - ) - socket_id = numa_node if numa_node > 0 else 0 - if socket_id == 0: - global default_1_port_cores_config - global default_2_port_cores_config - global routing_performance_steps - global bridge_performance_steps - global loopback_performance_steps - - default_1_port_cores_config = default_1_port_cores_config.replace( - "C{1.", "C{0." - ) - default_2_port_cores_config = default_1_port_cores_config.replace( - "C{1.", "C{0." - ) - for i in range(len(routing_performance_steps)): - routing_performance_steps[i]["config"] = routing_performance_steps[i][ - "config" - ].replace("C{1.", "C{0.") - for j in range(len(bridge_performance_steps)): - bridge_performance_steps[j]["config"] = bridge_performance_steps[j][ - "config" - ].replace("C{1.", "C{0.") - for k in range(len(loopback_performance_steps)): - loopback_performance_steps[k]["config"] = loopback_performance_steps[k][ - "config" - ].replace("C{1.", "C{0.") - - self.extract_ports_cores_config(default_1_port_cores_config) - out = self.start_kni() - self.verify("Error" not in out, "Error found during kni start") - out = self.dut.send_expect("cat /etc/os-release", "# ") - if "Ubuntu" in out: - self.dut.send_expect("ufw disable", "# ") - else: - self.dut.send_expect("service iptables stop", "# ") - self.dut.send_expect("service firewalld stop", "# ") - - # 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() - # enable dut ipv6 - self.dut.enable_ipv6("all") - - def set_up(self): - """ - Run before each test case. - """ - pass - - def start_kni(self, lo_mode=None, kthread_mode=None): - """ - Insert the igb_uio and rte_kni modules with passed parameters and launch - kni application. - """ - module_param = "" - if lo_mode is not None: - module_param += "lo_mode=%s " % lo_mode - - if kthread_mode is not None: - module_param += "kthread_mode=%s" % kthread_mode - self.dut.kill_all() - out = self.dut.send_expect("rmmod rte_kni", "# ", 10) - self.verify("in use" not in out, "Error unloading KNI module: " + out) - if self.drivername == "igb_uio": - self.dut.send_expect("rmmod igb_uio", "# ", 5) - self.dut.send_expect( - "insmod ./%s/kmod/igb_uio.ko" % (self.target), "# ", 20 - ) - self.dut.bind_interfaces_linux(self.drivername) - out = self.dut.send_expect( - "insmod ./%s/kmod/rte_kni.ko %s" % (self.target, module_param), "# ", 10 - ) - - self.verify("Error" not in out, "Error loading KNI module: " + out) - - port_mask = utils.create_mask(self.config["ports"]) - core_mask = utils.create_mask( - self.config["rx_cores"] - + self.config["tx_cores"] - + self.config["kernel_cores"] - ) - - config_param = self.build_config_param() - - eal_para = self.dut.create_eal_parameters( - cores=self.config["rx_cores"] - + self.config["tx_cores"] - + self.config["kernel_cores"] - ) - out_kni = self.dut.send_expect( - "./%s %s -- -P -p %s %s -m &" - % (self.app_kni_path, eal_para, port_mask, config_param), - "Link [Uu]p", - 20, - ) - - time.sleep(5) - if kthread_mode == "single": - kthread_mask = utils.create_mask(self.config["kernel_cores"]) - out = self.dut.send_expect( - "taskset -p `pgrep -fl kni_single | awk '{print $1}'`", "#" - ) - self.verify("current affinity mask" in out, "Unable to set core affinity") - - return out_kni - - def extract_ports_cores_config(self, ports_cores_config): - """ - Parses a ports/cores configuration string into the 'self.config' variable. - """ - ports_cores_pattern = re.compile(ports_cores_template) - port_configs = ports_cores_pattern.findall(ports_cores_config) - dut_ports = self.dut.get_ports(self.nic) - - config = {} - ports = [] - rx_cores = [] - tx_cores = [] - k_cores = [] - port_details = [] - for port_config in port_configs: - details = {} - - port_number = int(port_config[0]) - self.verify(port_number < len(dut_ports), "Not enough ports available") - - ports.append(dut_ports[port_number]) - details["port"] = dut_ports[port_number] - rx_cores.append(self.dut.get_lcore_id(port_config[1])) - details["rx_core"] = self.dut.get_lcore_id(port_config[1]) - tx_cores.append(self.dut.get_lcore_id(port_config[2])) - details["tx_core"] = self.dut.get_lcore_id(port_config[2]) - - details["kernel_cores"] = [] - for k_core in port_config[3:]: - if k_core != "": - k_cores.append(self.dut.get_lcore_id(k_core)) - details["kernel_cores"].append(self.dut.get_lcore_id(k_core)) - - port_details.append(details) - - config["ports"] = ports - config["rx_cores"] = rx_cores - config["tx_cores"] = tx_cores - config["kernel_cores"] = k_cores - config["port_details"] = port_details - - self.config = config - - def build_config_param(self): - """ - Formats the '--conf=(xxx)' parameter for kni application calls - """ - config_param = '--config="%s' - port_cores = "(%s,%s,%s)" - port_cores_kernel = "(%s,%s,%s," - - for port in self.config["port_details"]: - - # Kernel threads specified - if len(port["kernel_cores"]) > 0: - - port_config = port_cores_kernel % ( - port["port"], - port["rx_core"], - port["tx_core"], - ) - - for core in port["kernel_cores"]: - port_config += str(core) + "," - - port_config = port_config[:-1] + ")" - - # No kernel threads specified - else: - port_config = port_cores % ( - port["port"], - port["rx_core"], - port["tx_core"], - ) - - config_param = config_param % port_config + ",%s" - - config_param = config_param.replace(",%s", '"') - - return config_param - - def stripped_config_param(self): - """ - Removes the '--config=' prefix from the config string. - Used for reporting. - """ - config_param = self.build_config_param() - config_param = config_param.replace('--config="', "") - config_param = config_param.replace('"', "") - return config_param - - def virtual_interface_name(self, port, sub_port=0): - """ - Given a port and subport name, formats the virtual interface name. - """ - return "vEth%d_%d" % (port, sub_port) - - def dut_physical_cores(self): - """ - Returns the number of physical cores in socket 0. - """ - dut_cores = self.dut.get_all_cores() - - first_core = dut_cores[0] - cores = [] - - for core in dut_cores[1:]: - if core["core"] not in cores and core["socket"] == first_core["socket"]: - cores.append(core["core"]) - - return len(cores) - - def make_allow_list(self, target, nic): - """ - Create allow list with ports. - """ - allow_list = [] - dut_ports = self.dut.get_ports(self.nic) - self.dut.restore_interfaces() - allPort = self.dut.ports_info - if self.drivername in ["igb_uio"]: - self.dut.send_expect("insmod ./" + self.target + "/kmod/igb_uio.ko", "#") - for port in range(0, len(allPort)): - if port in dut_ports: - allow_list.append(allPort[port]["pci"]) - return allow_list - - # - # - # - # Test cases. - # - - def test_ifconfig(self): - """ - Ifconfig support KNI. - """ - - # Ports and cores configuration set in set_up_all function - # Check that all virtual interfaces support ifconfig calls. - out = self.dut.send_expect("ifconfig -a", "# ") - for port in self.config["ports"]: - virtual_interface = self.virtual_interface_name(port) - self.verify( - virtual_interface in out, - "ifconfig not supported for %s" % virtual_interface, - ) - - # For each virtual interface perform the following operations - for port in self.config["ports"]: - virtual_interface = self.virtual_interface_name(port) - - # some time, the virtual interface stats is up when it create - # so should set down before set up. - self.dut.send_expect("ifconfig %s down" % virtual_interface, "# ") - out = self.dut.send_expect("ifconfig %s up" % virtual_interface, "# ") - self.verify( - "Configure network interface of %d up" % port in out, - "ifconfig up not supported", - ) - # Add an IPv6 address - out = self.dut.send_expect( - "ifconfig %s add fe80::%d" % (virtual_interface, port + 1), "# " - ) - out = self.dut.send_expect( - "ip -family inet6 address show dev %s" % virtual_interface, "# " - ) - self.verify( - "inet6 fe80::%d" % (port + 1) in out, - "ifconfig add ipv6 address not supported", - ) - - # Delete the IPv6 address - out = self.dut.send_expect( - "ifconfig %s del fe80::%d" % (virtual_interface, port + 1), "# " - ) - out = self.dut.send_expect( - "ip -family inet6 address show dev %s" % virtual_interface, "# " - ) - self.verify( - "inet6 fe80::%d/128" % (port + 1) not in out, - "ifconfig del ipv6 address not supported", - ) - - # Add an IPv4 address - out = self.dut.send_expect( - "ifconfig %s 192.168.%d.1 netmask 255.255.255.192" - % (virtual_interface, port), - "# ", - ) - out = self.dut.send_expect( - "ip -family inet address show dev %s" % virtual_interface, "# " - ) - self.verify( - "inet 192.168.%d.1/26" % port in out, - "ifconfig set ip address not supported", - ) - - # Set the MTU - out = self.dut.send_expect("ifconfig %s mtu 1300" % virtual_interface, "# ") - out = self.dut.send_expect("ip link show %s" % virtual_interface, "# ") - self.verify("mtu 1300" in out, "mtu setup not supported") - - # Bring down - self.dut.send_expect("ifconfig %s down" % virtual_interface, "# ") - out = self.dut.send_expect( - "ip -family inet6 address show dev %s" % virtual_interface, "# " - ) - self.verify("inet6 addr" not in out, "ifconfig down not supported") - - def test_ping(self): - """ - Ping support KNI. - """ - - # Ports and cores configuration set in set_up_all function - # Setup IP address on virtual interfaces and tester ports - self.dut.kill_all() - self.start_kni() - ports_ips = {} - for port in self.config["ports"]: - virtual_interface = self.virtual_interface_name(port) - - tx_port = self.tester.get_local_port(port) - tx_interface = self.tester.get_interface(tx_port) - out = self.dut.send_expect("ifconfig %s up" % virtual_interface, "# ") - time.sleep(5) - v_intf_ip = f"192.168.{port}.1" - tx_intf_ip = f"192.168.{port}.2" - self.dut.send_expect( - "ifconfig %s %s netmask 255.255.255.192" - % (virtual_interface, v_intf_ip), - "# ", - ) - self.tester.send_expect( - "ifconfig %s %s netmask 255.255.255.192" % (tx_interface, tx_intf_ip), - "# ", - ) - ports_ips[port] = [tx_intf_ip, v_intf_ip] - self.tester.enable_ipv6(tx_interface) - time.sleep(5) - # Send ping requests and check for answers - for port in self.config["ports"]: - tx_intf_ip, v_intf_ip = ports_ips[port] - - tx_port = self.tester.get_local_port(port) - tx_interface = self.tester.get_interface(tx_port) - - virtual_interface = self.virtual_interface_name(port) - - out = self.dut.send_expect( - "ping -w 2 -I %s 192.168.%d.2" % (v_intf_ip, port), "# ", 10 - ) - out1 = self.dut.send_expect( - "ping -w 2 -I %s 192.168.%d.2" % (virtual_interface, port), "# ", 10 - ) - expected_str = "64 bytes from 192.168.%d.2:" % port - self.verify( - any([expected_str in out, expected_str in out1]), "ping not supported" - ) - out = self.tester.send_expect( - "ping -w 1 -I %s 192.168.%d.1" % (tx_intf_ip, port), "# ", 10 - ) - out1 = self.tester.send_expect( - "ping -w 1 -I %s 192.168.%d.1" % (tx_interface, port), "# ", 10 - ) - expected_str = "64 bytes from 192.168.%d.1:" % port - self.verify( - any([expected_str in out, expected_str in out1]), - "kni cannot reply ping packet", - ) - out = self.dut.send_expect( - "ping -w 1 -I %s 192.168.%d.123" % (v_intf_ip, port), "# ", 10 - ) - out1 = self.dut.send_expect( - "ping -w 1 -I %s 192.168.%d.123" % (virtual_interface, port), "# ", 10 - ) - expected_str = "0 received, 100% packet loss" - self.verify( - all([expected_str in out, expected_str in out1]), "ping not supported" - ) - out = self.dut.send_expect( - "ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'| cut -d'/' -f1" - % virtual_interface, - "# ", - 10, - ) - out1 = self.tester.send_expect( - "ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'| cut -d'/' -f1" - % tx_interface, - "# ", - 10, - ) - if out.strip() == "": - self.dut.send_expect( - "ip -6 addr add fe80::742e:c5ef:bb9:b4c8/64 dev %s" - % virtual_interface, - "# ", - 3, - ) - if out1.strip() == "": - self.tester.send_expect( - "ip -6 addr add fe80::742e:c5ef:bb9:b4c9/64 dev %s" % tx_interface, - "# ", - 3, - ) - time.sleep(3) - out = self.dut.send_expect( - "ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'| cut -d'/' -f1" - % virtual_interface, - "# ", - 10, - ) - ipv6_address = out.split("\r\n")[0] - self.tester.send_expect("ifconfig %s up" % tx_interface, "# ") - out = self.dut.send_expect( - "ping6 -w 1 -I %s %s" % (v_intf_ip, str(ipv6_address)), "# ", 10 - ) - out1 = self.dut.send_expect( - "ping6 -w 1 %s%%%s" % (str(ipv6_address), virtual_interface), "# ", 10 - ) - # FC25 ping6 output info is "64 bytes from ipv6_address%v: icmp_seq=1 ttl=64" - # other os ping6 output is "64 bytes from ipv6_address: icmp_seq=1 ttl=64" - expected_str = "64 bytes from %s" % ipv6_address - self.verify( - any([expected_str in out, expected_str in out1]), "ping6 not supported" - ) - out = self.tester.send_expect( - "ping6 -w 1 -I %s %s" % (tx_intf_ip, str(ipv6_address)), "# ", 10 - ) - out1 = self.tester.send_expect( - "ping6 -w 1 %s%%%s" % (str(ipv6_address), tx_interface), "# ", 10 - ) - expected_str = "64 bytes from %s" % ipv6_address - self.verify( - any([expected_str in out, expected_str in out1]), - "kni cannot reply ping6 packet", - ) - ipv6list = list(ipv6_address) - for j in range(10): - if str(j) == ipv6list[-1]: - continue - else: - ipv6list[-1] = str(j) - break - - out = self.dut.send_expect( - "ping6 -w 1 -I %s %s" % (v_intf_ip, "".join(ipv6list)), "# ", 10 - ) - out1 = self.dut.send_expect( - "ping6 -w 1 %s%%%s" % ("".join(ipv6list), virtual_interface), "# ", 10 - ) - expected_str = "0 received, 100% packet loss" - self.verify( - any([expected_str in out, expected_str in out1]), "ping6 not supported" - ) - # remove ip from tester - self.tester.send_expect( - "ip addr del 192.168.%d.2 dev %s" % (port, tx_interface), "# " - ) - - for port in self.config["ports"]: - tx_port = self.tester.get_local_port(port) - tx_interface = self.tester.get_interface(tx_port) - self.tester.disable_ipv6(tx_interface) - time.sleep(1) - - def test_tcpdump(self): - """ - Tcpdump support KNI. - """ - - # Ports and cores configuration set in set_up_all function - self.dut.kill_all() - self.start_kni() - - file_name = "packet.log" - for port in self.config["ports"]: - self.dut.send_expect(f"rm -rf {file_name}", "#") - virtual_interface = self.virtual_interface_name(port) - - tx_port = self.tester.get_local_port(port) - rx_mac = self.dut.get_mac_address(port) - tx_mac = self.tester.get_mac(tx_port) - tx_interface = self.tester.get_interface(tx_port) - - self.dut.send_expect("ifconfig %s up" % virtual_interface, "# ") - # ensure virtual_interface link up - self.verify( - self.dut.is_interface_up(intf=virtual_interface), - "Wrong link status, should be up", - ) - # Start tcpdump with filters for src and dst MAC address, this avoids - # unwanted broadcast, ICPM6... packets - out = self.dut.send_expect( - 'tcpdump -i %s -e -w %s "ether src %s and ether dst %s"' - % (virtual_interface, file_name, tx_mac, rx_mac), - "listening on %s" % virtual_interface, - 30, - ) - - packets_to_send = [ - 'sendp([Ether(src=srcmac,dst=dstmac)/IP()/UDP()/("W"*28)],iface="%s")', - 'sendp([Ether(src=srcmac,dst=dstmac)/IP()/TCP()/("W"*28)],iface="%s")', - 'sendp([Ether(src=srcmac,dst=dstmac)/IP()/ICMP()/("W"*28)],iface="%s")', - 'sendp([Ether(src=srcmac,dst=dstmac)/IP()/("W"*38)],iface="%s")', - 'sendp([Ether(src=srcmac,dst=dstmac)/("W"*46)],iface="%s")', - ] - - self.tester.scapy_append('dstmac="%s"' % rx_mac) - self.tester.scapy_append('srcmac="%s"' % tx_mac) - - for packet in packets_to_send: - self.tester.scapy_append(packet % tx_interface) - - self.tester.scapy_execute() - - out = self.dut.send_expect("^C", "# ", 20) - - self.verify( - "%d packets captured" % len(packets_to_send) in out, - "Wrong number of packets captured", - ) - - def test_statistics(self): - """ - KNI Statistics test. - """ - rx_match = "RX packets.(\d+)" - - self.dut.kill_all() - self.start_kni(lo_mode="lo_mode_ring_skb") - - # Ports and cores configuration set in set_up_all function - # For each virtual interface perform the following operations - for port in self.config["ports"]: - - virtual_interface = self.virtual_interface_name(port) - - out = self.dut.send_expect("ifconfig %s up" % virtual_interface, "# ") - # ensure virtual_interface up - self.verify( - self.dut.is_interface_up(intf=virtual_interface), - "virtual_interface should be up", - ) - out = self.dut.send_expect("ifconfig %s" % virtual_interface, "# ") - m = re.search(rx_match, out) - previous_rx_packets = int(m.group(1)) - - tx_port = self.tester.get_local_port(port) - rx_mac = self.dut.get_mac_address(port) - tx_mac = self.tester.get_mac(tx_port) - tx_interface = self.tester.get_interface(tx_port) - - scapy_str = [ - 'Ether(src = "%s",dst="%s")/IP()/UDP()/("X"*28)' % (tx_mac, rx_mac), - 'Ether(src = "%s",dst="%s")/IP()/TCP()/("X"*28)' % (tx_mac, rx_mac), - 'Ether(src = "%s",dst="%s")/IP()/ICMP()/("X"*28)' % (tx_mac, rx_mac), - 'Ether(src = "%s",dst="%s")/IP()/("X"*38)' % (tx_mac, rx_mac), - 'Ether(src = "%s",dst="%s")/("X"*46)' % (tx_mac, rx_mac), - ] - - pkt = packet.Packet() - pkt.update_pkt(scapy_str) - # ensure tester's interface up - self.verify( - self.tester.is_interface_up(intf=tx_interface), - "Tester's interface should be up", - ) - pkt.send_pkt(self.tester, tx_port=tx_interface, count=200) - - out = self.dut.send_expect("ifconfig %s" % virtual_interface, "# ") - m = re.search(rx_match, out) - rx_packets = int(m.group(1)) - - self.verify( - rx_packets == (previous_rx_packets + 1000), - "Rx statistics error in iface %s" % virtual_interface, - ) - - self.dut.kill_all() - - def test_stress(self): - """ - KNI stress test. - """ - self.extract_ports_cores_config(default_2_port_cores_config) - self.dut.send_expect("dmesg -c", "]# ") # Clean the dmesg ring buffer - for i in range(stress_test_iterations + stress_test_random_iterations): - - self.dut.kill_all() - - if i < stress_test_iterations: - step = stress_modes_output[i % len(stress_modes_output)] - else: - step = stress_modes_output[randint(0, len(stress_modes_output) - 1)] - - expectedMessage = step["output"] - - try: - out = self.start_kni(step["lo_mode"], step["kthread_mode"]) - self.verify("Error" not in out, "Error found during kni start") - # kni setup out info by kernel debug function. so should re-build kernel. - # now not check kni setup out info, only check kni setup ok and setup no error output - out = self.dut.send_expect("ps -aux", "]# ") - self.verify("kni" not in out, "kni process setup failed") - except: - # some permutations have to fail - pass - - def test_perf_loopback(self): - """ - KNI loopback performance - """ - self.dut.kill_all() - - header = loopback_perf_results_header - for size in packet_sizes_loopback: - header.append("%d (pps)" % size) - - self.result_table_create(header) - - # Execute the permutations of the test - for step in loopback_performance_steps: - - self.extract_ports_cores_config(step["config"]) - - total_cores = len( - self.config["tx_cores"] - + self.config["rx_cores"] - + self.config["kernel_cores"] - ) - if total_cores > self.dut_physical_cores(): - self.logger.info( - "Skipping step %s (%d cores needed, got %d)" - % (step["config"], total_cores, self.dut_physical_cores()) - ) - continue - - self.start_kni(lo_mode=step["lo_mode"], kthread_mode=step["kthread_mode"]) - - pps_results = [] - - for size in packet_sizes_loopback: - - payload_size = size - 38 - - ports_number = len(self.config["ports"]) - - # Set up the flows for the ports - tgen_input = [] - for port in self.config["ports"]: - - rx_mac = self.dut.get_mac_address(port) - tx_port = self.tester.get_local_port(port) - self.tester.scapy_append('dstmac = "%s"' % rx_mac) - self.tester.scapy_append( - 'flows = [Ether(dst=dstmac)/IP()/("X"*%d)]' % payload_size - ) - pcap = os.sep.join( - [self.output_path, "tester{0}.pcap".format(tx_port)] - ) - self.tester.scapy_append('wrpcap("%s",flows)' % pcap) - self.tester.scapy_execute() - tgen_input.append((tx_port, tx_port, pcap)) - - time.sleep(1) - - # 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_results.append(float(pps) / 1000000) - - ports_number = len(self.config["ports"]) - results_row = [ - step["lo_mode"], - step["kthread_mode"], - ports_number, - self.stripped_config_param(), - ] + pps_results - self.result_table_add(results_row) - - self.dut.kill_all() - - self.result_table_print() - - def test_perf_bridge(self): - """ - KNI performance bridge mode. - """ - self.result_table_create(bridge_perf_results_header) - - self.tester.scapy_append('srcmac="00:00:00:00:00:01"') - pcap = os.sep.join([self.output_path, "kni.pcap"]) - self.tester.scapy_append( - 'wrpcap("%s", [Ether(src=srcmac, dst="ff:ff:ff:ff:ff:ff")/IP(len=46)/UDP()/("X"*18)])' - % pcap - ) - self.tester.scapy_execute() - - for step in bridge_performance_steps: - - self.extract_ports_cores_config(step["config"]) - - total_cores = len( - self.config["tx_cores"] - + self.config["rx_cores"] - + self.config["kernel_cores"] - ) - if total_cores > self.dut_physical_cores(): - self.logger.info( - "Skipping step %s (%d cores needed, got %d)" - % (step["config"], total_cores, self.dut_physical_cores()) - ) - continue - - port_virtual_interaces = [] - for port in self.config["port_details"]: - for i in range(len(port["kernel_cores"])): - port_virtual_interaces.append( - self.virtual_interface_name(port["port"], i) - ) - - self.dut.kill_all() - self.start_kni(lo_mode=None, kthread_mode=step["kthread_mode"]) - - for virtual_interace in port_virtual_interaces: - out = self.dut.send_expect("ifconfig %s up" % virtual_interace, "# ") - self.verify("ERROR" not in out, "Virtual interface not found") - - self.dut.send_expect('brctl addbr "br_kni"', "# ") - - for virtual_interace in port_virtual_interaces: - out = self.dut.send_expect( - "brctl addif br_kni %s" % virtual_interace, "# " - ) - self.verify("ERROR" not in out, "Device not found") - - self.dut.send_expect("ifconfig br_kni up", "# ") - - tx_port = self.tester.get_local_port(self.config["ports"][0]) - rx_port = self.tester.get_local_port(self.config["ports"][1]) - - tgenInput = [] - tgenInput.append((tx_port, rx_port, pcap)) - - if step["flows"] == 2: - tgenInput.append((rx_port, tx_port, pcap)) - self.verify(self.dut.is_interface_up(intf="br_kni"), "br_kni should be up") - - # clear streams before add new streams - self.tester.pktgen.clear_streams() - # run packet generator - streams = self.pktgen_helper.prepare_stream_from_tginput( - tgenInput, 100, None, self.tester.pktgen - ) - _, pps = self.tester.pktgen.measure_throughput(stream_ids=streams) - step["pps"] = float(pps) / 10**6 - - results_row = [ - step["kthread_mode"], - step["flows"], - self.stripped_config_param(), - (float(pps) / 10**6), - ] - - self.result_table_add(results_row) - - self.dut.send_expect("ifconfig br_kni down", "# ") - self.dut.send_expect('brctl delbr "br_kni"', "# ", 10) - - self.result_table_print() - - def test_perf_bridge_without_kni(self): - """ - Bridge mode performance without KNI. - """ - self.result_table_create(bridge_perf_no_kni_results_header) - - self.dut.kill_all() - - dut_ports = self.dut.get_ports(self.nic) - - self.tester.scapy_append('srcmac="00:00:00:00:00:01"') - pcap = os.sep.join([self.output_path, "kni.pcap"]) - self.tester.scapy_append( - 'wrpcap("%s", [Ether(src=srcmac, dst="ff:ff:ff:ff:ff:ff")/IP(len=46)/UDP()/("X"*18)])' - % pcap - ) - self.tester.scapy_execute() - - allow_list = self.make_allow_list(self.target, self.nic) - port_virtual_interaces = [] - for port in allow_list: - information = self.dut.send_expect( - "./usertools/dpdk-devbind.py --status | grep '%s'" % port, "# " - ) - data = information.split(" ") - for field in data: - if field.rfind("if=") != -1: - port_virtual_interaces.append(field.replace("if=", "")) - - self.dut.send_expect("ifconfig %s up" % port_virtual_interaces[0], "# ") - self.dut.send_expect("ifconfig %s up" % port_virtual_interaces[1], "# ") - self.dut.send_expect('brctl addbr "br1"', "# ") - self.dut.send_expect("brctl addif br1 %s" % port_virtual_interaces[0], "# ") - self.dut.send_expect("brctl addif br1 %s" % port_virtual_interaces[1], "# ") - self.dut.send_expect("ifconfig br1 up", "# ") - time.sleep(3) - - tx_port = self.tester.get_local_port(dut_ports[0]) - rx_port = self.tester.get_local_port(dut_ports[1]) - - for flows in range(1, flows_without_kni + 1): - tgen_input = [] - tgen_input.append((tx_port, rx_port, pcap)) - - if flows == 2: - tgen_input.append((rx_port, tx_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 - ) - _, pps = self.tester.pktgen.measure_throughput(stream_ids=streams) - - self.result_table_add([flows, float(pps) / 10**6]) - - self.dut.send_expect("ifconfig br1 down", "# ") - self.dut.send_expect('brctl delbr "br1"', "# ", 30) - - for port in allow_list: - self.dut.send_expect( - "./usertools/dpdk-devbind.py -b igb_uio %s" % (port), "# " - ) - self.result_table_print() - - def test_perf_routing(self): - """ - Routing performance. - """ - - header = routing_perf_results_header - - for size in packet_sizes_routing: - header.append("%d Mpps" % size) - - self.result_table_create(header) - - self.dut.send_expect("echo 1 > /proc/sys/net/ipv4/ip_forward", "# ") - - # Run the test steps - for step in routing_performance_steps: - self.extract_ports_cores_config(step["config"]) - - resutls_row = [ - step["kthread_mode"], - len(self.config["ports"]), - self.stripped_config_param(), - ] - - self.dut.kill_all() - self.start_kni() - - # Set up the IP addresses, routes and arp entries of the virtual - # interfaces - virtual_interaces = {} - ip_subnet = 0 - for port in self.config["port_details"]: - - port_number = port["port"] - - # Get the virtual interfaces base on the number of kernel - # lcores - port_virtual_interaces = [] - for i in range(len(port["kernel_cores"])): - port_virtual_interaces.append( - self.virtual_interface_name(port_number, i) - ) - - virtual_interaces[port_number] = port_virtual_interaces - - # Setup IP, ARP and route for each virtual interface - for interface in range(len(virtual_interaces[port_number])): - tx_port = self.tester.get_local_port(port_number) - - self.dut.send_expect( - "ifconfig %s 192.170.%d.1" - % (virtual_interaces[port_number][interface], ip_subnet), - "# ", - ) - self.dut.send_expect( - "route add -net 192.170.%d.0 netmask 255.255.255.0 gw 192.170.%d.1" - % (ip_subnet, ip_subnet), - "# ", - ) - self.dut.send_expect( - "arp -s 192.170.%d.2 %s" - % (ip_subnet, self.tester.get_mac(tx_port)), - "# ", - ) - ip_subnet += 1 - - # Get performance for each frame size - for packet_size in packet_sizes_routing: - payload_size = packet_size - 38 - tgen_input = [] - - # Test one port - tx_port = self.tester.get_local_port(self.config["ports"][0]) - rx_mac = self.dut.get_mac_address(self.config["ports"][0]) - - port_iterator = 0 - cnt = 0 - for port in self.config["port_details"]: - port_number = port["port"] - - rx_mac = self.dut.get_mac_address(port_number) - tx_port = self.tester.get_local_port(port_number) - - num_interfaces_per_port = len(virtual_interaces[port_number]) - - # Set flows from and to virtual interfaces in the same port - src_ip_subnet = port_iterator * num_interfaces_per_port - for interface in range(len(virtual_interaces[port_number])): - dst_ip_subnet = (src_ip_subnet + 1) % num_interfaces_per_port - dst_ip_subnet += port_iterator * num_interfaces_per_port - self.tester.scapy_append("flows = []") - self.tester.scapy_append( - 'flows.append(Ether(dst="%s")/IP(src="192.170.%d.2",dst="192.170.%d.2")/("X"*%d))' - % (rx_mac, src_ip_subnet, dst_ip_subnet, payload_size) - ) - src_ip_subnet += 1 - pcap = os.sep.join( - [self.output_path, "routePerf_{0}.pcap".format(cnt)] - ) - self.tester.scapy_append('wrpcap("%s",flows)' % pcap) - self.tester.scapy_execute() - tgen_input.append((tx_port, tx_port, pcap)) - cnt += 1 - time.sleep(1) - - # 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) - - resutls_row.append(float(pps) / 10**6) - - self.result_table_add(resutls_row) - - self.result_table_print() - - def test_perf_routing_without_kni(self): - """ - Routing performance without KNI. - """ - - header = routing_perf_no_kni_results_header - - for size in packet_sizes_routing: - header.append("%d Mpps" % size) - - self.result_table_create(header) - - self.dut.kill_all() - self.dut.send_expect("rmmod rte_kni", "# ", 20) - - self.dut.send_expect("systemctl stop NetworkManager.service", "# ") - - dut_ports = self.dut.get_ports(self.nic) - - allow_list = self.make_allow_list(self.target, self.nic) - port_virtual_interaces = [] - - for port in allow_list: - - # Enables the interfaces - information = self.dut.send_expect( - "./usertools/dpdk-devbind.py --status | grep '%s'" % port, "# " - ) - data = information.split(" ") - for field in data: - if field.rfind("if=") != -1: - interface_aux = field.replace("if=", "") - port_virtual_interaces.append(interface_aux) - self.dut.send_expect("ifconfig %s up" % interface_aux, "# ") - - self.dut.send_expect("echo 1 > /proc/sys/net/ipv4/ip_forward", "# ") - - for port in range(0, ports_without_kni): - tx_port = self.tester.get_local_port(dut_ports[port]) - self.dut.send_expect( - "ifconfig %s 192.170.%d.1 up" - % (port_virtual_interaces[port], port + 100), - "# ", - ) - self.dut.send_expect( - "route add -net 192.170.%d.0 netmask 255.255.255.0 gw 192.170.%d.1" - % (port + 100, port + 100), - "# ", - ) - self.dut.send_expect( - "arp -s 192.170.%d.2 %s" % (port + 100, self.tester.get_mac(tx_port)), - "# ", - ) - - one_port_resutls_row = [1] - two_port_resutls_row = [2] - for packet_size in packet_sizes_routing: - - payload_size = packet_size - 38 - tgen_input = [] - - # Prepare test with 1 port - tx_port = self.tester.get_local_port(dut_ports[0]) - rx_mac = self.dut.get_mac_address(dut_ports[0]) - self.tester.scapy_append("flows = []") - self.tester.scapy_append( - 'flows.append(Ether(dst="%s")/IP(src="192.170.100.2",dst="192.170.100.2")/("X"*%d))' - % (rx_mac, payload_size) - ) - pcap = os.sep.join([self.output_path, "routePerf_1.pcap"]) - self.tester.scapy_append('wrpcap("%s",flows)' % pcap) - self.tester.scapy_execute() - - tgen_input = [] - tgen_input.append((tx_port, tx_port, pcap)) - - # Get throughput with 1 port - - # 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) - - one_port_resutls_row.append(float(pps) / 10**6) - self.result_table_add(one_port_resutls_row) - - # Prepare test with 'ports_without_kni' ports - cnt = 0 - for port in range(ports_without_kni): - rx_mac = self.dut.get_mac_address(dut_ports[port]) - tx_port = self.tester.get_local_port(dut_ports[port]) - self.tester.scapy_append("flows = []") - self.tester.scapy_append( - 'flows.append(Ether(dst="%s")/IP(src="192.170.%d.2",dst="192.170.%d.2")/("X"*%d))' - % ( - rx_mac, - 100 + port, - 100 + (port + 1) % ports_without_kni, - payload_size, - ) - ) - pcap = os.sep.join( - [ - self.output_path, - "routePerf_{0}_{1}.pcap".format(ports_without_kni, cnt), - ] - ) - tgen_input.append((tx_port, tx_port, pcap)) - self.tester.scapy_append('wrpcap("%s",flows)' % pcap) - self.tester.scapy_execute() - cnt += 1 - - # Get throughput with 'ports_without_kni' ports - # 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) - - two_port_resutls_row.append(float(pps) / 10**6) - self.result_table_add(two_port_resutls_row) - - self.result_table_print() - - for port in allow_list: - self.dut.send_expect( - "./usertools/dpdk-devbind.py -b %s %s" % (self.drivername, port), "# " - ) - - def tear_down(self): - """ - Run after each test case. - """ - if self._suite_result.test_case == "test_ping": - for port in self.config["ports"]: - tx_port = self.tester.get_local_port(port) - tx_interface = self.tester.get_interface(tx_port) - self.tester.send_expect("ip addr flush %s" % tx_interface, "# ") - - def tear_down_all(self): - """ - Run after each test suite. - """ - self.dut.kill_all() - self.dut.send_expect("rmmod rte_kni", "# ", 10) - # disable dut ipv6 - self.dut.disable_ipv6("all") -- 2.17.1