From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id C92A38E5E for ; Fri, 15 Jan 2016 08:34:02 +0100 (CET) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 14 Jan 2016 23:34:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,298,1449561600"; d="scan'208";a="893676916" Received: from unknown (HELO dpdk-fedora20.icx.intel.com) ([10.238.55.12]) by fmsmga002.fm.intel.com with ESMTP; 14 Jan 2016 23:34:00 -0800 From: Lijuan Tu To: dts@dpdk.org Date: Fri, 15 Jan 2016 15:29:37 +0800 Message-Id: <1452842977-19313-1-git-send-email-lijuanx.a.tu@intel.com> X-Mailer: git-send-email 1.9.3 Subject: [dts] [PATCH V2] Add vf port start/stop test script, test plan and config file X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2016 07:34:03 -0000 Send packets from tester ,at the same time, vf prot start/stop several time and check if it running right. Three files added in the patch: 1, vf_port_start_stop.cfg: vm setting and qemu parameters. 2, vf_port_start_stop_test_plan.rst: test plan, describe 1 case. 3, TestSuite_vf_port_start_stop.py: implement one case according to the tes plan. Signed-off-by: Lijuan Tu --- conf/vf_port_start_stop.cfg | 107 ++++++++++++ test_plans/vf_port_start_stop_test_plan.rst | 168 +++++++++++++++++++ tests/TestSuite_vf_port_start_stop.py | 243 ++++++++++++++++++++++++++++ 3 files changed, 518 insertions(+) create mode 100644 conf/vf_port_start_stop.cfg create mode 100644 test_plans/vf_port_start_stop_test_plan.rst create mode 100644 tests/TestSuite_vf_port_start_stop.py diff --git a/conf/vf_port_start_stop.cfg b/conf/vf_port_start_stop.cfg new file mode 100644 index 0000000..ab1c0c7 --- /dev/null +++ b/conf/vf_port_start_stop.cfg @@ -0,0 +1,107 @@ +# QEMU options +# name +# name: vm0 +# +# enable_kvm +# enable: [yes | no] +# +# cpu +# model: [host | core2duo | ...] +# usage: +# choose model value from the command +# qemu-system-x86_64 -cpu help +# number: '4' #number of vcpus +# cpupin: '3 4 5 6' # host cpu list +# +# mem +# size: 1024 +# +# disk +# file: /path/to/image/test.img +# +# net +# type: [nic | user | tap | bridge | ...] +# nic +# opt_vlan: 0 +# note: Default is 0. +# opt_macaddr: 00:00:00:00:01:01 +# note: if creating a nic, it`s better to specify a MAC, +# else it will get a random number. +# opt_model:["e1000" | "virtio" | "i82551" | ...] +# note: Default is e1000. +# opt_name: 'nic1' +# opt_addr: '' +# note: PCI cards only. +# opt_vectors: +# note: This option currently only affects virtio cards. +# user +# opt_vlan: 0 +# note: default is 0. +# opt_hostfwd: [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport +# note: If not specified, it will be setted automatically. +# tap +# opt_vlan: 0 +# note: default is 0. +# opt_br: br0 +# note: if choosing tap, need to specify bridge name, +# else it will be br0. +# opt_script: QEMU_IFUP_PATH +# note: if not specified, default is self.QEMU_IFUP_PATH. +# opt_downscript: QEMU_IFDOWN_PATH +# note: if not specified, default is self.QEMU_IFDOWN_PATH. +# +# device +# driver: [pci-assign | virtio-net-pci | ...] +# pci-assign +# prop_host: 08:00.0 +# prop_addr: 00:00:00:00:01:02 +# virtio-net-pci +# prop_netdev: mynet1 +# prop_id: net1 +# prop_mac: 00:00:00:00:01:03 +# prop_bus: pci.0 +# prop_addr: 0x3 +# +# monitor +# port: 6061 +# note: if adding monitor to vm, need to specicy +# this port, else it will get a free port +# on the host machine. +# +# qga +# enable: [yes | no] +# +# serial_port +# enable: [yes | no] +# +# vnc +# displayNum: 1 +# note: you can choose a number not used on the host. +# +# daemon +# enable: 'yes' +# note: +# By default VM will start with the daemonize status. +# Not support starting it on the stdin now. + +# vm configuration for pmd sriov case +[vm0] +cpu = + model=host,number=4,cpupin=5 6 7 8 9; +disk = + file=/home/image/fedora23.img; +mem = + size=8196 +login = + user=root,password=tester; +net = + type=nic,opt_vlan=0; + type=user,opt_vlan=0; +monitor = + port=; +qga = + enable=yes; +vnc = + displayNum=11; +daemon = + enable=yes; diff --git a/test_plans/vf_port_start_stop_test_plan.rst b/test_plans/vf_port_start_stop_test_plan.rst new file mode 100644 index 0000000..c0ce8a4 --- /dev/null +++ b/test_plans/vf_port_start_stop_test_plan.rst @@ -0,0 +1,168 @@ +.. Copyright (c) <2015>, 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. + +Prerequisites +========================================= + +Create Two VF interfaces from two kernel PF ineterfaces, and then attach them to VM. Suppose PF is 0000:04:00.0. Generate 2VFs using commands below and make them in pci-stub mods. + +1. Get the pci device id of DUT:: + + ./dpdk_nic_bind.py --st + 0000:04:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' if=ens261f0 drv=ixgbe unused=igb_uio + +2. Create 2 VFs from 2 PFs:: + + echo 2 > /sys/bus/pci/devices/0000\:04\:00.0/sriov_numvfs + +VFs 04:10.0 & 04:10.1 have been created:: + + ./dpdk_nic_bind.py --st + 0000:04:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' if=ens261f0 drv=ixgbe unused= + 0000:04:10.0 '82599 Ethernet Controller Virtual Function' if=enp4s16 drv=ixgbevf unused= + 0000:04:10.1 '82599 Ethernet Controller Virtual Function' if=enp4s16f1 drv=ixgbevf unused= + +3. detach VFs from the host, bind them to pci-stub driver:: + + /sbin/modprobe pci-stub + echo "8086 10ed" > /sys/bus/pci/drivers/pci-stub/new_id + echo 0000:04:10.0 > /sys/bus/pci/devices/0000\:04\:10.0/driver/unbind + echo 0000:04:10.0 > /sys/bus/pci/drivers/pci-stub/bind + echo 0000:04:10.1 > /sys/bus/pci/devices/0000\:04\:10.1/driver/unbind + echo 0000:04:10.1 > /sys/bus/pci/drivers/pci-stub/bind + +or using the following more easy way:: + + ./dpdk_nic_bind.py -b pci-stub 04:10.0 04:10.1 + +it can be seen that VFs 04:10.0 & 04:10.1 's drv is pci-stub:: + + ./dpdk_nic_bind.py --st + 0000:04:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' if=ens261f0 drv=ixgbe unused=vfio-pci + 0000:04:10.0 '82599 Ethernet Controller Virtual Function' if= drv=pci-stub unused=ixgbevf,vfio-pci + 0000:04:10.1 '82599 Ethernet Controller Virtual Function' if= drv=pci-stub unused=ixgbevf,vfio-pci + +4. Do not forget bring up PFs:: + + ifconfig ens261f0 up + +Passthrough VFs 04:10.0 & 04:10.1 to vm0, and start vm0, you can refer to below command:: + + taskset -c 6-12 qemu-system-x86_64 \ + -enable-kvm -m 8192 -smp 6 -cpu host -name dpdk15-vm1 \ + -drive file=/home/image/fedora23.img \ + -netdev tap,id=hostnet1,ifname=tap1,script=/etc/qemu-ifup,vhost=on \ + -device rtl8139,netdev=hostnet1,id=net1,mac=52:54:01:6b:10:61,bus=pci.0,addr=0xa \ + -device pci-assign,bus=pci.0,addr=0x6,host=04:10.0 \ + -device pci-assign,bus=pci.0,addr=0x7,host=04:10.1 \ + -vnc :11 -daemonize + +the /etc/qemu-ifup can be below script, need you to create first:: + + #!/bin/sh + set -x + switch=br0 + if [ -n "$1" ];then + /usr/sbin/tunctl -u `whoami` -t $1 + /sbin/ip link set $1 up + sleep 0.5s + /usr/sbin/brctl addif $switch $1 + exit 0 + else + echo "Error: no interface specified" + exit 1 + fi + +Set up bridge br0 before create /etc/qemu-ifup, for example:: + + cd /etc/sysconfig/network-scripts + vim ifcfg-enp1s0f0 + + HWADDR=00:1e:67:fb:0f:d4 + TYPE=Ethernet + NAME=enp1s0f0 + ONBOOT=yes + DEVICE=enp1s0f0 + NM_CONTROLLED=no + BRIDGE=br0 + + vim ifcfg-br0 + TYPE=Bridge + DEVICE=br0 + ONBOOT=yes + NM_CONTROLLED=no + BOOTPROTO=dhcp + HOSTNAME="dpdk-test58" + +Login vm0, got VFs pci device id in vm0, assume they are 00:06.0 & +00:07.0, bind them to igb_uio driver, and then start testpmd, set it in +mac forward mode:: + + ./tools/dpdk_nic_bind.py --bind=igb_uio 00:06.0 00:07.0 + ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x0f -n 4 -- -i + testpmd-> set fwd mac + testpmd-> start + +Test Case: port start/stop +========================== +Start send packets from tester , then start/stop ports several times ,verify if it running right. + +Commands could be used to start/stop ports refer to below:: + +Start port:: + + testpmd-> port start all + +Stop port:: + + testpmd-> port stop all + +Send IP+UDP packet:: + + Ether(dst="0E:CB:F8:FF:4E:02", src="0E:CB:F8:FF:4E:02")/IP(src="127.0.0.2")/UDP()/("X"*46) + +Send IP+TCP packet:: + + Ether(dst="0E:CB:F8:FF:4E:02", src="0E:CB:F8:FF:4E:02")/IP(src="127.0.0.2")/TCP()/("X"*46) + +Send IP+SCTP packet:: + + Ether(dst="0E:CB:F8:FF:4E:02", src="0E:CB:F8:FF:4E:02")/IP(src="127.0.0.2")/SCTP()/("X"*46) + +Send IPv6+UDP packet:: + + Ether(dst="0E:CB:F8:FF:4E:02", src="0E:CB:F8:FF:4E:02")/IP(src="::2")/UDP()/("X"*46) + +Send IPv6+TCP packet:: + + Ether(dst="0E:CB:F8:FF:4E:02", src="0E:CB:F8:FF:4E:02")/IP(src="::2")/TCP()/("X"*46) + diff --git a/tests/TestSuite_vf_port_start_stop.py b/tests/TestSuite_vf_port_start_stop.py new file mode 100644 index 0000000..7e3c74b --- /dev/null +++ b/tests/TestSuite_vf_port_start_stop.py @@ -0,0 +1,243 @@ +# + +import re +import time + +import dts +from qemu_kvm import QEMUKvm +from test_case import TestCase +from pmd_output import PmdOutput +from utils import RED, GREEN +from net_device import NetDevice +from crb import Crb +from scapy.all import * +VM_CORES_MASK = 'all' + +class TestVfPortStartStop(TestCase): + + def set_up_all(self): + + self.dut_ports = self.dut.get_ports(self.nic) + self.verify(len(self.dut_ports) >= 1, "Insufficient ports") + self.vm0 = None + self.filename = "/tmp/vf.pcap" + + def set_up(self): + + self.setup_1pf_2vf_1vm_env_flag = 0 + + def pktgen_prerequisites(self): + """ + igb_uio.ko should be put in ~ before you using pktgen + """ + out = self.tester.send_expect("ls", "#") + self.verify("igb_uio.ko" in out, "No file igb_uio.ko, please add it in ~") + self.tester.send_expect("modprobe uio", "#", 70) + out = self.tester.send_expect("lsmod | grep igb_uio", "#") + if "igb_uio" in out: + self.tester.send_expect("rmmod -f igb_uio", "#", 70) + self.tester.send_expect("insmod ~/igb_uio.ko", "#", 60) + out = self.tester.send_expect("lsmod | grep igb_uio", "#") + assert ("igb_uio" in out), "Failed to insmod igb_uio" + + total_huge_pages = self.tester.get_total_huge_pages() + if total_huge_pages == 0: + self.tester.mount_huge_pages() + self.tester.set_huge_pages(2048) + + def pktgen_kill(self): + """ + Kill all pktgen on tester. + """ + pids = [] + pid_reg = r'p(\d+)' + out = self.tester.alt_session.send_expect("lsof -Fp /var/run/.pg_config", "#", 20) + if len(out): + lines = out.split('\r\n') + for line in lines: + m = re.match(pid_reg, line) + if m: + pids.append(m.group(1)) + for pid in pids: + self.tester.alt_session.send_expect('kill -9 %s' % pid, '# ', 20) + + def send_and_verify(self, dst_mac, testpmd): + """ + Generates packets by pktgen + """ + self.testpmd_reset_status(testpmd) + + self.pktgen_prerequisites() + # bind ports + self.tester_tx_port = self.tester.get_local_port(self.dut_ports[0]) + self.tester_tx_pci = self.tester.ports_info[self.tester_tx_port]['pci'] + port = self.tester.ports_info[self.tester_tx_port]['port'] + self.tester_port_driver = port.get_nic_driver() + self.tester.send_expect("./dpdk_nic_bind.py --bind=igb_uio %s" % self.tester_tx_pci, "#") + + src_mac = self.tester.get_mac(self.tester_tx_port) + if src_mac == 'N/A': + src_mac = "02:00:00:00:01" + + self.create_pcap_file(self.filename, dst_mac, src_mac) + + self.tester.send_expect("./pktgen -c 0x1f -n 2 --proc-type auto --socket-mem 128,128 --file-prefix pg -- -P -T -m '1.0' -s 0:%s" % self.filename, "Pktgen >", 100) + time.sleep(1) + self.tester.send_expect("start all", "Pktgen>") + time.sleep(1) + self.check_port_start_stop(testpmd) + # quit pktgen + self.tester.send_expect("stop all", "Pktgen>") + self.tester.send_expect("quit", "# ") + + def create_pcap_file(self, filename, dst_mac, src_mac): + """ + Generates a valid PCAP file with the given configuration. + """ + def_pkts = {'IP/UDP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IP(src="127.0.0.2")/UDP()/("X"*46), + 'IP/TCP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IP(src="127.0.0.2")/TCP()/("X"*46), + 'IP/SCTP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IP(src="127.0.0.2")/SCTP()/("X"*48), + 'IPv6/UDP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IPv6(src="::2")/UDP()/("X"*46), + 'IPv6/TCP': Ether(dst="%s" % dst_mac, src="%s" % src_mac)/IPv6(src="::2")/TCP()/("X"*46),} + + pkts = [] + for key in def_pkts.keys(): + pkts.append(def_pkts[key]) + + wrpcap(filename, pkts) + + def testpmd_reset_status(self, testpmd): + """ + Reset testpmd :stop forword & stop port + """ + testpmd.execute_cmd('stop') + testpmd.execute_cmd('port stop all') + testpmd.execute_cmd('clear port stats all') + + def check_port_start_stop(self, testpmd, times=10): + """ + VF port start/stop several times , check if it work well. + """ + for i in range(times): + out = testpmd.execute_cmd('port start all') + self.verify("Checking link statuses" in out, "ERROR: port start all") + testpmd.execute_cmd('start') + time.sleep(.5) + testpmd.execute_cmd('stop') + out = testpmd.execute_cmd('port stop all') + self.verify("Checking link statuses" in out, "ERROR: port stop all") + + port_id_0 = 0 + port_id_1 = 1 + vf0_stats = self.vm0_testpmd.get_pmd_stats(port_id_0) + vf1_stats = self.vm0_testpmd.get_pmd_stats(port_id_1) + + vf0_rx_cnt = vf0_stats['RX-packets'] + self.verify(vf0_rx_cnt != 0, "no packet was received by vm0_VF0") + + vf0_rx_err = vf0_stats['RX-errors'] + self.verify(vf0_rx_err == 0, "vm0_VF0 rx-errors") + + vf1_tx_cnt = vf1_stats['TX-packets'] + self.verify(vf1_tx_cnt != 0, "no packet was transmitted by vm0_VF1") + + vf1_tx_err = vf1_stats['TX-errors'] + self.verify(vf1_tx_err == 0, "vm0_VF0 tx-errors") + + def setup_1pf_2vf_1vm_env(self, driver='default'): + + self.used_dut_port = self.dut_ports[0] + self.dut.generate_sriov_vfs_by_port(self.used_dut_port, 2, driver=driver) + self.sriov_vfs_port = self.dut.ports_info[self.used_dut_port]['vfs_port'] + + try: + + for port in self.sriov_vfs_port: + port.bind_driver('pci-stub') + + time.sleep(1) + + vf0_prop = {'opt_host': self.sriov_vfs_port[0].pci} + vf1_prop = {'opt_host': self.sriov_vfs_port[1].pci} + + if driver == 'igb_uio': + # start testpmd without the two VFs on the host + self.host_testpmd = PmdOutput(self.dut) + eal_param = '-b %(vf0)s -b %(vf1)s' % {'vf0': self.sriov_vfs_port[0].pci, + 'vf1': self.sriov_vfs_port[1].pci} + self.host_testpmd.start_testpmd("1S/2C/2T", eal_param=eal_param) + + # set up VM0 ENV + self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_port_start_stop') + self.vm0.set_vm_device(driver='pci-assign', **vf0_prop) + self.vm0.set_vm_device(driver='pci-assign', **vf1_prop) + self.vm_dut_0 = self.vm0.start() + if self.vm_dut_0 is None: + raise Exception("Set up VM0 ENV failed!") + + self.setup_1pf_2vf_1vm_env_flag = 1 + except Exception as e: + self.destroy_1pf_2vf_1vm_env() + raise Exception(e) + + def destroy_1pf_2vf_1vm_env(self): + if getattr(self, 'vm0', None): + #destroy testpmd in vm0 + self.vm0_testpmd.execute_cmd('stop') + self.vm0_testpmd.execute_cmd('quit', '# ') + self.vm0_testpmd = None + self.vm0_dut_ports = None + #destroy vm0 + self.vm0.stop() + self.vm0 = None + + if getattr(self, 'host_testpmd', None): + self.host_testpmd.execute_cmd('quit', '# ') + self.host_testpmd = None + + if getattr(self, 'used_dut_port', None): + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port) + port = self.dut.ports_info[self.used_dut_port]['port'] + port.bind_driver() + self.used_dut_port = None + + for port_id in self.dut_ports: + port = self.dut.ports_info[port_id]['port'] + port.bind_driver() + + self.setup_1pf_2vf_1vm_env_flag = 0 + + def test_start_stop_with_kernel_1pf_2vf_1vm(self): + + self.setup_1pf_2vf_1vm_env(driver='') + + self.vm0_dut_ports = self.vm_dut_0.get_ports('any') + + self.vm0_testpmd = PmdOutput(self.vm_dut_0) + self.vm0_testpmd.start_testpmd(VM_CORES_MASK) + self.vm0_testpmd.execute_cmd('set fwd mac') + + time.sleep(2) + + dst_mac = self.vm_dut_0.get_mac_address(self.vm0_dut_ports[0]) + self.send_and_verify(dst_mac, self.vm0_testpmd) + + def tear_down(self): + + if self.setup_1pf_2vf_1vm_env_flag == 1: + self.destroy_1pf_2vf_1vm_env() + + def tear_down_all(self): + + self.pktgen_kill() + self.tester.send_expect("./dpdk_nic_bind.py --bind=%s %s" %(self.tester_port_driver, self.tester_tx_pci), "#") + + if getattr(self, 'vm0', None): + self.vm0.stop() + + for port_id in self.dut_ports: + self.dut.destroy_sriov_vfs_by_port(port_id) + -- 1.9.3