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

sjiajiax sunx.jiajia at intel.com
Mon May 18 07:07:18 CEST 2015


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)
         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:
+            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