[dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single class NetDevice

Jiajia, SunX sunx.jiajia at intel.com
Mon May 18 10:58:49 CEST 2015


Hi Huilong,

Please see my comments as below.

> -----Original Message-----
> From: Xu, HuilongX
> Sent: Monday, May 18, 2015 3:47 PM
> To: Jiajia, SunX; dts at dpdk.org
> Subject: RE: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single
> class NetDevice
> 
> Hi Jiajia,
> I have two comments in this patch,
> Would you check the comments in function "def
> destroy_sriov_vfs_by_port(self, port_id):" and "def set_toolchain(self,
> target):"
> Thanks  a lot
> 
> -----Original Message-----
> From: dts [mailto:dts-bounces at dpdk.org] On Behalf Of sjiajiax
> Sent: Monday, May 18, 2015 1:07 PM
> To: dts at dpdk.org
> Subject: [dts] [‘dts-v1’ 1/9] Abstract the NIC device as the single
> class NetDevice
> 
> Signed-off-by: sjiajiax <sunx.jiajia at intel.com>
> ---
>  framework/crb.py        | 135 +++++++----
>  framework/dut.py        | 268 ++++++++++++++++++---
>  framework/net_device.py | 600
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  framework/settings.py   |  43 ++++
>  framework/test_case.py  |   3 +-
>  framework/tester.py     |  51 +++-
>  6 files changed, 1006 insertions(+), 94 deletions(-)
>  create mode 100644 framework/net_device.py
> 
> diff --git a/framework/crb.py b/framework/crb.py
> index a699bfc..2eb2033 100644
> --- a/framework/crb.py
> +++ b/framework/crb.py
> @@ -69,6 +69,12 @@ class Crb(object):
> 
>          return self.session.send_expect(cmds, expected, timeout,
> verify)
> 
> +    def get_session_output(self, timeout=TIMEOUT):
> +        """
> +        Get session output message before timeout
> +        """
> +        return self.session.get_session_before(timeout)
> +
>      def set_test_types(self, func_tests, perf_tests):
>          """
>          Enable or disable function/performance test.
> @@ -80,7 +86,9 @@ class Crb(object):
>          """
>          Get the huge page number of CRB.
>          """
> -        huge_pages = self.send_expect("awk '/HugePages_Total/ { print
> $2 }' /proc/meminfo", "# ")
> +        huge_pages = self.send_expect(
> +            "awk '/HugePages_Total/ { print $2 }' /proc/meminfo",
> +            "# ", alt_session=True)
>          if huge_pages != "":
>              return int(huge_pages)
>          return 0
> @@ -115,6 +123,9 @@ class Crb(object):
>          """
>          self.base_dir = base_dir
> 
> +    def set_virttype(self, virttype):
> +        self.virttype = virttype
> +
>      def admin_ports(self, port, status):
>          """
>          Force set port's interface status.
> @@ -127,13 +138,15 @@ class Crb(object):
>          Force set remote interface link status in FreeBSD.
>          """
>          eth = self.ports_info[port]['intf']
> -        self.send_expect("ifconfig %s %s" % (eth, status), "# ")
> +        self.send_expect("ifconfig %s %s" %
> +                         (eth, status), "# ", alt_session=True)
> 
>      def admin_ports_linux(self, eth, status):
>          """
>          Force set remote interface link status in Linux.
>          """
> -        self.send_expect("ip link set  %s %s" % (eth, status), "# ")
> +        self.send_expect("ip link set  %s %s" %
> +                         (eth, status), "# ", alt_session=True)
> 
>      def pci_devices_information(self):
>          """
> @@ -157,8 +170,9 @@ class Crb(object):
>          """
>          Look for the NIC's information (PCI Id and card type).
>          """
> -        out = self.send_expect("lspci -nn | grep -i eth", "# ")
> -        rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .*?([\da-
> f]{4}:[\da-f]{4})"
> +        out = self.send_expect(
> +            "lspci -nn | grep -i eth", "# ", alt_session=True)
> +        rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) .*Eth.*?ernet .*?([\da-
> f]{4}:[\da-f]{4})"
>          pattern = re.compile(rexp)
>          match = pattern.findall(out)
>          self.pci_devices_info = []
> @@ -169,7 +183,7 @@ class Crb(object):
>          """
>          Look for the NIC's information (PCI Id and card type).
>          """
> -        out = self.send_expect("pciconf -l", "# ")
> +        out = self.send_expect("pciconf -l", "# ", alt_session=True)
>          rexp = r"pci0:([\da-f]{1,3}:[\da-
> f]{1,2}:\d{1}):\s*class=0x020000.*chip=0x([\da-f]{4})8086"
>          pattern = re.compile(rexp)
>          match = pattern.findall(out)
> @@ -179,66 +193,69 @@ class Crb(object):
>              card_type = "8086:%s" % match[i][1]
>              self.pci_devices_info.append((match[i][0], card_type))
> 
> -    def get_interface_name(self, bus_id, devfun_id=''):
> -        """
> -        Get interface name of specified pci device.
> -        """
> -        get_interface_name = getattr(self, 'get_interface_name_%s' %
> self.get_os_type())
> -        return get_interface_name(bus_id, devfun_id)
> -
> -    def get_interface_name_linux(self, bus_id, devfun_id):
> +    def get_pci_dev_driver(self, bus_id, devfun_id):
>          """
> -        Get interface name of specified pci device on linux.
> +        Get the driver of specified pci device.
>          """
> -        command = 'ls --color=never
> /sys/bus/pci/devices/0000:%s:%s/net' % (bus_id, devfun_id)
> -        out = self.send_expect(command, '# ', verify=True)
> -        if out == -1:
> -            name = ""
> -        else:
> -            name = out.split()[0]
> -        return name
> +        get_pci_dev_driver = getattr(
> +            self, 'get_pci_dev_driver_%s' % self.get_os_type())
> +        return get_pci_dev_driver(bus_id, devfun_id)
> 
> -    def get_interface_name_freebsd(self, bus_id, devfun_id):
> +    def get_pci_dev_driver_linux(self, bus_id, devfun_id):
>          """
> -        Get interface name of specified pci device on Freebsd.
> +        Get the driver of specified pci device on linux.
>          """
> -        out = self.send_expect("pciconf -l", "# ")
> -        rexp = r"(\w*)@pci0:%s" % bus_id
> +        out = self.send_expect("cat
> /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
> +                               (bus_id, devfun_id), "# ",
> alt_session=True)
> +        rexp = r"DRIVER=(.+?)\r"
>          pattern = re.compile(rexp)
> -        match = pattern.findall(out)
> -        return match[0]
> +        match = pattern.search(out)
> +        if not match:
> +            return None
> +        return match.group(1)
> 
> -    def get_mac_addr(self, intf, bus_id='', devfun_id=''):
> +    def get_pci_dev_driver_freebsd(self, bus_id, devfun_id):
>          """
> -        Get mac address of specified pci device.
> +        Get the driver of specified pci device.
>          """
> -        get_mac_addr = getattr(self, 'get_mac_addr_%s' %
> self.get_os_type())
> -        return get_mac_addr(intf, bus_id, devfun_id)
> +        return True
> 
> -    def get_mac_addr_linux(self, intf, bus_id, devfun_id):
> +    def get_pci_dev_id(self, bus_id, devfun_id):
>          """
> -        Get mac address of specified pci device on linux.
> +        Get the pci id of specified pci device.
>          """
> -        command = ('cat
> /sys/bus/pci/devices/0000:%s:%s/net/%s/address' %
> -                   (bus_id, devfun_id, intf))
> -        return self.send_expect(command, '# ')
> +        get_pci_dev_id = getattr(
> +            self, 'get_pci_dev_id_%s' % self.get_os_type())
> +        return get_pci_dev_id(bus_id, devfun_id)
> 
> -    def get_mac_addr_freebsd(self, intf, bus_id, devfun_id):
> +    def get_pci_dev_id_linux(self, bus_id, devfun_id):
>          """
> -        Get mac address of specified pci device on Freebsd.
> +        Get the pci id of specified pci device on linux.
>          """
> -        out = self.send_expect('ifconfig %s' % intf, '# ')
> -        rexp = r"ether ([\da-f:]*)"
> +        out = self.send_expect("cat
> /sys/bus/pci/devices/0000\:%s\:%s/uevent" %
> +                               (bus_id, devfun_id), "# ",
> alt_session=True)
> +        rexp = r"PCI_ID=(.+)"
>          pattern = re.compile(rexp)
> -        match = pattern.findall(out)
> -        return match[0]
> +        match = re.search(out)
> +        if not match:
> +            return None
> +        return match.group(1)
> 
>      def get_device_numa(self, bus_id, devfun_id):
>          """
> -        Get numa id of specified pci device
> +        Get numa number of specified pci device.
> +        """
> +        get_device_numa = getattr(
> +            self, "get_device_numa_%s" % self.get_os_type())
> +        return get_device_numa(bus_id, devfun_id)
> +
> +    def get_device_numa_linux(self, bus_id, devfun_id):
> +        """
> +        Get numa number of specified pci device on Linux.
>          """
> -        numa = self.send_expect("cat
> /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
> -                                (bus_id, devfun_id), "# ")
> +        numa = self.send_expect(
> +            "cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
> +            (bus_id, devfun_id), "# ", alt_session=True)
> 
>          try:
>              numa = int(numa)
> @@ -259,14 +276,14 @@ class Crb(object):
>          Get ipv6 address of specified pci device on linux.
>          """
>          out = self.send_expect("ip -family inet6 address show dev %s |
> awk '/inet6/ { print $2 }'"
> -                               % intf, "# ")
> +                               % intf, "# ", alt_session=True)
>          return out.split('/')[0]
> 
>      def get_ipv6_addr_freebsd(self, intf):
>          """
>          Get ipv6 address of specified pci device on Freebsd.
>          """
> -        out = self.send_expect('ifconfig %s' % intf, '# ')
> +        out = self.send_expect('ifconfig %s' % intf, '# ',
> alt_session=True)
>          rexp = r"inet6 ([\da-f:]*)%"
>          pattern = re.compile(rexp)
>          match = pattern.findall(out)
> @@ -275,6 +292,22 @@ class Crb(object):
> 
>          return match[0]
> 
> +    def disable_ipv6(self, intf):
> +        """
> +        Disable ipv6 of of specified interface
> +        """
> +        if intf != 'N/A':
> +            self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=1" %
> +                             intf, "# ", alt_session=True)
> +
> +    def enable_ipv6(self, intf):
> +        """
> +        Enable ipv6 of of specified interface
> +        """
> +        if intf != 'N/A':
> +            self.send_expect("sysctl net.ipv6.conf.%s.disable_ipv6=0" %
> +                             intf, "# ", alt_session=True)
> +
>      def create_file(self, contents, fileName):
>          """
>          Create file with contents and copy it to CRB.
> @@ -318,7 +351,7 @@ class Crb(object):
>          if isinstance(self, Dut) and self.get_os_type() == 'freebsd':
>              expected = 'FreeBSD.*#'
> 
> -        self.send_expect('uname', expected, 2)
> +        self.send_expect('uname', expected, 2, alt_session=True)
> 
>      def init_core_list(self):
>          """
> @@ -378,7 +411,9 @@ class Crb(object):
>          self.cores = []
> 
>          cpuinfo = \
> -            self.send_expect("grep \"processor\\|physical id\\|core
> id\\|^$\" /proc/cpuinfo", "#")
> +            self.send_expect(
> +                "grep --color=never \"processor\\|physical id\\|core
> id\\|^$\" /proc/cpuinfo",
> +                "#", alt_session=True)
>          cpuinfo = cpuinfo.split('\r\n\r\n')
>          for line in cpuinfo:
>              m = re.search("processor\t: (\d+)\r\n" +
> diff --git a/framework/dut.py b/framework/dut.py
> index 5b7aba2..247b01c 100644
> --- a/framework/dut.py
> +++ b/framework/dut.py
> @@ -33,11 +33,17 @@ import os
>  import re
>  import time
>  import dts
> -from config import UserConf
> -from settings import NICS
> +import settings
> +from config import PortConf
> +from settings import NICS, LOG_NAME_SEP
>  from ssh_connection import SSHConnection
>  from crb import Crb
> +from net_device import NetDevice
>  from logger import getLogger
> +from virt_resource import VirtResource
> +from utils import RED
> +
> +
> 
> 
>  class Dut(Crb):
> @@ -60,20 +66,36 @@ class Dut(Crb):
>      def __init__(self, crb, serializer):
>          super(Dut, self).__init__(crb, serializer)
>          self.NAME = 'dut'
> +
> +        self.host_init_flag = 0
>          self.logger = getLogger(self.NAME)
>          self.session = SSHConnection(self.get_ip_address(), self.NAME,
>                                       self.get_password())
>          self.session.init_log(self.logger)
> -        self.alt_session = SSHConnection(self.get_ip_address(),
> self.NAME + '_alt',
> -                                         self.get_password())
> +        self.alt_session = SSHConnection(
> +            self.get_ip_address(),
> +            self.NAME + '_alt',
> +            self.get_password())
>          self.alt_session.init_log(self.logger)
>          self.number_of_cores = 0
>          self.tester = None
>          self.cores = []
>          self.architecture = None
>          self.ports_info = None
> -        self.conf = UserConf()
> +        self.conf = PortConf()
>          self.ports_map = []
> +        self.virt_pool = None
> +
> +    def init_host_session(self):
> +        if self.host_init_flag:
> +            pass
> +        else:
> +            self.host_session = SSHConnection(
> +                self.get_ip_address(),
> +                self.NAME + '_host',
> +                self.get_password())
> +            self.host_session.init_log(self.logger)
> +            self.host_init_flag = 1
> 
>      def change_config_option(self, target, parameter, value):
>          """
> @@ -82,12 +104,12 @@ class Dut(Crb):
>          self.send_expect("sed -i 's/%s=.*$/%s=%s/'
> config/defconfig_%s" %
>                           (parameter, parameter, value, target), "# ")
> 
> -    def set_nic_type(self, nic):
> +    def set_nic_type(self, nic_type):
>          """
>          Set CRB NICS ready to validated.
>          """
> -        self.nic = nic
> -        if 'cfg' in nic:
> +        self.nic_type = nic_type
> +        if 'cfg' in nic_type:
>              self.conf.load_ports_config(self.get_ip_address())
> 
>      def set_toolchain(self, target):
> @@ -167,11 +189,17 @@ class Dut(Crb):
>          self.mount_procfs()
>          # auto detect network topology
>          self.map_available_ports()
> +        # disable tester port ipv6
> +        self.disable_tester_ipv6()
>          # print latest ports_info
> -        self.logger.info(dts.pprint(self.ports_info))
> +        for port_info in self.ports_info:
> +            self.logger.info(port_info)

>          when virt dut init not have any port, but we will add port by
> hot plug or build vport by dpdk app testpmd(eg, xen virtio test)
>          The test will can't continued

Yes, maybe it is good to have a warning message.

>          if self.ports_map is None or len(self.ports_map) == 0:
>              raise ValueError("ports_map should not be empty, please
> check all links")
> 
> +        # initialize virtualization resource pool
> +        self.virt_pool = VirtResource(self)
> +
>      def restore_interfaces(self):
>          """
>          Restore all ports's interfaces.
> @@ -195,20 +223,22 @@ class Dut(Crb):
>              pci_bus = port['pci']
>              pci_id = port['type']
>              # get device driver
> -            driver = dts.get_nic_driver(pci_id)
> +            driver = settings.get_nic_driver(pci_id)
>              if driver is not None:
>                  # unbind device driver
>                  addr_array = pci_bus.split(':')
>                  bus_id = addr_array[0]
>                  devfun_id = addr_array[1]
> 
> +                port = NetDevice(self, bus_id, devfun_id)
> +
>                  self.send_expect('echo 0000:%s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind'
>                                   % (pci_bus, bus_id, devfun_id), '# ')
>                  # bind to linux kernel driver
>                  self.send_expect('modprobe %s' % driver, '# ')
>                  self.send_expect('echo 0000:%s >
> /sys/bus/pci/drivers/%s/bind'
>                                   % (pci_bus, driver), '# ')
> -                itf = self.get_interface_name(addr_array[0],
> addr_array[1])
> +                itf = port.get_interface_name()
>                  self.send_expect("ifconfig %s up" % itf, "# ")
>              else:
>                  self.logger.info("NOT FOUND DRIVER FOR PORT
> (%s|%s)!!!" % (pci_bus, pci_id))
> @@ -228,7 +258,10 @@ class Dut(Crb):
>          """
>          Setup Linux hugepages.
>          """
> -        hugepages_size = self.send_expect("awk '/Hugepagesize/ {print
> $2}' /proc/meminfo", "# ")
> +        if self.virttype == 'xen':
> +            return
> +        hugepages_size = self.send_expect(
> +            "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
> 
>          if int(hugepages_size) < (1024 * 1024):
>              if self.architecture == "x86_64":
> @@ -265,6 +298,20 @@ class Dut(Crb):
> 
>          return 'taskset %s ' % core
> 
> +    def is_ssh_session_port(self, pci_bus):
> +        """
> +        Check if the pci device is the dut SSH session port.
> +        """
> +        port = None
> +        for port_info in self.ports_info:
> +            if pci_bus == port_info['pci']:
> +                port = port_info['port']
> +                break
> +        if port and port.get_ipv4_addr() == crbs['IP'].strip():
> +            return True
> +        else:
> +            return False
> +
>      def bind_interfaces_linux(self, driver='igb_uio',
> nics_to_bind=None):
>          """
>          Bind the interfaces to the selected driver. nics_to_bind can
> be None
> @@ -275,12 +322,17 @@ class Dut(Crb):
> 
>          current_nic = 0
>          for (pci_bus, pci_id) in self.pci_devices_info:
> -            if dts.accepted_nic(pci_id):
> +            if settings.accepted_nic(pci_id):
> +                if self.is_ssh_session_port(pci_bus):
> +                    continue
> 
>                  if nics_to_bind is None or current_nic in nics_to_bind:
>                      binding_list += '%s ' % (pci_bus)
> 
>                  current_nic += 1
> +        if current_nic == 0:
> +            self.logger.info("Not nic need bind driver: %s" % driver)
> +            return
> 
>          self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list,
> '# ')
> 
> @@ -293,13 +345,19 @@ class Dut(Crb):
> 
>          current_nic = 0
>          for (pci_bus, pci_id) in self.pci_devices_info:
> -            if dts.accepted_nic(pci_id):
> +            if settings.accepted_nic(pci_id):
> +                if self.is_ssh_session_port(pci_bus):
> +                    continue
> 
>                  if nics_to_bind is None or current_nic in nics_to_bind:
>                      binding_list += '%s ' % (pci_bus)
> 
>                  current_nic += 1
> 
> +        if current_nic == 0:
> +            self.logger.info("Not nic need unbind driver")
> +            return
> +
>          self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list,
> '# ', 30)
> 
>      def get_ports(self, nic_type='any', perf=None, socket=None):
> @@ -314,14 +372,17 @@ class Dut(Crb):
>              perf = self.want_perf_tests
> 
>          nictypes = []
> -        if nic_type == 'any':
> +        if self.nic_type == 'any':
>              for portid in range(len(self.ports_info)):
>                  ports.append(portid)
>              return ports
> -        elif nic_type == 'cfg':
> +        elif self.nic_type == 'cfg':
>              for portid in range(len(self.ports_info)):
>                  if self.ports_info[portid]['source'] == 'cfg':
> -                    ports.append(portid)
> +                    if (socket is None or
> +                        self.ports_info[portid]['numa'] == -1 or
> +                            socket == self.ports_info[portid]['numa']):
> +                        ports.append(portid)
>              return ports
>          else:
>              for portid in range(len(self.ports_info)):
> @@ -440,36 +501,38 @@ class Dut(Crb):
>          Check that whether auto scanned ports ready to use
>          """
>          pci_addr = "%s:%s" % (pci_bus, pci_id)
> -        if self.nic == 'any':
> +        if self.nic_type == 'any':
>              return True
> -        elif self.nic == 'cfg':
> +        elif self.nic_type == 'cfg':
>              if self.conf.check_port_available(pci_bus) is True:
>                  return True
> -        elif self.nic not in NICS.keys():
> -            self.logger.warning("NOT SUPPORTED NIC TYPE: %s" %
> self.nic)
> +        elif self.nic_type not in NICS.keys():
> +            self.logger.warning("NOT SUPPORTED NIC TYPE: %s" %
> self.nic_type)
>          else:
> -            codename = NICS[self.nic]
> +            codename = NICS[self.nic_type]
>              if pci_id == codename:
>                  return True
> 
>          return False
> 
>      def rescan_ports(self):
> -        unknow_interface = dts.RED('Skipped: unknow_interface')
> +        unknow_interface = RED('Skipped: unknow_interface')
> 
>          for port_info in self.ports_info:
>              pci_bus = port_info['pci']
>              addr_array = pci_bus.split(':')
>              bus_id = addr_array[0]
>              devfun_id = addr_array[1]
> -            intf = self.get_interface_name(bus_id, devfun_id)
> +
> +            port = NetDevice(self, bus_id, devfun_id)
> +            intf = port.get_interface_name()
>              if "No such file" in intf:
>                  self.logger.info("DUT: [0000:%s] %s" % (pci_bus,
> unknow_interface))
>              out = self.send_expect("ip link show %s" % intf, "# ")
>              if "DOWN" in out:
>                  self.send_expect("ip link set %s up" % intf, "# ")
>                  time.sleep(5)
> -            macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
> +            macaddr = port.get_mac_addr()
>              out = self.send_expect("ip -family inet6 address show
> dev %s | awk '/inet6/ { print $2 }'"
>                                     % intf, "# ")
>              ipv6 = out.split('/')[0]
> @@ -481,16 +544,32 @@ class Dut(Crb):
>              port_info['intf'] = intf
>              port_info['ipv6'] = ipv6
> 
> +    def load_serializer_ports(self):
> +        self.ports_info = []
> +        cached_ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> +        if cached_ports_info is None:
> +            return
> +        for port in cached_ports_info:
> +            self.ports_info.append({'pci': port['pci'], 'type':
> port['type'],
> +                                    'numa': port['numa']})
> +
> +    def save_serializer_ports(self):
> +        cached_ports_info = []
> +        for port in self.ports_info:
> +            cached_ports_info.append({'pci': port['pci'], 'type':
> port['type'],
> +                                      'numa': port['numa']})
> +        self.serializer.save(self.PORT_INFO_CACHE_KEY,
> cached_ports_info)
> +
>      def scan_ports(self):
>          """
>          Scan ports information or just read it from cache file.
>          """
>          if self.read_cache:
> -            self.ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> +            self.load_serializer_ports()
> 
>          if not self.read_cache or self.ports_info is None:
>              self.scan_ports_uncached()
> -            self.serializer.save(self.PORT_INFO_CACHE_KEY,
> self.ports_info)
> +            self.save_serializer_ports()
> 
>      def scan_ports_uncached(self):
>          """
> @@ -505,8 +584,8 @@ class Dut(Crb):
>          """
>          self.ports_info = []
> 
> -        skipped = dts.RED('Skipped: Unknown/not selected')
> -        unknow_interface = dts.RED('Skipped: unknow_interface')
> +        skipped = RED('Skipped: Unknown/not selected')
> +        unknow_interface = RED('Skipped: unknow_interface')
> 
>          for (pci_bus, pci_id) in self.pci_devices_info:
>              if self.check_ports_available(pci_bus, pci_id) is False:
> @@ -518,9 +597,11 @@ class Dut(Crb):
>              bus_id = addr_array[0]
>              devfun_id = addr_array[1]
> 
> +            port = NetDevice(self, bus_id, devfun_id)
>              numa = self.get_device_numa(bus_id, devfun_id)
>              # store the port info to port mapping
> -            self.ports_info.append({'pci': pci_bus, 'type': pci_id,
> 'numa': numa})
> +            self.ports_info.append(
> +                {'port': port, 'pci': pci_bus, 'type': pci_id, 'numa':
> numa})
> 
>      def scan_ports_uncached_freebsd(self):
>          """
> @@ -528,16 +609,17 @@ class Dut(Crb):
>          """
>          self.ports_info = []
> 
> -        skipped = dts.RED('Skipped: Unknown/not selected')
> +        skipped = RED('Skipped: Unknown/not selected')
> 
>          for (pci_bus, pci_id) in self.pci_devices_info:
> 
> -            if not dts.accepted_nic(pci_id):
> +            if not setttings.accepted_nic(pci_id):
>                  self.logger.info("DUT: [%s %s] %s" % (pci_bus, pci_id,
>                                                        skipped))
>                  continue
> 
> -            intf = self.get_interface_name(pci_bus)
> +            port = NetDevice(self, pci_bus, '')
> +            intf = port.get_interface_name(pci_bus)
> 
>              macaddr = self.get_mac_addr(intf)
>              ipv6 = self.get_ipv6_addr(intf)
> @@ -560,9 +642,93 @@ class Dut(Crb):
>              pci_str = "%s:%s.%s" % (pci_bus_id, pci_dev_str,
> pci_split[2])
> 
>              # store the port info to port mapping
> -            self.ports_info.append({'pci': pci_str, 'type': pci_id,
> 'intf':
> +            self.ports_info.append({'port': port, 'pci': pci_str,
> 'type': pci_id, 'intf':
>                                      intf, 'mac': macaddr, 'ipv6': ipv6,
> 'numa': -1})
> 
> +    def generate_sriov_vfs_by_port(self, port_id, vf_num,
> driver='default'):
> +        """
> +        Generate SRIOV VFs with default driver it is bound now or
> specifid driver.
> +        """
> +        port = self.ports_info[port_id]['port']
> +        port_driver = port.get_nic_driver()
> +
> +        if driver == 'default':
> +            if not port_driver:
> +                self.logger.info(
> +                    "No driver on specified port, can not generate
> SRIOV VF.")
> +                return None
> +        else:
> +            if port_driver != driver:
> +                port.bind_driver(driver)
> +        port.generate_sriov_vfs(vf_num)
> +
> +        # append the VF PCIs into the ports_info
> +        sriov_vfs_pci = port.get_sriov_vfs_pci()
> +        self.ports_info[port_id]['sriov_vfs_pci'] = sriov_vfs_pci
> +
> +        # instantiate the VF with NetDevice
> +        vfs_port = []
> +        for vf_pci in sriov_vfs_pci:
> +            addr_array = vf_pci.split(':')
> +            bus_id = addr_array[0]
> +            devfun_id = addr_array[1]
> +            vf_port = NetDevice(self, bus_id, devfun_id)
> +            vfs_port.append(vf_port)
> +        self.ports_info[port_id]['vfs_port'] = vfs_port
> +
> +        pci = self.ports_info[port_id]['pci']
> +        self.virt_pool.add_vf_on_pf(pf_pci=pci, vflist=sriov_vfs_pci)
> +
> +    def destroy_sriov_vfs_by_port(self, port_id):
> +        port = self.ports_info[port_id]['port']
> +        vflist = []
> +        port_driver = port.get_nic_driver()
> +        if 'sriov_vfs_pci' in self.ports_info[port_id] and \
> +           self.ports_info[port_id]['sriov_vfs_pci']:
> +            vflist = self.ports_info[port_id]['sriov_vfs_pci']
> +        else:
> +            if not port.get_sriov_vfs_pci():
> +                return
> +
> +        if not port_driver:
> +            self.logger.info(
> +                "No driver on specified port, skip destroy SRIOV VF.")
> +        else:


>              Why we need "sriov_vfs_pci"? would we check destroy sriov
> vfs succeed or failed before we reset ports_info?

Yes, I think it is better to check the sriov_vfs_pci to confirm if the VFs
have been destroyed.

> +            sriov_vfs_pci = port.destroy_sriov_vfs()
> +        self.ports_info[port_id]['sriov_vfs_pci'] = []
> +        self.ports_info[port_id]['vfs_port'] = []
> +
> +        pci = self.ports_info[port_id]['pci']
> +        self.virt_pool.del_vf_on_pf(pf_pci=pci, vflist=vflist)
> +
> +    def get_vm_core_list(self):
> +        return VMCORELIST[self.crb['VM CoreList']]
> +
> +    def create_blacklist_string(self, target, nic):
> +        create_blacklist_string = getattr(
> +            self, 'create_blacklist_string_%s' % self.get_os_type())
> +        return create_blacklist_string(target, nic)
> +
> +    def create_blacklist_string_linux(self, target, nic):
> +        blacklist = ''
> +        dutPorts = self.get_ports(nic)
> +        self.restore_interfaces()
> +        if dts.drivername == "igb_uio":
> +            self.send_expect('insmod ./%s/kmod/igb_uio.ko ' % target,
> '# ')
> +        elif dts.drivername == "vfio-pci":
> +            self.send_expect("modprobe vfio", '# ')
> +            self.send_expect("modprobe vfio-pci", '# ')
> +        self.bind_interfaces_linux(dts.drivername)
> +        for port in range(0, len(self.ports_info)):
> +            if(port not in dutPorts):
> +                blacklist += '-b 0000:%s ' %
> self.ports_info[port]['pci']
> +        return blacklist
> +
> +    def create_blacklist_string_freebsd(self, target, nic):
> +        blacklist = ''
> +        # No blacklist option in FreeBSD
> +        return blacklist
> +
>      def load_portconf(self):
>          """
>          Load port configurations for ports_info. If manually
> configured infor
> @@ -637,7 +803,11 @@ class Dut(Crb):
>                  if ipv6 == "Not connected":
>                      continue
> 
> -                out = self.tester.send_ping6(remotePort, ipv6,
> self.get_mac_address(dutPort))
> +                if getattr(self, 'send_ping6', None):
> +                    self.send_ping6(
> +                        dutPort,
> self.tester.ports_info[remotePort]['ipv6'])
> +                out = self.tester.send_ping6(
> +                    remotePort, ipv6, self.get_mac_address(dutPort))
> 
>                  if ('64 bytes from' in out):
>                      self.logger.info("PORT MAP: [dut %d: tester %d]" %
> (dutPort, remotePort))
> @@ -656,3 +826,31 @@ class Dut(Crb):
> 
>          for port in remove:
>              self.ports_info.remove(port)
> +
> +    def disable_tester_ipv6(self):
> +        for tester_port in self.ports_map:
> +            intf = self.tester.get_interface(tester_port)
> +            self.tester.disable_ipv6(intf)
> +
> +    def enable_tester_ipv6(self):
> +        for tester_port in self.ports_map:
> +            intf = self.tester.get_interface(tester_port)
> +            self.tester.enable_ipv6(intf)
> +
> +    def check_port_occupied(self, port):
> +        out = self.alt_session.send_expect('lsof -i:%d' % port, '# ')
> +        if out == '':
> +            return False
> +        else:
> +            return True
> +
> +    def get_maximal_vnc_num(self):
> +        out = self.send_expect("ps aux | grep '\-vnc' | grep -v grep",
> '# ')
> +        if out:
> +            ports = re.findall(r'-vnc .*?:(\d+)', out)
> +            for num in range(len(ports)):
> +                ports[num] = int(ports[num])
> +                ports.sort()
> +        else:
> +            ports = [0, ]
> +        return ports[-1]
> diff --git a/framework/net_device.py b/framework/net_device.py
> new file mode 100644
> index 0000000..c04d442
> --- /dev/null
> +++ b/framework/net_device.py
> @@ -0,0 +1,600 @@
> +import os
> +import re
> +from functools import wraps
> +import time
> +import pdb
> +
> +import settings
> +from crb import Crb
> +from settings import TIMEOUT
> +
> +
> +class NetDevice(object):
> +
> +    """
> +    Abstract the device which is PF or VF.
> +    """
> +
> +    def __init__(self, crb, bus_id, devfun_id):
> +        if not isinstance(crb, Crb):
> +            raise Exception("  Please input the instance of Crb!!!")
> +        self.crb = crb
> +        self.bus_id = bus_id
> +        self.devfun_id = devfun_id
> +        self.pci = bus_id + ':' + devfun_id
> +        self.pci_id = self.get_pci_id(bus_id, devfun_id)
> +        self.default_driver = settings.get_nic_driver(self.pci_id)
> +        # bind to default driver
> +        current_driver = self.get_nic_driver()
> +        if self.default_driver != current_driver:
> +            self.bind_driver()
> +        if self.nic_is_pf():
> +            self.default_vf_driver = ''
> +        self.intf_name = self.get_interface_name()
> +
> +    def __send_expect(self, cmds, expected, timeout=TIMEOUT,
> alt_session=True):
> +        """
> +        Wrap the crb`s session as private session for sending expect.
> +        """
> +        return self.crb.send_expect(cmds, expected, timeout=timeout,
> alt_session=alt_session)
> +
> +    def __get_os_type(self):
> +        """
> +        Get OS type.
> +        """
> +        return self.crb.get_os_type()
> +
> +    def nic_is_pf(self):
> +        """
> +        It is the method that you can check if the nic is PF.
> +        """
> +        return True
> +
> +    def nic_has_driver(func):
> +        """
> +        Check if the NIC has a driver.
> +        """
> +        @wraps(func)
> +        def wrapper(*args, **kwargs):
> +            nic_instance = args[0]
> +            nic_instance.current_driver = nic_instance.get_nic_driver()
> +            if not nic_instance.current_driver:
> +                return ''
> +            return func(*args, **kwargs)
> +        return wrapper
> +
> +    def get_nic_driver(self):
> +        """
> +        Get the NIC driver.
> +        """
> +        return self.crb.get_pci_dev_driver(self.bus_id, self.devfun_id)
> +
> +    @nic_has_driver
> +    def get_interface_name(self):
> +        """
> +        Get interface name of specified pci device.
> +        """
> +        get_interface_name = getattr(
> +            self, 'get_interface_name_%s' %
> +            self.__get_os_type())
> +        return get_interface_name(self.bus_id, self.devfun_id,
> self.current_driver)
> +
> +    def get_interface_name_linux(self, bus_id, devfun_id, driver):
> +        """
> +        Get interface name of specified pci device on linux.
> +        """
> +        try:
> +            get_interface_name_linux = getattr(
> +                self,
> +                'get_interface_name_linux_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_interface_name_linux = getattr(self,
> +
> 'get_interface_name_linux_%s' % generic_driver)
> +
> +        return get_interface_name_linux(bus_id, devfun_id)
> +
> +    def get_interface_name_linux_generic(self, bus_id, devfun_id):
> +        """
> +        Get the interface name by the default way on linux.
> +        """
> +        command = 'ls --color=never
> /sys/bus/pci/devices/0000\:%s\:%s/net' % (
> +            bus_id, devfun_id)
> +        return self.__send_expect(command, '# ')
> +
> +    def get_interface_name_freebsd(self, bus_id, devfun_id, driver):
> +        """
> +        Get interface name of specified pci device on Freebsd.
> +        """
> +        try:
> +            get_interface_name_linux = getattr(self,
> +
> 'get_interface_name_freebsd_%s' % driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_interface_name_linux = getattr(self,
> +
> 'get_interface_name_freebsd_%s' % generic_driver)
> +
> +        return get_interface_name_freebsd(bus_id, devfun_id)
> +
> +    def get_interface_name_freebsd_generic(self, bus_id, devfun_id):
> +        """
> +        Get the interface name by the default way on freebsd.
> +        """
> +        out = self.__send_expect("pciconf -l", "# ")
> +        rexp = r"(\w*)@pci0:%s" % bus_id
> +        pattern = re.compile(rexp)
> +        match = pattern.findall(out)
> +        return match[0]
> +
> +    @nic_has_driver
> +    def get_mac_addr(self):
> +        """
> +        Get mac address of specified pci device.
> +        """
> +        get_mac_addr = getattr(self, 'get_mac_addr_%s' %
> self.__get_os_type())
> +        return get_mac_addr(self.intf_name, self.bus_id,
> self.devfun_id, self.current_driver)
> +
> +    def get_mac_addr_linux(self, intf, bus_id, devfun_id, driver):
> +        """
> +        Get mac address of specified pci device on linux.
> +        """
> +        try:
> +            get_mac_addr_linux = getattr(
> +                self,
> +                'get_mac_addr_linux_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_mac_addr_linux = getattr(
> +                self,
> +                'get_mac_addr_linux_%s' %
> +                generic_driver)
> +
> +        return get_mac_addr_linux(intf, bus_id, devfun_id, driver)
> +
> +    def get_pci_id(self, bus_id, devfun_id):
> +        command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/vendor' %
> +                   (bus_id, devfun_id))
> +        out = self.__send_expect(command, '# ')
> +        vender = out[2:]
> +        command = ('cat /sys/bus/pci/devices/0000\:%s\:%s/device' %
> +                   (bus_id, devfun_id))
> +        out = self.__send_expect(command, '# ')
> +        device = out[2:]
> +        return "%s:%s" % (vender, device)
> +
> +    def get_mac_addr_linux_generic(self, intf, bus_id, devfun_id,
> driver):
> +        """
> +        Get MAC by the default way on linux.
> +        """
> +        command = ('cat
> /sys/bus/pci/devices/0000\:%s\:%s/net/%s/address' %
> +                   (bus_id, devfun_id, intf))
> +        return self.__send_expect(command, '# ')
> +
> +    def get_mac_addr_freebsd(self, intf, bus_id, devfun_id, driver):
> +        """
> +        Get mac address of specified pci device on Freebsd.
> +        """
> +        try:
> +            get_mac_addr_freebsd = getattr(
> +                self,
> +                'get_mac_addr_freebsd_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_mac_addr_freebsd = getattr(
> +                self,
> +                'get_mac_addr_freebsd_%s' %
> +                generic_driver)
> +
> +        return get_mac_addr_freebsd(intf, bus_id, devfun_id, driver)
> +
> +    def get_mac_addr_freebsd_generic(self, intf, bus_id, devfun_id):
> +        """
> +        Get the MAC by the default way on Freebsd.
> +        """
> +        out = self.__send_expect('ifconfig %s' % intf, '# ')
> +        rexp = r"ether ([\da-f:]*)"
> +        pattern = re.compile(rexp)
> +        match = pattern.findall(out)
> +        return match[0]
> +
> +    @nic_has_driver
> +    def get_ipv4_addr(self):
> +        """
> +        Get ipv4 address of specified pci device.
> +        """
> +        get_ipv4_addr = getaddr(
> +            self, 'get_ipv4_addr_%s' % self.__get_os_type())
> +        return get_ipv4_addr(self.intf_name, self.currenct_driver)
> +
> +    def get_ipv4_addr_linux(self, intf, driver):
> +        """
> +        Get ipv4 address of specified pci device on linux.
> +        """
> +        try:
> +            get_ipv4_addr_linux = getattr(self, 'get_ipv4_linux_%s' %
> driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_ipv4_addr_linux = getattr(
> +                self, 'get_ipv4_linux_%s' %
> +                generic_driver)
> +
> +        return get_ipv4_addr_linux(intf, bus_id, devfun_id, driver)
> +
> +    def get_ipv4_addr_linux_generic(self, intf):
> +        """
> +        Get IPv4 address by the default way on linux.
> +        """
> +        out = self.__send_expect("ip -family inet address show dev %s
> | awk '/inet/ { print $2 }'"
> +                                 % intf, "# ")
> +        return out.split('/')[0]
> +
> +    def get_ipv4_addr_freebsd(self, intf, driver):
> +        """
> +        Get ipv4 address of specified pci device on Freebsd.
> +        """
> +        try:
> +            get_ipv4_addr_freebsd = getattr(
> +                self,
> +                'get_ipv4_addr_freebsd_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_ipv4_addr_freebsd = getattr(
> +                self,
> +                'get_ipv4_addr_freebsd_%s' %
> +                generic_driver)
> +
> +        return get_ipv4_addr_freebsd(intf, bus_id, devfun_id)
> +
> +    def get_ipv4_addr_freebsd_generic(self, intf):
> +        """
> +        Get the IPv4 address by the default way on Freebsd.
> +        """
> +        out = self.__send_expect('ifconfig %s' % intf, '# ')
> +        rexp = r"inet ([\d:]*)%"
> +        pattern = re.compile(rexp)
> +        match = pattern.findall(out)
> +        if len(match) == 0:
> +            return None
> +
> +        return match[0]
> +
> +    @nic_has_driver
> +    def get_ipv6_addr(self):
> +        """
> +        Get ipv6 address of specified pci device.
> +        """
> +        get_ipv6_addr = getattr(
> +            self, 'get_ipv6_addr_%s' % self.__get_os_type())
> +        return get_ipv6_addr(self.intf_name, self.current_driver)
> +
> +    def get_ipv6_addr_linux(self, intf, driver):
> +        """
> +        Get ipv6 address of specified pci device on linux.
> +        """
> +        try:
> +            get_ipv6_addr_linux = getattr(
> +                self,
> +                'get_ipv6_addr_linux_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_ipv6_addr_linux = getattr(
> +                self,
> +                'get_ipv6_addr_linux_%s' %
> +                generic_driver)
> +
> +        return get_ipv6_addr_linux(intf)
> +
> +    def get_ipv6_addr_linux_generic(self, intf):
> +        """
> +        Get the IPv6 address by the default way on linux.
> +        """
> +        out = self.__send_expect("ip -family inet6 address show dev %s
> | awk '/inet6/ { print $2 }'"
> +                                 % intf, "# ")
> +        return out.split('/')[0]
> +
> +    def get_ipv6_addr_freebsd(self, intf, driver):
> +        """
> +        Get ipv6 address of specified pci device on Freebsd.
> +        """
> +        try:
> +            get_ipv6_addr_freebsd = getattr(
> +                self,
> +                'get_ipv6_addr_freebsd_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_ipv6_addr_freebsd = getattr(
> +                self,
> +                'get_ipv6_addr_freebsd_%s' %
> +                generic_driver)
> +
> +        return get_ipv6_addr_freebsd(intf)
> +
> +    def get_ipv6_addr_freebsd_generic(self, intf):
> +        """
> +        Get the IPv6 address by the default way on Freebsd.
> +        """
> +        out = self.__send_expect('ifconfig %s' % intf, '# ')
> +        rexp = r"inet6 ([\da-f:]*)%"
> +        pattern = re.compile(rexp)
> +        match = pattern.findall(out)
> +        if len(match) == 0:
> +            return None
> +
> +        return match[0]
> +
> +    def get_nic_numa(self):
> +        """
> +        Get numa number of specified pci device.
> +        """
> +        self.crb.get_nic_numa(self.bus_id, self.devfun_id)
> +
> +    def get_card_type(self):
> +        """
> +        Get card type of specified pci device.
> +        """
> +        return self.crb.get_pci_dev_id(self.bus_id, self.devfun_id)
> +
> +    @nic_has_driver
> +    def get_sriov_vfs_pci(self):
> +        """
> +        Get all SRIOV VF pci bus of specified pci device.
> +        """
> +        get_sriov_vfs_pci = getattr(
> +            self, 'get_sriov_vfs_pci_%s' % self.__get_os_type())
> +        return get_sriov_vfs_pci(self.bus_id, self.devfun_id,
> self.current_driver)
> +
> +    def get_sriov_vfs_pci_linux(self, bus_id, devfun_id, driver):
> +        """
> +        Get all SRIOV VF pci bus of specified pci device on linux.
> +        """
> +        try:
> +            get_sriov_vfs_pci_linux = getattr(
> +                self,
> +                'get_sriov_vfs_pci_linux_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            get_sriov_vfs_pci_linux = getattr(
> +                self,
> +                'get_sriov_vfs_pci_linux_%s' %
> +                generic_driver)
> +
> +        return get_sriov_vfs_pci_linux(bus_id, devfun_id)
> +
> +    def get_sriov_vfs_pci_linux_generic(self, bus_id, devfun_id):
> +        """
> +        Get all the VF PCIs of specified PF by the default way on
> linux.
> +        """
> +        sriov_numvfs = self.__send_expect(
> +            "cat /sys/bus/pci/devices/0000\:%s\:%s/sriov_numvfs" %
> +            (bus_id, devfun_id), "# ")
> +        sriov_vfs_pci = []
> +        if int(sriov_numvfs) == 0:
> +            pass
> +        else:
> +            try:
> +                virtfns = self.__send_expect(
> +                    "ls -d /sys/bus/pci/devices/0000\:%s\:%s/virtfn*" %
> +                    (bus_id, devfun_id), "# ")
> +                for virtfn in virtfns.split():
> +                    vf_uevent = self.__send_expect(
> +                        "cat %s" %
> +                        os.path.join(virtfn, "uevent"), "# ")
> +                    vf_pci = re.search(
> +                        r"PCI_SLOT_NAME=0000:([0-9a-f]+:[0-9a-f]+\.[0-
> 9a-f]+)",
> +                        vf_uevent).group(1)
> +                    sriov_vfs_pci.append(vf_pci)
> +            except Exception as e:
> +                print "Scan linux port [0000:%s.%s] sriov vf
> failed: %s" % (bus_id, devfun_id, e)
> +
> +        return sriov_vfs_pci
> +
> +    @nic_has_driver
> +    def generate_sriov_vfs(self, vf_num):
> +        """
> +        Generate some numbers of SRIOV VF.
> +        """
> +        if vf_num == 0:
> +            self.bind_vf_driver()
> +        generate_sriov_vfs = getattr(
> +            self, 'generate_sriov_vfs_%s' %
> +            self.__get_os_type())
> +        generate_sriov_vfs(
> +            self.bus_id,
> +            self.devfun_id,
> +            vf_num,
> +            self.current_driver)
> +        if vf_num != 0:
> +            self.sriov_vfs_pci = self.get_sriov_vfs_pci()
> +
> +            vf_pci = self.sriov_vfs_pci[0]
> +            addr_array = vf_pci.split(':')
> +            bus_id = addr_array[0]
> +            devfun_id = addr_array[1]
> +
> +            self.default_vf_driver = self.crb.get_pci_dev_driver(
> +                bus_id, devfun_id)
> +        else:
> +            self.sriov_vfs_pci = []
> +        time.sleep(1)
> +
> +    def generate_sriov_vfs_linux(self, bus_id, devfun_id, vf_num,
> driver):
> +        """
> +        Generate some numbers of SRIOV VF.
> +        """
> +        try:
> +            generate_sriov_vfs_linux = getattr(
> +                self,
> +                'generate_sriov_vfs_linux_%s' %
> +                driver)
> +        except Exception as e:
> +            generic_driver = 'generic'
> +            generate_sriov_vfs_linux = getattr(
> +                self,
> +                'generate_sriov_vfs_linux_%s' %
> +                generic_driver)
> +
> +        return generate_sriov_vfs_linux(bus_id, devfun_id, vf_num)
> +
> +    def generate_sriov_vfs_linux_generic(self, bus_id, devfun_id,
> vf_num):
> +        """
> +        Generate SRIOV VFs by the default way on linux.
> +        """
> +        nic_driver = self.get_nic_driver()
> +
> +        if not nic_driver:
> +            return None
> +
> +        vf_reg_file = "sriov_numvfs"
> +        vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
> +                                   (bus_id, devfun_id), vf_reg_file)
> +        self.__send_expect("echo %d > %s" %
> +                           (int(vf_num), vf_reg_path), "# ")
> +
> +    def generate_sriov_vfs_linux_igb_uio(self, bus_id, devfun_id,
> vf_num):
> +        """
> +        Generate SRIOV VFs by the special way of igb_uio driver on
> linux.
> +        """
> +        nic_driver = self.get_nic_driver()
> +
> +        if not nic_driver:
> +            return None
> +
> +        vf_reg_file = "max_vfs"
> +        vf_reg_path = os.path.join("/sys/bus/pci/devices/0000:%s:%s" %
> +                                   (bus_id, devfun_id), vf_reg_file)
> +        self.__send_expect("echo %d > %s" %
> +                           (int(vf_num), vf_reg_path), "# ")
> +
> +    def destroy_sriov_vfs(self):
> +        """
> +        Destroy the SRIOV VFs.
> +        """
> +        self.generate_sriov_vfs(0)
> +
> +    def bind_vf_driver(self, pci='', driver=''):
> +        """
> +        Bind the specified driver to VF.
> +        """
> +        bind_vf_driver = getattr(self, 'bind_driver_%s' %
> self.__get_os_type())
> +        if not driver:
> +            if not self.default_vf_driver:
> +                print "Must specify a driver because default VF driver
> is NULL!"
> +                return
> +            driver = self.default_vf_driver
> +
> +        if not pci:
> +            if not self.sriov_vfs_pci:
> +                print "No VFs on the nic [%s]!" % self.pci
> +                return
> +            for vf_pci in self.sriov_vfs_pci:
> +                addr_array = vf_pci.split(':')
> +                bus_id = addr_array[0]
> +                devfun_id = addr_array[1]
> +
> +                bind_vf_driver(bus_id, devfun_id, driver)
> +        else:
> +            addr_array = pci.split(':')
> +            bus_id = addr_array[0]
> +            devfun_id = addr_array[1]
> +
> +            bind_vf_driver(bus_id, devfun_id, driver)
> +
> +    def bind_driver(self, driver=''):
> +        """
> +        Bind specified driver to PF.
> +        """
> +        bind_driver = getattr(self, 'bind_driver_%s' %
> self.__get_os_type())
> +        if not driver:
> +            if not self.default_driver:
> +                print "Must specify a driver because default driver is
> NULL!"
> +                return
> +            driver = self.default_driver
> +        ret = bind_driver(self.bus_id, self.devfun_id, driver)
> +        time.sleep(1)
> +        return ret
> +
> +    def bind_driver_linux(self, bus_id, devfun_id, driver):
> +        """
> +        Bind NIC port to specified driver on linux.
> +        """
> +        driver_alias = driver.replace('-', '_')
> +        try:
> +            bind_driver_linux = getattr(
> +                self,
> +                'bind_driver_linux_%s' %
> +                driver_alias)
> +            return bind_driver_linux(bus_id, devfun_id)
> +        except Exception as e:
> +            driver_alias = 'generic'
> +            bind_driver_linux = getattr(
> +                self,
> +                'bind_driver_linux_%s' %
> +                driver_alias)
> +            return bind_driver_linux(bus_id, devfun_id, driver)
> +
> +    def bind_driver_linux_generic(self, bus_id, devfun_id, driver):
> +        """
> +        Bind NIC port to specified driver by the default way on linux.
> +        """
> +        nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
> +        self.__send_expect(
> +            "echo %s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
> +            (nic_pci_num, bus_id, devfun_id), "# ")
> +        self.__send_expect(
> +            "echo %s > /sys/bus/pci/drivers/%s/bind" %
> +            (nic_pci_num, driver), "# ")
> +
> +    def bind_driver_linux_pci_stub(self, bus_id, devfun_id):
> +        """
> +        Bind NIC port to the pci-stub driver on linux.
> +        """
> +        nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
> +        pci_id = self.get_card_type()
> +        self.__send_expect(
> +            "echo %s > /sys/bus/pci/drivers/pci-stub/new_id" %
> +            nic_pci_num, "# ")
> +        self.__send_expect(
> +            "echo %s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind" %
> +            (nic_pci_num, bus_id, devfun_id), "# ")
> +        self.__send_expect(
> +            "echo %s > /sys/bus/pci/drivers/pci-stub/bind" %
> +            nic_pci_num, "# ")
> +
> +    @nic_has_driver
> +    def unbind_driver(self, driver=''):
> +        """
> +        Unbind driver.
> +        """
> +        unbind_driver = getattr(
> +            self, 'unbind_driver_%s' %
> +            self.__get_os_type())
> +        if not driver:
> +            driver = 'generic'
> +        ret = unbind_driver(self.bus_id, self.devfun_id, driver)
> +        time.sleep(1)
> +        return ret
> +
> +    def unbind_driver_linux(self, bus_id, devfun_id, driver):
> +        """
> +        Unbind driver on linux.
> +        """
> +        driver_alias = driver.replace('-', '_')
> +
> +        unbind_driver_linux = getattr(
> +            self, 'unbind_driver_linux_%s' % driver_alias)
> +        return unbind_driver_linux(bus_id, devfun_id)
> +
> +    def unbind_driver_linux_generic(self, bus_id, devfun_id):
> +        """
> +        Unbind driver by the default way on linux.
> +        """
> +        nic_pci_num = ':'.join(['0000', bus_id, devfun_id])
> +        cmd = "echo %s >
> /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind"
> +        self.send_expect(cmd % (nic_pci_num, bus_id, devfun_id), "# ")
> diff --git a/framework/settings.py b/framework/settings.py
> index feb6fa5..2eccc64 100644
> --- a/framework/settings.py
> +++ b/framework/settings.py
> @@ -48,6 +48,7 @@ NICS = {
>      'powerville': '8086:1521',
>      'ophir': '8086:105e',
>      'niantic': '8086:10fb',
> +    'niantic_vf': '8086:10ed',
>      'ironpond': '8086:151c',
>      'twinpond': '8086:1528',
>      'twinville': '8086:1512',
> @@ -77,6 +78,7 @@ DRIVERS = {
>      'powerville': 'igb',
>      'ophir': 'igb',
>      'niantic': 'ixgbe',
> +    'niantic_vf': 'ixgbevf',
>      'ironpond': 'ixgbe',
>      'twinpond': 'ixgbe',
>      'twinville': 'ixgbe',
> @@ -137,6 +139,17 @@ Global macro for dts.
>  """
>  IXIA = "ixia"
> 
> +"""
> +The root path of framework configs.
> +"""
> +CONFIG_ROOT_PATH = "./conf/"
> +
> +"""
> +The log name seperater.
> +"""
> +LOG_NAME_SEP = '.'
> +
> +
>  def nic_name_from_type(type):
>      """
>      strip nic code name by nic type
> @@ -145,3 +158,33 @@ def nic_name_from_type(type):
>          if nic_type == type:
>              return name
>      return 'Unknown'
> +
> +
> +def get_nic_driver(pci_id):
> +    """
> +    Return linux driver for specified pci device
> +    """
> +    driverlist = dict(zip(NICS.values(), DRIVERS.keys()))
> +    try:
> +        driver = DRIVERS[driverlist[pci_id]]
> +    except Exception as e:
> +        driver = None
> +    return driver
> +
> +
> +def accepted_nic(pci_id):
> +    """
> +    Return True if the pci_id is a known NIC card in the settings file
> and if
> +    it is selected in the execution file, otherwise it returns False.
> +    """
> +    if pci_id not in NICS.values():
> +        return False
> +
> +    if nic is 'any':
> +        return True
> +
> +    else:
> +        if pci_id == NICS[nic]:
> +            return True
> +
> +    return False
> diff --git a/framework/test_case.py b/framework/test_case.py
> index 3d2e2dc..a519691 100644
> --- a/framework/test_case.py
> +++ b/framework/test_case.py
> @@ -40,10 +40,11 @@ from settings import DRIVERS, NICS,
> nic_name_from_type
> 
>  class TestCase(object):
> 
> -    def __init__(self, dut, tester, target):
> +    def __init__(self, dut, tester, target, suite):
>          self.dut = dut
>          self.tester = tester
>          self.target = target
> +        self.suite = suite
>          self.nics = []
>          for portid in range(len(self.dut.ports_info)):
>              nic_type = self.dut.ports_info[portid]['type']
> diff --git a/framework/tester.py b/framework/tester.py
> index aba0356..ce136e4 100644
> --- a/framework/tester.py
> +++ b/framework/tester.py
> @@ -38,6 +38,7 @@ from time import sleep
>  from settings import NICS
>  from ssh_connection import SSHConnection
>  from crb import Crb
> +from net_device import NetDevice
>  from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
>  from logger import getLogger
>  from settings import IXIA
> @@ -152,6 +153,7 @@ class Tester(Crb):
>              index += 1
>              if pci == port['pci']:
>                  return index
> +        return -1
> 
>      def get_pci(self, localPort):
>          """
> @@ -163,6 +165,9 @@ class Tester(Crb):
>          """
>          Return tester local port interface name.
>          """
> +        if 'intf' not in self.ports_info[localPort]:
> +            return 'N/A'
> +
>          return self.ports_info[localPort]['intf']
> 
>      def get_mac(self, localPort):
> @@ -202,26 +207,51 @@ class Tester(Crb):
>          try:
>              for (pci_bus, pci_id) in self.pci_devices_info:
>                  addr_array = pci_bus.split(':')
> -                itf = self.get_interface_name(addr_array[0],
> addr_array[1])
> +                port = NetDevice(self, addr_array[0], addr_array[1])
> +                itf = port.get_interface_name()
> +                self.enable_ipv6(itf)
>                  self.send_expect("ifconfig %s up" % itf, "# ")
> 
>          except Exception as e:
>              self.logger.error("   !!! Restore ITF: " + e.message)
> 
> +        sleep(2)
> +
> +    def load_serializer_ports(self):
> +        self.ports_info = []
> +        cached_ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> +        if cached_ports_info is None:
> +            return
> +
> +        # now not save netdev object, will implemented later
> +        self.ports_info = cached_ports_info
> +
> +    def save_serializer_ports(self):
> +        cached_ports_info = []
> +        for port in self.ports_info:
> +            port_info = {}
> +            for key in port.keys():
> +                if type(port[key]) is str:
> +                    port_info[key] = port[key]
> +                # need save netdev objects
> +            cached_ports_info.append(port_info)
> +        self.serializer.save(self.PORT_INFO_CACHE_KEY,
> cached_ports_info)
> +
>      def scan_ports(self):
>          """
>          Scan all ports on tester and save port's pci/mac/interface.
>          """
>          if self.read_cache:
> -            self.ports_info =
> self.serializer.load(self.PORT_INFO_CACHE_KEY)
> +            self.load_serializer_ports()
> 
>          if not self.read_cache or self.ports_info is None:
>              self.scan_ports_uncached()
>              if self.it_uses_external_generator():
> 
> self.ports_info.extend(self.ixia_packet_gen.get_ports())
> -            self.serializer.save(self.PORT_INFO_CACHE_KEY,
> self.ports_info)
> +            self.save_serializer_ports()
> 
> -        self.logger.info(self.ports_info)
> +        for port_info in self.ports_info:
> +            self.logger.info(port_info)
> 
>      def scan_ports_uncached(self):
>          """
> @@ -240,7 +270,8 @@ class Tester(Crb):
>              bus_id = addr_array[0]
>              devfun_id = addr_array[1]
> 
> -            intf = self.get_interface_name(bus_id, devfun_id)
> +            port = NetDevice(self, bus_id, devfun_id)
> +            intf = port.get_interface_name()
> 
>              if "No such file" in intf:
>                  self.logger.info("Tester: [000:%s %s] %s" % (pci_bus,
> pci_id,
> @@ -248,13 +279,17 @@ class Tester(Crb):
>                  continue
> 
>              self.logger.info("Tester: [000:%s %s] %s" % (pci_bus,
> pci_id, intf))
> -            macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
> +            macaddr = port.get_mac_addr()
> +
> +            ipv6 = port.get_ipv6_addr()
> 
>              # store the port info to port mapping
> -            self.ports_info.append({'pci': pci_bus,
> +            self.ports_info.append({'port': port,
> +                                    'pci': pci_bus,
>                                      'type': pci_id,
>                                      'intf': intf,
> -                                    'mac': macaddr})
> +                                    'mac': macaddr,
> +                                    'ipv6': ipv6})
> 
>      def send_ping6(self, localPort, ipv6, mac):
>          """
> --
> 1.9.0



More information about the dts mailing list