* [dts] [PATCH V1 1/4] add kni test plan @ 2015-09-02 3:08 Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 2/4] add kni test case Huilong Xu ` (3 more replies) 0 siblings, 4 replies; 5+ messages in thread From: Huilong Xu @ 2015-09-02 3:08 UTC (permalink / raw) To: dts; +Cc: lijuanx.a.tu From: "huilongx,xu" <huilongx.xu@intel.com> Signed-off-by: huilongx,xu <huilongx.xu@intel.com> --- test_plans/kni_test_plan.rst | 608 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 608 insertions(+) create mode 100644 test_plans/kni_test_plan.rst diff --git a/test_plans/kni_test_plan.rst b/test_plans/kni_test_plan.rst new file mode 100644 index 0000000..94a0b76 --- /dev/null +++ b/test_plans/kni_test_plan.rst @@ -0,0 +1,608 @@ +.. Copyright (c) <2010,2011>, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +==================== +Kernel NIC Interface +==================== + +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. + +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 +============= + +Support igb_uio and vfio driver, if used vfio, kernel need 3.6+ and enable vt-d in bios. +When used vfio , used "modprobe vfio" and "modprobe vfio-pci" insmod vfiod driver, then used +"./tools/dpdk_nic_bind.py --bind=vfio-pci device_bus_id" to bind vfio driver to test driver. + + +The DUT has at least 2 DPDK supported IXGBE 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/kni/build/app/kni -c 0xa0001e -n 4 -- -P -p 0x3 --config="(0,1,2,21),(1,3,4,23)" & + + +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``:: + + ./build/app/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<BROADCAST,MULTICAST> 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<BROADCAST,MULTICAST> 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<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 + inet6 fe80::92e2:baff:fe37:92f8 prefixlen 64 scopeid 0x20<link> + 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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<BROADCAST,MULTICAST> 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 belowing 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" + ./build/app/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 <Changing Parameters> + ./build/app/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 <lo_mode and kthread_mode parameters> + ./examples/kni/build/app/kni -c <Core mask> -n 4 -- -P -p <Port mask> --config="<Ports/Cores configuration>" & + + +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 <kthread_mode parameter> + ./build/app/kni -c <Core mask> -n 4 -- -P -p <Port mask> --config="<Ports/Cores configuration>" & + + 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 <kthread_mode parameter> + ./build/app/kni -c <Core mask> -n 4 -- -P -p <Port mask> --config="<Ports/Cores configuration>" & + + ifconfig vEth2_0 192.170.2.1 + ifconfig vEth2_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 vEth2_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 | | | ++-------+-------+-------+ -- 1.9.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [dts] [PATCH V1 2/4] add kni test case 2015-09-02 3:08 [dts] [PATCH V1 1/4] add kni test plan Huilong Xu @ 2015-09-02 3:08 ` Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 3/4] kni not support on freebsd os, skip test on freebsd Huilong Xu ` (2 subsequent siblings) 3 siblings, 0 replies; 5+ messages in thread From: Huilong Xu @ 2015-09-02 3:08 UTC (permalink / raw) To: dts; +Cc: lijuanx.a.tu From: "huilongx,xu" <huilongx.xu@intel.com> Signed-off-by: huilongx,xu <huilongx.xu@intel.com> --- tests/TestSuite_kni.py | 1207 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1207 insertions(+) create mode 100644 tests/TestSuite_kni.py diff --git a/tests/TestSuite_kni.py b/tests/TestSuite_kni.py new file mode 100644 index 0000000..14c100b --- /dev/null +++ b/tests/TestSuite_kni.py @@ -0,0 +1,1207 @@ +# <COPYRIGHT_TAG> +# BSD LICENSE +# +# Copyright(c) 2010-2015 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +DPDK Test suite. + +Test Kernel NIC Interface. +""" + +import dts +import re +import time +from random import randint + +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.0.1})' +default_2_port_cores_config = '(P0,C{1.0.0},C{1.1.0},C{1.0.1}),(P1,C{1.2.0},C{1.3.0},C{1.2.1})' + +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: Error: 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': 'KNI: Error: Invalid parameter for kthread_mode'}, + {'lo_mode': 'lo_mode_random', 'kthread_mode': 'multiple', + 'output': 'KNI: Incognizant parameter, loopback disabled'} + ] + + +from test_case import TestCase + +# +# +# 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.send_expect("make -C ./examples/kni/", "# ", 5) + self.verify('Error' not in out, "Compilation failed") + + self.extract_ports_cores_config(default_1_port_cores_config) + self.start_kni() + self.verify("Error" not in out, "Error found during kni start") + + self.dut.send_expect("service iptables stop", "# ") + self.dut.send_expect("service firewalld stop", "# ") + + 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 dts.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() + 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 = dts.create_mask(self.config['ports']) + core_mask = dts.create_mask( + self.config['rx_cores'] + self.config['tx_cores'] + self.config['kernel_cores']) + + config_param = self.build_config_param() + + out_kni = self.dut.send_expect( + './examples/kni/build/app/kni -c %s -n %d -- -P -p %s %s &' % + (core_mask, self.dut.get_memory_channels(), port_mask, config_param), + "APP: Lcore [0-9]+ is reading from port [0-9]+", 10) + + if kthread_mode == 'single': + kthread_mask = dts.create_mask(self.config['kernel_cores']) + out = self.dut.send_expect( + "taskset -p %s `pgrep -fl kni_single | awk '{print $1}'`" % kthread_mask, "#") + self.verify( + 'new 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_white_list(self, target, nic): + """ + Create white list with ports. + """ + white_list = [] + dut_ports = self.dut.get_ports(self.nic) + self.dut.restore_interfaces() + allPort = self.dut.ports_info + if dts.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: + white_list.append(allPort[port]['pci']) + return white_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) + + # Set up + 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") + + out = self.dut.send_expect( + "ip -family inet6 address show dev %s" % virtual_interface, "# ") + self.verify( + "inet6 " in out, "ifconfig up the port_virtual_interaces not support") + + # 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 + 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, "# ") + self.dut.send_expect( + "ifconfig %s 192.168.%d.1" % (virtual_interface, port), "# ") + self.tester.send_expect( + "ifconfig %s 192.168.%d.2" % (tx_interface, port), "# ") + self.tester.enable_ipv6(tx_interface) + time.sleep(1) + # Send ping requests and check for answers + for port in self.config['ports']: + + 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 1 -I %s 192.168.%d.1" % (virtual_interface, port), "# ", 5) + self.verify("64 bytes from 192.168.%d.1:" % + port in out, "ping not supported") + + out = self.dut.send_expect( + "ping -w 1 -I %s 192.168.%d.2" % (virtual_interface, port), "# ", 5) + self.verify("64 bytes from 192.168.%d.2:" % + port in out, "ping not supported") + + out = self.tester.send_expect( + "ping -w 1 -I %s 192.168.%d.1" % (tx_interface, port), "# ", 5) + self.verify("64 bytes from 192.168.%d.1:" % + port in out, "kni cannot reply ping packet") + + out = self.dut.send_expect( + "ping -w 1 -I %s 192.168.%d.123" % (virtual_interface, port), "# ", 5) + self.verify( + "0 received, 100% packet loss" in out, "ping not supported") + + out = self.dut.send_expect( + "ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'| cut -d'/' -f1" % virtual_interface, "# ", 5) + ipv6_address = out.split('\r\n')[0] + + out = self.dut.send_expect("ping6 -w 1 -I %s %s" % + (virtual_interface, str(ipv6_address)), "# ", 5) + self.verify("64 bytes from %s: icmp_seq=1 ttl=64" % + ipv6_address in out, "ping6 not supported") + + out = self.tester.send_expect( + "ping6 -w 1 -I %s %s" % (tx_interface, str(ipv6_address)), "# ", 5) + self.verify("64 bytes from %s: icmp_seq=1 ttl=64" % + ipv6_address in out, "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" % + (virtual_interface, ''.join(ipv6list)), "# ", 5) + self.verify( + "0 received, 100% packet loss" in out, "ping6 not supported") + + 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 + for port in self.config['ports']: + + 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, "# ") + + # 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 packet.log "ether src %s and ether dst %s"' % + (virtual_interface, 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_ethtool(self): + """ + Ethtool support KNI. + """ + + # 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) + + # Request settings + out = self.dut.send_expect("ethtool %s" % virtual_interface, + "# ") + self.verify("Settings for %s" % virtual_interface in out, + "ethtool not supported") + self.verify("Operation not supported" not in out, + "ethtool not supported") + + # Request driver information + out = self.dut.send_expect("ethtool -i %s" % virtual_interface, + "# ") + self.verify("driver: ixgbe" or "driver: igb" in out, + "'ethtool -i' not supported") + self.verify("Operation not supported" not in out, + "'ethtool -i' not supported") + + # Request pause parameters + out = self.dut.send_expect("ethtool -a %s" % virtual_interface, + "# ") + self.verify("Pause parameters for %s" % virtual_interface in out, + "'ethtool -a' not supported") + self.verify("Operation not supported" not in out, + "ethtool '-a' not supported") + + # Request statistics + out = self.dut.send_expect("ethtool -S %s" % virtual_interface, + "# ") + self.verify("NIC statistics" in out, + "'ethtool -S' not supported") + self.verify("Operation not supported" not in out, + "ethtool '-S' not supported") + + # Request features status + out = self.dut.send_expect("ethtool -k %s" % virtual_interface, "# ") + self.verify(("Features for %s" % virtual_interface in out) or + ("Offload parameters for %s" % + virtual_interface in out), + "'ethtool -k' not supported") + self.verify("Operation not supported" not in out, + "'ethtool -k' not supported") + + # Request ring parameters + out = self.dut.send_expect("ethtool -g %s" % virtual_interface, + "# ") + self.verify("Ring parameters for %s" % virtual_interface in out, + "'ethtool -g' not supported") + self.verify("Operation not supported" not in out, + "'ethtool -g' not supported") + + # Request coalesce parameters. NOT SUPORTED + out = self.dut.send_expect("ethtool -c %s" % virtual_interface, + "# ") + self.verify("Operation not supported" in out, + "'ethtool -c' seems to be supported. Check it.") + + # Request register dump + out = self.dut.send_expect("ethtool -d %s" % virtual_interface, + "# ") + self.verify("Link Status register" in out, + "'ethtool -d' not supported") + self.verify("Operation not supported" not in out, + "'ethtool -d' not supported") + + # Request eeprom dump + out = self.dut.send_expect("ethtool -e %s" % virtual_interface, + "# ") + self.verify("Offset" and "Values" in out, + "'ethtool -e' not support") + self.verify("Operation not supported" not in out, + "'ethtool -e' not support") + + 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, "# ") + time.sleep(5) + 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) + + self.tester.scapy_append('dstmac = "%s"' % rx_mac) + self.tester.scapy_append('srcmac = "%s"' % tx_mac) + + self.tester.scapy_append( + 'sendp([Ether(src = srcmac,dst=dstmac)/IP()/UDP()/("X"*28)],iface="%s")' % tx_interface) + self.tester.scapy_append( + 'sendp([Ether(src = srcmac,dst=dstmac)/IP()/TCP()/("X"*28)],iface="%s")' % tx_interface) + self.tester.scapy_append( + 'sendp([Ether(src = srcmac,dst=dstmac)/IP()/ICMP()/("X"*28)],iface="%s")' % tx_interface) + self.tester.scapy_append( + 'sendp([Ether(src = srcmac,dst=dstmac)/IP()/("X"*38)],iface="%s")' % tx_interface) + self.tester.scapy_append( + 'sendp([Ether(src = srcmac,dst=dstmac)/("X"*46)],iface="%s")' % tx_interface) + self.tester.scapy_execute() + + 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 + 5), + "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") + except: + # some permutations have to fail + pass + + out = self.dut.send_expect('dmesg -c | grep "KNI"', "]# ") + self.verify(len(re.findall(expectedMessage, out, re.DOTALL)) > 0, + "Module not properly loaded") + + 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) + + dts.results_table_add_header(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(): + print dts.RED("Skiping 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) + self.tester.scapy_append( + 'wrpcap("tester%d.pcap",flows)' % tx_port) + self.tester.scapy_execute() + tgen_input.append( + (tx_port, tx_port, "tester%d.pcap" % tx_port)) + + time.sleep(1) + _, pps = self.tester.traffic_generator_throughput(tgen_input) + 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 + dts.results_table_add_row(results_row) + + self.dut.kill_all() + + dts.results_table_print() + + def test_perf_bridge(self): + """ + KNI performance bridge mode. + """ + dts.results_table_add_header(bridge_perf_results_header) + + self.tester.scapy_append('srcmac="00:00:00:00:00:01"') + self.tester.scapy_append( + 'wrpcap("kni.pcap", [Ether(src=srcmac, dst="ff:ff:ff:ff:ff:ff")/IP(len=46)/UDP()/("X"*18)])') + 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(): + print dts.RED("Skiping 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", "# ") + time.sleep(3) + + 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, "kni.pcap")) + + if step['flows'] == 2: + tgenInput.append((rx_port, tx_port, "kni.pcap")) + + time.sleep(1) + _, pps = self.tester.traffic_generator_throughput(tgenInput) + step['pps'] = float(pps) / 10 ** 6 + + results_row = [step['kthread_mode'], step['flows'], + self.stripped_config_param(), (float(pps) / 10 ** 6)] + + dts.results_table_add_row(results_row) + + self.dut.send_expect("ifconfig br_kni down", "# ") + self.dut.send_expect("brctl delbr \"br_kni\"", "# ", 10) + + dts.results_table_print() + + def test_perf_bridge_without_kni(self): + """ + Bridge mode performance without KNI. + """ + dts.results_table_add_header(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"') + self.tester.scapy_append( + 'wrpcap("kni.pcap", [Ether(src=srcmac, dst="ff:ff:ff:ff:ff:ff")/IP(len=46)/UDP()/("X"*18)])') + self.tester.scapy_execute() + + white_list = self.make_white_list(self.target, self.nic) + port_virtual_interaces = [] + for port in white_list: + information = self.dut.send_expect( + "./tools/dpdk_nic_bind.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): + tgenInput = [] + tgenInput.append((tx_port, rx_port, "kni.pcap")) + + if flows == 2: + tgenInput.append((rx_port, tx_port, "kni.pcap")) + + _, pps = self.tester.traffic_generator_throughput(tgenInput) + dts.results_table_add_row([flows, float(pps) / 10 ** 6]) + + self.dut.send_expect("ifconfig br1 down", "# ") + self.dut.send_expect("brctl delbr \"br1\"", "# ", 30) + + for port in white_list: + self.dut.send_expect( + "./tools/dpdk_nic_bind.py -b igb_uio %s" % (port), "# ") + dts.results_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) + + dts.results_table_add_header(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]) + self.tester.scapy_append('flows = []') + + self.tester.scapy_append('flows = []') + port_iterator = 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.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 + + tgen_input.append((tx_port, tx_port, "routePerf.pcap")) + + self.tester.scapy_append('wrpcap("routePerf.pcap",flows)') + self.tester.scapy_execute() + + time.sleep(1) + _, pps = self.tester.traffic_generator_throughput(tgen_input) + resutls_row.append(float(pps) / 10 ** 6) + + dts.results_table_add_row(resutls_row) + + dts.results_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) + + dts.results_table_add_header(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) + + white_list = self.make_white_list(self.target, self.nic) + port_virtual_interaces = [] + + for port in white_list: + + # Enables the interfaces + information = self.dut.send_expect( + "./tools/dpdk_nic_bind.py --status | grep '%s'" % port, "# ") + print information + 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)) + self.tester.scapy_append('wrpcap("routePerf_1.pcap",flows)') + self.tester.scapy_execute() + + tgen_input = [] + tgen_input.append((tx_port, tx_port, "routePerf_1.pcap")) + + # Get throughput with 1 port + _, pps = self.tester.traffic_generator_throughput(tgen_input) + one_port_resutls_row.append(float(pps) / 10 ** 6) + dts.results_table_add_row(one_port_resutls_row) + + # Prepare test with 'ports_without_kni' ports + self.tester.scapy_append('flows = []') + 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.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)) + tgen_input.append((tx_port, tx_port, "routePerf.pcap")) + + self.tester.scapy_append( + 'wrpcap("routePerf_%d.pcap",flows)' % ports_without_kni) + self.tester.scapy_execute() + + # Get throughput with 'ports_without_kni' ports + _, pps = self.tester.traffic_generator_throughput(tgen_input) + two_port_resutls_row.append(float(pps) / 10 ** 6) + dts.results_table_add_row(two_port_resutls_row) + + dts.results_table_print() + + for port in white_list: + self.dut.send_expect( + "./tools/dpdk_nic_bind.py -b %s %s" % (dts.drivername, port), "# ") + + def tear_down(self): + """ + Run after each test case. + """ + pass + + def tear_down_all(self): + """ + Run after each test suite. + """ + self.dut.kill_all() + self.dut.send_expect("rmmod rte_kni", "# ", 10) -- 1.9.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [dts] [PATCH V1 3/4] kni not support on freebsd os, skip test on freebsd 2015-09-02 3:08 [dts] [PATCH V1 1/4] add kni test plan Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 2/4] add kni test case Huilong Xu @ 2015-09-02 3:08 ` Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 4/4] add kni test suite on niantic and fvl NIC test Huilong Xu 2015-09-02 6:07 ` [dts] [PATCH V1 1/4] add kni test plan Liu, Yong 3 siblings, 0 replies; 5+ messages in thread From: Huilong Xu @ 2015-09-02 3:08 UTC (permalink / raw) To: dts; +Cc: lijuanx.a.tu From: "huilongx,xu" <huilongx.xu@intel.com> Signed-off-by: huilongx,xu <huilongx.xu@intel.com> --- conf/dpdk_test_case_checklist.xls | Bin 19968 -> 20480 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/conf/dpdk_test_case_checklist.xls b/conf/dpdk_test_case_checklist.xls index de3f5a286093a9e43dffe43128196336b89418a5..c6464d7017e0711b280e5e4034ef18a52ef9d133 100644 GIT binary patch delta 1170 zcma)+&rj1}7{{NtuA^;$*06OY!K8`<8JOrsbR!59qLGO4z+Zr)uqL=Jv?QKZjKPD6 zk?>wUaPs5@OH53Rfr~#ld6UEo7cX-0WP(xW^Fp(>W(N;l-|zQ%-p}*AKf2XtWOb9Q zkCNW4YwrokQl9fV&H=!mMx()=KK}`4la0ju=~vVB-rUzu1a2MF+50?QNj&6s4F6}M zpCgl07d5)sCjQSz5@DTS5e|;0NvTjOf+h{a8!m_{!dV0=g4)hOCd^{BmIPKy5mNNA z&=HJY1S3r<h73%W#$t1^LZtpl1x*?cr!eY$kx?IsEX?Zdh*;0x6TN}Hy#lreNtmse zrh9n}I$?V(;^dh#GC}RaOvjl+0>5C6uVeh8|Do_BVF>`%LfNh^Sc?gOnpIsy$8;;M zZ7(@(0B*T9zjCjZ1aRDC({Us=m~$=1waP5Muxy%lo%tTjteE<pS-onzy0cQN*~_l( zRxC#^&pBoT@^rU2nEa9l=;7(N;)d9bJsb=JDD>mhAR+!%NhYM*-yK;ap1>*4b-bt{ zb}|4&2Ii$&c<C0N+QQ4U@U(xt-+;>l@NbWnc#jFzgbZ2yJy8VJU{i6ZaAShlshHwX z4FxgQwhVnu6{V!`-i4GDG$|gIPeByJRw_e(fJs9Xla681AqFYw7=`VP3>N~58l$KY ziYI{@!>BO~+fEq<0!$``$wV*`eksj0VKbQ+g&lwlxqzZYDVIQtVYC=VYhpgb71+l+ zdqAHWS-NSo({1BwXBWot+Ta0VCQpxyY3|)P-J8l0Lbpl}==aHeZpMfi+cbB5;^mFk P9Dn#6|5N<8Hz)bO*rC!N delta 512 zcmZozz}PT{ae@t_(nj0kjEpLiS()lN|NZ~}AB0smPh`qxoS48ei6upl`DF2gqh~KL z3gq_3-M@T+QF(GHOEZ&}{pMdR>P(DDlNC56CNE&;B!<Ps$uNPDfq{XE0j!Nn1i=;H zkl-?5*uw;s72r?=8YsXa#>2!Qj!*@%D~AJQmjH*z<Sq_gC~FOrCBbEZFaxNV%ML{^ z&;}&?AvQ>G*(0=oOs(JqncBt)k_Op#fD>rn=2M*Ynrbn|K<6>AF$8C%rj{7CGVn3T z*&vA+fkc+rPR=*>;k|0X#PEmVH%kIgUUl;c<8Lg?{~5F<t6OSMj<TG<B@7fUGGSn7 zv!0ybrp3sxS>B4Dkx_WFzI7|(W*u7xR_^NzS`2&G7#K1bLnbS_C{OlsG3R3gh8zO} zBhUpv7SrT@7f&VwTZjRZ<*gbg^SE!BY~`lHw9O7h@XO=|ziFF1b~3THRso}M^FA*p FRsfazfL;Iq -- 1.9.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [dts] [PATCH V1 4/4] add kni test suite on niantic and fvl NIC test 2015-09-02 3:08 [dts] [PATCH V1 1/4] add kni test plan Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 2/4] add kni test case Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 3/4] kni not support on freebsd os, skip test on freebsd Huilong Xu @ 2015-09-02 3:08 ` Huilong Xu 2015-09-02 6:07 ` [dts] [PATCH V1 1/4] add kni test plan Liu, Yong 3 siblings, 0 replies; 5+ messages in thread From: Huilong Xu @ 2015-09-02 3:08 UTC (permalink / raw) To: dts; +Cc: lijuanx.a.tu From: "huilongx,xu" <huilongx.xu@intel.com> Signed-off-by: huilongx,xu <huilongx.xu@intel.com> --- executions/execution.cfg | 3 ++- executions/execution_FVL.cfg | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/executions/execution.cfg b/executions/execution.cfg index 6e42b90..20d9bd6 100644 --- a/executions/execution.cfg +++ b/executions/execution.cfg @@ -25,7 +25,8 @@ test_suites= scatter, pmdrssreta, pmd, - l2fwd + l2fwd, + kni targets= x86_64-native-linuxapp-gcc parameters=nic_type=cfg:func=true diff --git a/executions/execution_FVL.cfg b/executions/execution_FVL.cfg index 9f25802..7bdd2b7 100644 --- a/executions/execution_FVL.cfg +++ b/executions/execution_FVL.cfg @@ -26,7 +26,8 @@ test_suites= scatter, pmdrssreta, pmdrss_hash, - ieee1588 + ieee1588, + kni targets= x86_64-native-linuxapp-gcc parameters=nic_type=cfg:func=true -- 1.9.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [dts] [PATCH V1 1/4] add kni test plan 2015-09-02 3:08 [dts] [PATCH V1 1/4] add kni test plan Huilong Xu ` (2 preceding siblings ...) 2015-09-02 3:08 ` [dts] [PATCH V1 4/4] add kni test suite on niantic and fvl NIC test Huilong Xu @ 2015-09-02 6:07 ` Liu, Yong 3 siblings, 0 replies; 5+ messages in thread From: Liu, Yong @ 2015-09-02 6:07 UTC (permalink / raw) To: Xu, HuilongX, dts; +Cc: Tu, LijuanX A Thanks huilong. Some comments in the plan. > -----Original Message----- > From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of Huilong Xu > Sent: Wednesday, September 02, 2015 11:09 AM > To: dts@dpdk.org > Cc: Tu, LijuanX A > Subject: [dts] [PATCH V1 1/4] add kni test plan > > From: "huilongx,xu" <huilongx.xu@intel.com> > > Signed-off-by: huilongx,xu <huilongx.xu@intel.com> > --- > test_plans/kni_test_plan.rst | 608 > +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 608 insertions(+) > create mode 100644 test_plans/kni_test_plan.rst > > diff --git a/test_plans/kni_test_plan.rst b/test_plans/kni_test_plan.rst > new file mode 100644 > index 0000000..94a0b76 > --- /dev/null > +++ b/test_plans/kni_test_plan.rst > @@ -0,0 +1,608 @@ > +.. Copyright (c) <2010,2011>, Intel Corporation Copyright to 2015:) > + All rights reserved. > + > + Redistribution and use in source and binary forms, with or without > + modification, are permitted provided that the following conditions > + are met: > + > + - Redistributions of source code must retain the above copyright > + notice, this list of conditions and the following disclaimer. > + > + - Redistributions in binary form must reproduce the above copyright > + notice, this list of conditions and the following disclaimer in > + the documentation and/or other materials provided with the > + distribution. > + > + - Neither the name of Intel Corporation nor the names of its > + contributors may be used to endorse or promote products derived > + from this software without specific prior written permission. > + > + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS > + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE > + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, > + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES > + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR > + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, > + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED > + OF THE POSSIBILITY OF SUCH DAMAGE. > + > +==================== > +Kernel NIC Interface > +==================== > + > +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. > + > +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" > + Can you give us more information about the parameters? It can help us known what's the difference of lo_mode_ring and lo_mode_ring_sk. > +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" > + Need more description of kthread_mode parameter. > + > +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 > +============= > + > +Support igb_uio and vfio driver, if used vfio, kernel need 3.6+ and > enable vt-d in bios. > +When used vfio , used "modprobe vfio" and "modprobe vfio-pci" insmod > vfiod driver, then used > +"./tools/dpdk_nic_bind.py --bind=vfio-pci device_bus_id" to bind vfio > driver to test driver. > + > + > +The DUT has at least 2 DPDK supported IXGBE NIC ports. > + I think two NICs supported by DPDK are enough. Not only IXGBE NIC. > +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/kni/build/app/kni -c 0xa0001e -n 4 -- -P -p 0x3 -- > config="(0,1,2,21),(1,3,4,23)" & > + What's meaning of lcore 21, please use "S0/C1/T1" to clarify that. > + > +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``:: > + > + ./build/app/kni -c 0xa0001e -n 4 -- -P -p 0xc -- > config="(2,1,2,21),(3,3,4,23)" > + This command use port2 and port3, thus mean this case need at least four ports? If so, please change test prerequisites. > + > +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<BROADCAST,MULTICAST> 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<BROADCAST,MULTICAST> 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<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 > + inet6 fe80::92e2:baff:fe37:92f8 prefixlen 64 scopeid > 0x20<link> > + 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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<BROADCAST,MULTICAST> 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 belowing 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" > + ./build/app/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 <Changing Parameters> > + ./build/app/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 <lo_mode and > kthread_mode parameters> > + ./examples/kni/build/app/kni -c <Core mask> -n 4 -- -P -p <Port mask> > --config="<Ports/Cores configuration>" & > + > + > +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 <kthread_mode > parameter> > + ./build/app/kni -c <Core mask> -n 4 -- -P -p <Port mask> -- > config="<Ports/Cores configuration>" & > + > + 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 | > ++==============+=======+=============================+=======+ > +| | | | | > ++--------------+-------+-----------------------------+-------+ > + Please extend the table with detail configurations with Rx/Tx/Kernel core settings. >From this table, we have no idea that what core combination the case is profiling. > +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 > + > + Some questions here, if rmmod kni module and kill kni process, how does the virtual interface like vEth2_0 receive packets? > +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 | | > ++-------+-------+ > + Same comment in performance table. > +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 <kthread_mode > parameter> > + ./build/app/kni -c <Core mask> -n 4 -- -P -p <Port mask> -- > config="<Ports/Cores configuration>" & > + > + ifconfig vEth2_0 192.170.2.1 > + ifconfig vEth2_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 | > ++==============+=======+=============================+=======+=======+ > +| | | | | | > ++--------------+-------+-----------------------------+-------+-------+ > + Same comment in performance table. > + > +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 vEth2_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 | | | > ++-------+-------+-------+ > -- Same comment in performance table. > 1.9.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-09-02 6:07 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-09-02 3:08 [dts] [PATCH V1 1/4] add kni test plan Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 2/4] add kni test case Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 3/4] kni not support on freebsd os, skip test on freebsd Huilong Xu 2015-09-02 3:08 ` [dts] [PATCH V1 4/4] add kni test suite on niantic and fvl NIC test Huilong Xu 2015-09-02 6:07 ` [dts] [PATCH V1 1/4] add kni test plan Liu, Yong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).