* [dts] [PATCH V1 0/2] Etag automation testing script @ 2016-07-18 2:03 Yufen Mo 2016-07-18 2:03 ` [dts] [PATCH V1 1/2] add 802.1BR UDP format support in framework/packet module Yufen Mo 2016-07-18 2:03 ` [dts] [PATCH V1 2/2] Etag: upload automation testing script Yufen Mo 0 siblings, 2 replies; 4+ messages in thread From: Yufen Mo @ 2016-07-18 2:03 UTC (permalink / raw) To: dts; +Cc: yufengmx From: yufengmx <yufengx.mo@intel.com> yufengmx (2): add 802.1BR UDP format support in framework/packet module Etag: upload automation testing script conf/vf_etag.cfg | 106 +++++++++++++ framework/packet.py | 30 +++- tests/TestSuite_etag.py | 394 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 529 insertions(+), 1 deletion(-) create mode 100644 conf/vf_etag.cfg create mode 100644 tests/TestSuite_etag.py -- 1.9.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [dts] [PATCH V1 1/2] add 802.1BR UDP format support in framework/packet module 2016-07-18 2:03 [dts] [PATCH V1 0/2] Etag automation testing script Yufen Mo @ 2016-07-18 2:03 ` Yufen Mo 2016-07-18 2:03 ` [dts] [PATCH V1 2/2] Etag: upload automation testing script Yufen Mo 1 sibling, 0 replies; 4+ messages in thread From: Yufen Mo @ 2016-07-18 2:03 UTC (permalink / raw) To: dts; +Cc: yufengmx From: yufengmx <yufengx.mo@intel.com> Signed-off-by: yufengmx <yufengx.mo@intel.com> --- framework/packet.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/framework/packet.py b/framework/packet.py index a46fd47..98bc5c0 100755 --- a/framework/packet.py +++ b/framework/packet.py @@ -69,12 +69,13 @@ sys.path.append(DEP_FOLDER) from vxlan import Vxlan from nvgre import NVGRE, IPPROTO_NVGRE from lldp import LLDP, LLDPManagementAddress +from Dot1BR import Dot1BR # packet generator type should be configured later PACKETGEN = "scapy" LayersTypes = { - "L2": ['ether', 'vlan', '1588', 'arp', 'lldp'], + "L2": ['ether', 'vlan', 'etag', '1588', 'arp', 'lldp'], # ipv4_ext_unknown, ipv6_ext_unknown "L3": ['ipv4', 'ipv4ihl', 'ipv6', 'ipv4_ext', 'ipv6_ext', 'ipv6_ext2', 'ipv6_frag'], "L4": ['tcp', 'udp', 'frag', 'sctp', 'icmp', 'nofrag'], @@ -98,6 +99,7 @@ class scapy(object): SCAPY_LAYERS = { 'ether': Ether(dst="ff:ff:ff:ff:ff:ff"), 'vlan': Dot1Q(), + 'etag': Dot1BR(), '1588': Ether(type=0x88f7), 'arp': ARP(), 'ipv4': IP(), @@ -178,6 +180,24 @@ class scapy(object): value = int(str(self.pkt[Dot1Q].vlan)) return value + def etag(self, pkt_layer, ECIDbase=0, prio=0, type=None): + if pkt_layer.name != "802.1BR": + return + pkt_layer.ECIDbase = int(ECIDbase) + pkt_layer.prio = prio + if type is not None: + pkt_layer.type = type + + def strip_etag(self, element): + value = None + + if self.pkt.haslayer('Dot1BR') is 0: + return None + + if element == 'ECIDbase': + value = int(str(self.pkt[Dot1BR].ECIDbase)) + return value + def strip_layer2(self, element): value = None layer = self.pkt.getlayer(0) @@ -316,6 +336,7 @@ class Packet(object): 'TCP': {'layers': ['ether', 'ipv4', 'tcp', 'raw'], 'cfgload': True}, 'UDP': {'layers': ['ether', 'ipv4', 'udp', 'raw'], 'cfgload': True}, 'VLAN_UDP': {'layers': ['ether', 'vlan', 'ipv4', 'udp', 'raw'], 'cfgload': True}, + 'ETAG_UDP': {'layers': ['ether', 'etag', 'ipv4', 'udp', 'raw'], 'cfgload': True}, 'SCTP': {'layers': ['ether', 'ipv4', 'sctp', 'raw'], 'cfgload': True}, 'IPv6_TCP': {'layers': ['ether', 'ipv6', 'tcp', 'raw'], 'cfgload': True}, 'IPv6_UDP': {'layers': ['ether', 'ipv6', 'udp', 'raw'], 'cfgload': True}, @@ -446,6 +467,7 @@ class Packet(object): name2type = { 'MAC': 'ether', 'VLAN': 'vlan', + 'ETAG': 'etag', 'IP': 'ipv4', 'IPihl': 'ipv4ihl', 'IPFRAG': 'ipv4_ext', @@ -553,6 +575,9 @@ class Packet(object): def _config_layer_vlan(self, pkt_layer, config): return self.pktgen.vlan(pkt_layer, **config) + def _config_layer_etag(self, pkt_layer, config): + return self.pktgen.etag(pkt_layer, **config) + def _config_layer_ipv4(self, pkt_layer, config): return self.pktgen.ipv4(pkt_layer, **config) @@ -586,6 +611,9 @@ class Packet(object): def strip_element_vlan(self, element): return self.pktgen.strip_vlan(element) + def strip_element_etag(self, element): + return self.pktgen.strip_etag(element) + def strip_element_layer4(self, element): return self.pktgen.strip_layer4(element) -- 1.9.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [dts] [PATCH V1 2/2] Etag: upload automation testing script 2016-07-18 2:03 [dts] [PATCH V1 0/2] Etag automation testing script Yufen Mo 2016-07-18 2:03 ` [dts] [PATCH V1 1/2] add 802.1BR UDP format support in framework/packet module Yufen Mo @ 2016-07-18 2:03 ` Yufen Mo 2016-07-25 9:00 ` Liu, Yong 1 sibling, 1 reply; 4+ messages in thread From: Yufen Mo @ 2016-07-18 2:03 UTC (permalink / raw) To: dts; +Cc: yufengmx From: yufengmx <yufengx.mo@intel.com> E-tag mode is used for systems where the device adds a tag to identify a subsystem (usually a VM) and the near end switch adds a tag indicating the destination subsystem. Signed-off-by: yufengmx <yufengx.mo@intel.com> --- conf/vf_etag.cfg | 106 +++++++++++++ tests/TestSuite_etag.py | 394 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 500 insertions(+) create mode 100644 conf/vf_etag.cfg create mode 100644 tests/TestSuite_etag.py diff --git a/conf/vf_etag.cfg b/conf/vf_etag.cfg new file mode 100644 index 0000000..116be5a --- /dev/null +++ b/conf/vf_etag.cfg @@ -0,0 +1,106 @@ +# 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=4,5,6,7; +disk = + file=/home/image/vdisk01-sriov-fc20.img; +login = + user=root,password=tester; +net = + type=nic,opt_vlan=0; + type=user,opt_vlan=0; +monitor = + port=; +qga = + enable=yes; +vnc = + displayNum=1; +daemon = + enable=yes; + diff --git a/tests/TestSuite_etag.py b/tests/TestSuite_etag.py new file mode 100644 index 0000000..e293d03 --- /dev/null +++ b/tests/TestSuite_etag.py @@ -0,0 +1,394 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2016 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. + +''' + +import re +import time +import sys + +import dts +from qemu_kvm import QEMUKvm +from test_case import TestCase +from pmd_output import PmdOutput +from exception import VerifyFailure + +from scapy.utils import rdpcap + +from packet import Packet, sniff_packets, load_sniff_packets + +VM_CORES_MASK = 'all' + +class TestEtag(TestCase): + def set_up_all(self): + self.dut_ports = self.dut.get_ports(self.nic) + self.verify(self.nic in ['sagepond'], '802.1BR only support by sagepond') + self.verify(len(self.dut_ports) >= 1, 'Insufficient ports') + self.src_intf = self.tester.get_interface(self.tester.get_local_port(0)) + self.src_mac = self.tester.get_mac(self.tester.get_local_port(0)) + self.dst_mac = self.dut.get_mac_address(0) + self.vm0 = None + self.printFlag = dts.debug_mode + self.dut.send_expect('ls', '#') + self.setup_vm_env_flag = 0 + self.preset_host_cmds = list() + + def set_up(self): + pass + + def setup_vm_env(self, driver='default'): + ''' + setup qemu virtual environment + ''' + if self.setup_vm_env_flag == 1: + return + + self.used_dut_port_0 = self.dut_ports[0] + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 2, driver=driver) + self.sriov_vfs_port_0 = self.dut.ports_info[self.used_dut_port_0]['vfs_port'] + + try: + for port in self.sriov_vfs_port_0: + port.bind_driver('pci-stub') + + time.sleep(1) + vf0_prop = {'opt_host': self.sriov_vfs_port_0[0].pci} + vf1_prop = {'opt_host': self.sriov_vfs_port_0[1].pci} + + # 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[0].pci, + 'vf1': self.sriov_vfs_port_0[1].pci} + + self.preset_host_testpmd('1S/2C/2T', eal_param) + + # set up VM0 ENV + self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_etag') + 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!') + + except Exception as e: + print e + self.destroy_vm_env() + raise Exception(e) + + def destroy_vm_env(self): + #destroy testpmd in vm0 + if getattr(self, 'vm0_testpmd', None) and self.vm0_testpmd: + self.vm0_testpmd.execute_cmd('stop') + self.vm0_testpmd.execute_cmd('quit', '# ') + self.vm0_testpmd = None + + #destroy vm0 + if getattr(self, 'vm0', None) and self.vm0: + self.vm0_dut_ports = None + self.vm0.stop() + self.vm0 = None + + #destroy host testpmd + if getattr(self, 'host_testpmd', None): + self.host_testpmd.execute_cmd('quit', '# ') + self.host_testpmd = None + + # reset used port's sriov + if getattr(self, 'used_dut_port_0', None): + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0) + port = self.dut.ports_info[self.used_dut_port_0]['port'] + port.bind_driver() + self.used_dut_port_0 = None + + # bind used ports with default driver + for port_id in self.dut_ports: + port = self.dut.ports_info[port_id]['port'] + port.bind_driver() + self.setup_vm_env_flag = 0 + + def check_packet_transmission(self, pkt_types): + time.sleep(1) + for pkt_type in pkt_types.keys(): + intf = self.tester.get_interface(self.tester.get_local_port(0)) + pkt = Packet(pkt_type=pkt_type) + # set packet every layer's input parameters + if 'layer_configs' in pkt_types[pkt_type].keys(): + pkt_configs = pkt_types[pkt_type]['layer_configs'] + if pkt_configs: + for layer in pkt_configs.keys(): + pkt.config_layer(layer, pkt_configs[layer]) + pkt.send_pkt(tx_port=self.src_intf) + + # check vm testpmd packet received information + if 'vm' in pkt_types[pkt_type].keys(): + out = self.vm0_testpmd.get_output(timeout=2) + if self.printFlag: # debug output + print out + for pkt_attribute in pkt_types[pkt_type]['vm']: + if self.printFlag:# debug output + print pkt_attribute + if pkt_attribute not in out: + print dts.RED('Fail to detect %s' % pkt_attribute) + if not self.printFlag:# print out all info in debug mode + raise VerifyFailure('Failed to detect %s' % pkt_attribute) + print dts.GREEN('VM detected %s successfully' % pkt_type) + + # check dut testpmd packet received information + if 'dut' in pkt_types[pkt_type].keys(): + out = self.host_testpmd.get_output(timeout=2) + if self.printFlag: # debug output + print out + for pkt_attribute in pkt_types[pkt_type]['dut']: + if self.printFlag:# debug output + print pkt_attribute + if pkt_attribute not in out: + print dts.RED('Fail to detect %s' % pkt_attribute) + if not self.printFlag:# print out all info in debug mode + raise VerifyFailure('Failed to detect %s' % pkt_attribute) + print dts.GREEN('DUT detected %s successfully' % pkt_type) + time.sleep(1) + + def preset_host_testpmd(self, core_mask, eal_param): + if self.setup_vm_env_flag == 0: + self.host_testpmd.start_testpmd(core_mask, + param='--port-topology=loop', + eal_param=eal_param) + self.execute_host_testpmd_cmd(self.preset_host_cmds) + self.preset_host_cmds = list() + time.sleep(2) + + def execute_host_testpmd_cmd(self, cmds): + if len(cmds) == 0: + return + for item in cmds: + if len(item) == 2: + self.host_testpmd.execute_cmd(item[0], int(item[1])) + else: + self.host_testpmd.execute_cmd(item[0]) + + time.sleep(2) + + def preset_guest_testpmd(self): + if self.setup_vm_env_flag == 0: + self.vm0_testpmd = PmdOutput(self.vm_dut_0) + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, param='--port-topology=loop') + time.sleep(1) + elif self.vm0_testpmd: + self.vm0_testpmd.quit() + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, param='--port-topology=loop') + time.sleep(1) + + def execute_guest_testpmd_cmd(self, cmds): + if len(cmds) == 0: + return + for item in cmds: + if len(item) == 2: + self.vm0_testpmd.execute_cmd(item[0], int(item[1])) + else: + self.vm0_testpmd.execute_cmd(item[0]) + + def preset_test_enviroment(self): + self.setup_vm_env(driver='igb_uio') + self.preset_guest_testpmd() + self.setup_vm_env_flag = 1 + time.sleep(2) + + def test_l2_tunnel_filter(self): + ''' + Enable E-tag l2 tunnel support means enabling ability of parsing E-tag packet. + This ability should be enabled before we enable filtering, forwarding, + offloading for this specific type of tunnel. + ''' + host_cmds =[['port config 0 l2-tunnel E-tag enable'], + ['set fwd rxonly'], + ['set verbose 1'], + ['start']] + guest_cmds = [['set fwd rxonly'], + ['set verbose 1'], + ['start']] + config_layers = {'ether': {'src': self.src_mac}, + 'etag': {'ECIDbase': 1000}} + pkt_types = {'ETAG_UDP': {'dut':['type=0x893f'], + 'vm':['type=0x893f'], + 'layer_configs': config_layers}} + + self.preset_test_enviroment() + self.execute_host_testpmd_cmd(host_cmds) + self.execute_guest_testpmd_cmd(guest_cmds) + self.check_packet_transmission(pkt_types) + + def test_etag_filter(self): + ''' + when E-tag packet forwarding and add E-tag on VF0 + ''' + host_cmds = [['port config 0 l2-tunnel E-tag enable'], + ['E-tag set forwarding on port 0']] + self.preset_test_enviroment() + self.execute_host_testpmd_cmd(host_cmds) + for cnt in range(4): + host_cmds = [['E-tag set filter add e-tag-id 1000 dst-pool %d port 0'%cnt]] + guest_cmds = [['set fwd rxonly'], + ['set verbose 1'], + ['start']] + if cnt == 2: + # Same E-tag forwarding to PF0, Send 802.1BR packet with broardcast mac and + # check packet only recevied on PF + host_cmds_ex = [['set fwd mac'], + ['set verbose 1'], + ['start']] + + host_cmds.extend(host_cmds_ex) + # set packet type and its expecting result + config_layers = {'ether': {'src': self.src_mac, 'dst': self.dst_mac}, + 'etag': {'ECIDbase': 1000}} + pkt_types = {'ETAG_UDP': {'dut':['type=0x893f'], + 'layer_configs': config_layers}} + elif cnt == 3: + # Remove E-tag, Send 802.1BR packet with broardcast mac and check packet not + # recevied + host_cmds = [ ['E-tag set filter del e-tag-id 1000 port 0'], + ['set fwd rxonly'], + ['set verbose 1'], + ['start']] + config_layers = {'ether': {'src': self.src_mac}, + 'etag': {'ECIDbase': 1000}} + pkt_types = {'ETAG_UDP': {'vm':[''], + 'dut':[''], + 'layer_configs': config_layers}} + else: + # Same E-tag forwarding to VF0, Send 802.1BR packet with broardcast mac and + # check packet only recevied on VF0 or VF1 + host_cmds_ex = [['set fwd rxonly'], + ['set verbose 1'], + ['start']] + host_cmds.extend(host_cmds_ex) + config_layers = {'ether': {'src': self.src_mac}, + 'etag': {'ECIDbase': 1000}} + pkt_types = {'ETAG_UDP': {'vm':['type=0x893f'], + 'layer_configs': config_layers}} + + self.execute_host_testpmd_cmd(host_cmds) + self.execute_guest_testpmd_cmd(guest_cmds) + self.check_packet_transmission(pkt_types) + self.host_testpmd.execute_cmd('E-tag set forwarding off port 0') + + def test_etag_insertion(self): + ''' + When E-tag insertion enable in VF0 + ''' + host_cmds =[['port config 0 l2-tunnel E-tag enable'], + ['E-tag set insertion on port-tag-id 1000 port 0 vf 0'], + ['set fwd mac'], + ['set verbose 1'], + ['start']] + guest_cmds = [['set fwd mac'], + ['set verbose 1'], + ['start']] + self.preset_test_enviroment() + self.execute_host_testpmd_cmd(host_cmds) + self.execute_guest_testpmd_cmd(guest_cmds) + + self.vm0_dut_ports = self.vm_dut_0.get_ports('any') + config_layers = {'ether': {'src': self.src_mac}} + pkt_types = {'IP_RAW': {'layer_configs': config_layers}} + + intf = self.tester.get_interface(self.tester.get_local_port(0)) + inst = sniff_packets(intf) + + self.check_packet_transmission(pkt_types) + time.sleep(1) + pkts = load_sniff_packets(inst) + self.host_testpmd.execute_cmd('E-tag set insertion off port-tag-id 1000 port 0 vf 0') + + # load sniff pcap file, check received packet's content + packetContentFile = "/tmp/packetContent.log" + pcap_file = "/tmp/sniff_%s.pcap"%intf + fp=open(packetContentFile,'w') + backup_out=sys.stdout + sys.stdout=fp + pkts=rdpcap(pcap_file) + pkts.show() + fp.close() + sys.stdout=backup_out + fp=open(packetContentFile,'r') + out = fp.read() + fp.close() + if self.printFlag:# debug output + print out + self.verify( "Dot1BR" in out, "tester %s hasn't receiver etag packet"% intf) + + def test_etag_strip(self): + ''' + When E-tag strip enable on PF + ''' + host_cmds =[['port config 0 l2-tunnel E-tag enable'], + ['set fwd rxonly'], + ['set verbose 1'], + ['start']] + guest_cmds = [['set fwd rxonly'], + ['set verbose 1'], + ['start']] + config_layers = {'ether': {'src': self.src_mac}, + 'etag': {'ECIDbase': 1000}} + pkt_types_on = {'ETAG_UDP': {'vm':['type=0x0800', 'type=0x893f'], + 'layer_configs': config_layers}} + pkt_types_off = {'ETAG_UDP': {'vm':['type=0x893f', 'type=0x893f'], + 'layer_configs': config_layers}} + + self.preset_test_enviroment() + self.execute_host_testpmd_cmd(host_cmds) + self.execute_guest_testpmd_cmd(guest_cmds) + # Enable E-tag strip on PF, Send 802.1BR packet to VF and check forwarded packet without E-tag + self.host_testpmd.execute_cmd('E-tag set stripping on port 0') + self.check_packet_transmission(pkt_types_on) + + # Disable E-tag strip on PF, Send 802.1BR packet and check forwarded packet with E-tag + self.host_testpmd.execute_cmd('E-tag set stripping off port 0') + self.check_packet_transmission(pkt_types_off) + + def tear_down(self): + pass + + def tear_down_all(self): + if self.setup_vm_env_flag == 1: + self.destroy_vm_env() + + if getattr(self, 'vm0', None): + self.vm0.stop() + + for port_id in self.dut_ports: + self.dut.destroy_sriov_vfs_by_port(port_id) + + self.tester.send_expect("kill -9 $(ps aux | grep -i qemu | grep -v grep | awk {'print $2'})", '# ', 5) + -- 1.9.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [dts] [PATCH V1 2/2] Etag: upload automation testing script 2016-07-18 2:03 ` [dts] [PATCH V1 2/2] Etag: upload automation testing script Yufen Mo @ 2016-07-25 9:00 ` Liu, Yong 0 siblings, 0 replies; 4+ messages in thread From: Liu, Yong @ 2016-07-25 9:00 UTC (permalink / raw) To: Yufen Mo, dts Thanks Yufen, some comments below. On 07/18/2016 10:03 AM, Yufen Mo wrote: > From: yufengmx <yufengx.mo@intel.com> > > E-tag mode is used for systems where the device adds a tag to identify a > subsystem (usually a VM) and the near end switch adds a tag indicating the > destination subsystem. > > Signed-off-by: yufengmx <yufengx.mo@intel.com> > --- > conf/vf_etag.cfg | 106 +++++++++++++ > tests/TestSuite_etag.py | 394 ++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 500 insertions(+) > create mode 100644 conf/vf_etag.cfg > create mode 100644 tests/TestSuite_etag.py > > diff --git a/conf/vf_etag.cfg b/conf/vf_etag.cfg > new file mode 100644 > index 0000000..116be5a > --- /dev/null > +++ b/conf/vf_etag.cfg > @@ -0,0 +1,106 @@ > +# 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=4,5,6,7; > +disk = > + file=/home/image/vdisk01-sriov-fc20.img; > +login = > + user=root,password=tester; > +net = > + type=nic,opt_vlan=0; > + type=user,opt_vlan=0; > +monitor = > + port=; > +qga = > + enable=yes; > +vnc = > + displayNum=1; > +daemon = > + enable=yes; > + > diff --git a/tests/TestSuite_etag.py b/tests/TestSuite_etag.py > new file mode 100644 > index 0000000..e293d03 > --- /dev/null > +++ b/tests/TestSuite_etag.py > @@ -0,0 +1,394 @@ > +# BSD LICENSE > +# > +# Copyright(c) 2010-2016 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. > + > +''' > + > +import re > +import time > +import sys > + > +import dts > +from qemu_kvm import QEMUKvm > +from test_case import TestCase > +from pmd_output import PmdOutput > +from exception import VerifyFailure > + > +from scapy.utils import rdpcap > + > +from packet import Packet, sniff_packets, load_sniff_packets > + > +VM_CORES_MASK = 'all' > + > +class TestEtag(TestCase): > + def set_up_all(self): > + self.dut_ports = self.dut.get_ports(self.nic) > + self.verify(self.nic in ['sagepond'], '802.1BR only support by sagepond') > + self.verify(len(self.dut_ports) >= 1, 'Insufficient ports') > + self.src_intf = self.tester.get_interface(self.tester.get_local_port(0)) > + self.src_mac = self.tester.get_mac(self.tester.get_local_port(0)) > + self.dst_mac = self.dut.get_mac_address(0) > + self.vm0 = None > + self.printFlag = dts.debug_mode > + self.dut.send_expect('ls', '#') > + self.setup_vm_env_flag = 0 > + self.preset_host_cmds = list() > + > + def set_up(self): > + pass > + > + def setup_vm_env(self, driver='default'): > + ''' > + setup qemu virtual environment > + ''' > + if self.setup_vm_env_flag == 1: > + return > + > + self.used_dut_port_0 = self.dut_ports[0] > + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 2, driver=driver) > + self.sriov_vfs_port_0 = self.dut.ports_info[self.used_dut_port_0]['vfs_port'] > + > + try: > + for port in self.sriov_vfs_port_0: > + port.bind_driver('pci-stub') > + > + time.sleep(1) > + vf0_prop = {'opt_host': self.sriov_vfs_port_0[0].pci} > + vf1_prop = {'opt_host': self.sriov_vfs_port_0[1].pci} > + > + # 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[0].pci, > + 'vf1': self.sriov_vfs_port_0[1].pci} > + > + self.preset_host_testpmd('1S/2C/2T', eal_param) > + > + # set up VM0 ENV > + self.vm0 = QEMUKvm(self.dut, 'vm0', 'vf_etag') > + 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!') > + > + except Exception as e: > + print e > + self.destroy_vm_env() > + raise Exception(e) > + > + def destroy_vm_env(self): > + #destroy testpmd in vm0 > + if getattr(self, 'vm0_testpmd', None) and self.vm0_testpmd: > + self.vm0_testpmd.execute_cmd('stop') > + self.vm0_testpmd.execute_cmd('quit', '# ') > + self.vm0_testpmd = None > + > + #destroy vm0 > + if getattr(self, 'vm0', None) and self.vm0: > + self.vm0_dut_ports = None > + self.vm0.stop() > + self.vm0 = None > + > + #destroy host testpmd > + if getattr(self, 'host_testpmd', None): > + self.host_testpmd.execute_cmd('quit', '# ') > + self.host_testpmd = None > + > + # reset used port's sriov > + if getattr(self, 'used_dut_port_0', None): > + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0) > + port = self.dut.ports_info[self.used_dut_port_0]['port'] > + port.bind_driver() > + self.used_dut_port_0 = None > + > + # bind used ports with default driver > + for port_id in self.dut_ports: > + port = self.dut.ports_info[port_id]['port'] > + port.bind_driver() > + self.setup_vm_env_flag = 0 > + > + def check_packet_transmission(self, pkt_types): > + time.sleep(1) > + for pkt_type in pkt_types.keys(): > + intf = self.tester.get_interface(self.tester.get_local_port(0)) Tester interface has been initialized in setup_all function. > + pkt = Packet(pkt_type=pkt_type) > + # set packet every layer's input parameters > + if 'layer_configs' in pkt_types[pkt_type].keys(): > + pkt_configs = pkt_types[pkt_type]['layer_configs'] > + if pkt_configs: > + for layer in pkt_configs.keys(): > + pkt.config_layer(layer, pkt_configs[layer]) > + pkt.send_pkt(tx_port=self.src_intf) > + > + # check vm testpmd packet received information > + if 'vm' in pkt_types[pkt_type].keys(): > + out = self.vm0_testpmd.get_output(timeout=2) > + if self.printFlag: # debug output > + print out > + for pkt_attribute in pkt_types[pkt_type]['vm']: > + if self.printFlag:# debug output > + print pkt_attribute > + if pkt_attribute not in out: > + print dts.RED('Fail to detect %s' % pkt_attribute) > + if not self.printFlag:# print out all info in debug mode > + raise VerifyFailure('Failed to detect %s' % pkt_attribute) > + print dts.GREEN('VM detected %s successfully' % pkt_type) > + > + # check dut testpmd packet received information > + if 'dut' in pkt_types[pkt_type].keys(): > + out = self.host_testpmd.get_output(timeout=2) > + if self.printFlag: # debug output > + print out > + for pkt_attribute in pkt_types[pkt_type]['dut']: > + if self.printFlag:# debug output > + print pkt_attribute > + if pkt_attribute not in out: > + print dts.RED('Fail to detect %s' % pkt_attribute) > + if not self.printFlag:# print out all info in debug mode > + raise VerifyFailure('Failed to detect %s' % pkt_attribute) > + print dts.GREEN('DUT detected %s successfully' % pkt_type) > + time.sleep(1) > + > + def preset_host_testpmd(self, core_mask, eal_param): > + if self.setup_vm_env_flag == 0: > + self.host_testpmd.start_testpmd(core_mask, > + param='--port-topology=loop', > + eal_param=eal_param) > + self.execute_host_testpmd_cmd(self.preset_host_cmds) > + self.preset_host_cmds = list() > + time.sleep(2) > + > + def execute_host_testpmd_cmd(self, cmds): > + if len(cmds) == 0: > + return > + for item in cmds: > + if len(item) == 2: > + self.host_testpmd.execute_cmd(item[0], int(item[1])) > + else: > + self.host_testpmd.execute_cmd(item[0]) > + > + time.sleep(2) > + > + def preset_guest_testpmd(self): > + if self.setup_vm_env_flag == 0: > + self.vm0_testpmd = PmdOutput(self.vm_dut_0) > + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, param='--port-topology=loop') > + time.sleep(1) > + elif self.vm0_testpmd: > + self.vm0_testpmd.quit() > + self.vm0_testpmd.start_testpmd(VM_CORES_MASK, param='--port-topology=loop') > + time.sleep(1) > + > + def execute_guest_testpmd_cmd(self, cmds): > + if len(cmds) == 0: > + return > + for item in cmds: > + if len(item) == 2: > + self.vm0_testpmd.execute_cmd(item[0], int(item[1])) > + else: > + self.vm0_testpmd.execute_cmd(item[0]) > + > + def preset_test_enviroment(self): > + self.setup_vm_env(driver='igb_uio') > + self.preset_guest_testpmd() > + self.setup_vm_env_flag = 1 > + time.sleep(2) > + > + def test_l2_tunnel_filter(self): > + ''' > + Enable E-tag l2 tunnel support means enabling ability of parsing E-tag packet. > + This ability should be enabled before we enable filtering, forwarding, > + offloading for this specific type of tunnel. > + ''' > + host_cmds =[['port config 0 l2-tunnel E-tag enable'], > + ['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + guest_cmds = [['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + config_layers = {'ether': {'src': self.src_mac}, > + 'etag': {'ECIDbase': 1000}} > + pkt_types = {'ETAG_UDP': {'dut':['type=0x893f'], > + 'vm':['type=0x893f'], > + 'layer_configs': config_layers}} > + > + self.preset_test_enviroment() > + self.execute_host_testpmd_cmd(host_cmds) > + self.execute_guest_testpmd_cmd(guest_cmds) > + self.check_packet_transmission(pkt_types) > + > + def test_etag_filter(self): > + ''' > + when E-tag packet forwarding and add E-tag on VF0 > + ''' > + host_cmds = [['port config 0 l2-tunnel E-tag enable'], > + ['E-tag set forwarding on port 0']] > + self.preset_test_enviroment() > + self.execute_host_testpmd_cmd(host_cmds) > + for cnt in range(4): Number is useless here, please use something more meaningful like "for case in ['etag_pf', 'etag_remove', 'etag_vf']" replace it. > + host_cmds = [['E-tag set filter add e-tag-id 1000 dst-pool %d port 0'%cnt]] > + guest_cmds = [['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + if cnt == 2: > + # Same E-tag forwarding to PF0, Send 802.1BR packet with broardcast mac and > + # check packet only recevied on PF > + host_cmds_ex = [['set fwd mac'], > + ['set verbose 1'], > + ['start']] > + > + host_cmds.extend(host_cmds_ex) > + # set packet type and its expecting result > + config_layers = {'ether': {'src': self.src_mac, 'dst': self.dst_mac}, > + 'etag': {'ECIDbase': 1000}} > + pkt_types = {'ETAG_UDP': {'dut':['type=0x893f'], > + 'layer_configs': config_layers}} > + elif cnt == 3: > + # Remove E-tag, Send 802.1BR packet with broardcast mac and check packet not > + # recevied > + host_cmds = [ ['E-tag set filter del e-tag-id 1000 port 0'], > + ['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + config_layers = {'ether': {'src': self.src_mac}, > + 'etag': {'ECIDbase': 1000}} > + pkt_types = {'ETAG_UDP': {'vm':[''], > + 'dut':[''], > + 'layer_configs': config_layers}} > + else: > + # Same E-tag forwarding to VF0, Send 802.1BR packet with broardcast mac and > + # check packet only recevied on VF0 or VF1 > + host_cmds_ex = [['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + host_cmds.extend(host_cmds_ex) > + config_layers = {'ether': {'src': self.src_mac}, > + 'etag': {'ECIDbase': 1000}} > + pkt_types = {'ETAG_UDP': {'vm':['type=0x893f'], > + 'layer_configs': config_layers}} > + > + self.execute_host_testpmd_cmd(host_cmds) > + self.execute_guest_testpmd_cmd(guest_cmds) > + self.check_packet_transmission(pkt_types) > + self.host_testpmd.execute_cmd('E-tag set forwarding off port 0') > + > + def test_etag_insertion(self): > + ''' > + When E-tag insertion enable in VF0 > + ''' > + host_cmds =[['port config 0 l2-tunnel E-tag enable'], > + ['E-tag set insertion on port-tag-id 1000 port 0 vf 0'], > + ['set fwd mac'], > + ['set verbose 1'], > + ['start']] > + guest_cmds = [['set fwd mac'], > + ['set verbose 1'], > + ['start']] > + self.preset_test_enviroment() > + self.execute_host_testpmd_cmd(host_cmds) > + self.execute_guest_testpmd_cmd(guest_cmds) > + > + self.vm0_dut_ports = self.vm_dut_0.get_ports('any') > + config_layers = {'ether': {'src': self.src_mac}} > + pkt_types = {'IP_RAW': {'layer_configs': config_layers}} > + > + intf = self.tester.get_interface(self.tester.get_local_port(0)) > + inst = sniff_packets(intf) > + > + self.check_packet_transmission(pkt_types) > + time.sleep(1) > + pkts = load_sniff_packets(inst) > + self.host_testpmd.execute_cmd('E-tag set insertion off port-tag-id 1000 port 0 vf 0') > + > + # load sniff pcap file, check received packet's content > + packetContentFile = "/tmp/packetContent.log" > + pcap_file = "/tmp/sniff_%s.pcap"%intf > + fp=open(packetContentFile,'w') > + backup_out=sys.stdout > + sys.stdout=fp > + pkts=rdpcap(pcap_file) > + pkts.show() > + fp.close() > + sys.stdout=backup_out > + fp=open(packetContentFile,'r') > + out = fp.read() > + fp.close() > + if self.printFlag:# debug output > + print out > + self.verify( "Dot1BR" in out, "tester %s hasn't receiver etag packet"% intf) > + > + def test_etag_strip(self): > + ''' > + When E-tag strip enable on PF > + ''' > + host_cmds =[['port config 0 l2-tunnel E-tag enable'], > + ['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + guest_cmds = [['set fwd rxonly'], > + ['set verbose 1'], > + ['start']] > + config_layers = {'ether': {'src': self.src_mac}, > + 'etag': {'ECIDbase': 1000}} > + pkt_types_on = {'ETAG_UDP': {'vm':['type=0x0800', 'type=0x893f'], > + 'layer_configs': config_layers}} > + pkt_types_off = {'ETAG_UDP': {'vm':['type=0x893f', 'type=0x893f'], > + 'layer_configs': config_layers}} > + > + self.preset_test_enviroment() > + self.execute_host_testpmd_cmd(host_cmds) > + self.execute_guest_testpmd_cmd(guest_cmds) > + # Enable E-tag strip on PF, Send 802.1BR packet to VF and check forwarded packet without E-tag > + self.host_testpmd.execute_cmd('E-tag set stripping on port 0') > + self.check_packet_transmission(pkt_types_on) > + > + # Disable E-tag strip on PF, Send 802.1BR packet and check forwarded packet with E-tag > + self.host_testpmd.execute_cmd('E-tag set stripping off port 0') > + self.check_packet_transmission(pkt_types_off) > + > + def tear_down(self): > + pass > + > + def tear_down_all(self): > + if self.setup_vm_env_flag == 1: > + self.destroy_vm_env() > + > + if getattr(self, 'vm0', None): > + self.vm0.stop() > + > + for port_id in self.dut_ports: > + self.dut.destroy_sriov_vfs_by_port(port_id) > + > + self.tester.send_expect("kill -9 $(ps aux | grep -i qemu | grep -v grep | awk {'print $2'})", '# ', 5) > + ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-07-25 8:56 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-07-18 2:03 [dts] [PATCH V1 0/2] Etag automation testing script Yufen Mo 2016-07-18 2:03 ` [dts] [PATCH V1 1/2] add 802.1BR UDP format support in framework/packet module Yufen Mo 2016-07-18 2:03 ` [dts] [PATCH V1 2/2] Etag: upload automation testing script Yufen Mo 2016-07-25 9:00 ` 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).