test suite reviews and discussions
 help / color / mirror / Atom feed
* [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).