Ejemplo n.º 1
0
 def __init__(self, oper_type, vm_list, portchannel_ports, vm_dut_map, test_args, vlan_ports, ports_per_vlan):
     self.oper_type = ''
     self.memb_cnt = 0
     self.cnt = 1 if 'routing' not in oper_type else len(vm_list)
     self.ip_cnt = 1
     self.vm_list = vm_list
     self.portchannel_ports = portchannel_ports
     self.vm_dut_map = vm_dut_map
     self.test_args = test_args
     self.dut_connection = DeviceConnection(test_args['dut_hostname'], test_args['dut_username'], password=test_args['dut_password'])
     self.vlan_ports = vlan_ports
     self.ports_per_vlan = ports_per_vlan
     self.vlan_if_port = self.test_args['vlan_if_port']
     self.neigh_vms = []
     self.neigh_names = dict()
     self.vm_handles = dict()
     self.neigh_bgps = dict()
     self.dut_bgps = dict()
     self.log = []
     self.fails = dict()
     self.fails['dut'] = set()
     self.tot_memb_cnt = 0
     self.memb_index = 0
     self.if_port = []
     self.down_vlan_info = []
     self.bp_ip = None
     self.bp_ip6 = None
     self.extract_oper_info(oper_type)
     self.extract_nexthops()
Ejemplo n.º 2
0
    def setUp(self):
        self.dataplane = ptf.dataplane_instance

        config = self.get_param('config_file')
        self.ferret_ip = self.get_param('ferret_ip')
        self.dut_ssh = self.get_param('dut_ssh')
        self.dut_username = self.get_param('dut_username')
        self.dut_password = self.get_param('dut_password')
        self.dut_connection = DeviceConnection(self.dut_ssh,
                                               username=self.dut_username,
                                               password=self.dut_password)
        self.how_long = int(
            self.get_param('how_long', required=False, default=300))

        if not os.path.isfile(config):
            raise Exception("the config file %s doesn't exist" % config)

        with open(config) as fp:
            graph = json.load(fp)

        self.tests = []
        vni_base = 0
        for name, data in graph['minigraph_vlans'].items():
            test = {}
            test['acc_ports'] = [
                graph['minigraph_port_indices'][member]
                for member in data['members']
            ]
            vlan_id = int(name.replace('Vlan', ''))
            test['vni'] = vni_base + vlan_id

            gw = None
            prefixlen = None
            for d in graph['minigraph_vlan_interfaces']:
                if d['attachto'] == name:
                    gw = d['addr']
                    prefixlen = int(d['prefixlen'])
                    break
            else:
                raise Exception("Vlan '%s' is not found" % name)

            test['vlan_gw'] = gw
            test['vlan_ip_prefixes'] = self.generate_VlanPrefixes(
                gw, prefixlen, test['acc_ports'])

            self.tests.append(test)

        self.dut_mac = graph['dut_mac']

        self.ptf_mac_addrs = self.readMacs()

        self.generatePackets()

        self.cmd(["supervisorctl", "restart", "ferret"])

        self.dataplane.flush()

        return
Ejemplo n.º 3
0
    def setUp(self):
        self.dataplane = ptf.dataplane_instance

        self.test_params = testutils.test_params_get()
        if 'vxlan_enabled' in self.test_params and self.test_params[
                'vxlan_enabled']:
            self.vxlan_enabled = True

        if 'count' in self.test_params:
            self.nr = int(self.test_params['count'])

        if 'config_file' not in self.test_params:
            raise Exception("required parameter 'config_file' is not present")
        config = self.test_params['config_file']

        if 'dut_host' not in self.test_params:
            raise Exception("required parameter 'dut_host' is not present")
        self.dut_host = self.test_params['dut_host']

        if 'sonic_admin_user' not in self.test_params:
            raise Exception(
                "required parameter 'sonic_admin_user' is not present")
        self.sonic_admin_user = self.test_params['sonic_admin_user']

        if 'sonic_admin_password' not in self.test_params:
            raise Exception(
                "required parameter 'sonic_admin_password' is not present")
        self.sonic_admin_password = self.test_params['sonic_admin_password']

        if not os.path.isfile(config):
            raise Exception("the config file %s doesn't exist" % config)

        with open(config) as fp:
            graph = json.load(fp)

        self.pc_info = []
        self.net_ports = []
        for name, val in graph['minigraph_portchannels'].items():
            members = [
                graph['minigraph_port_indices'][member]
                for member in val['members']
            ]
            self.net_ports.extend(members)
            ip = None

            for d in graph['minigraph_portchannel_interfaces']:
                if d['attachto'] == name:
                    ip = d['peer_addr']
                    break
            else:
                raise Exception("Portchannel '%s' ip address is not found" %
                                name)

            self.pc_info.append((ip, members))

        self.tests = []
        vni_base = 336
        for name, data in graph['minigraph_vlans'].items():
            test = {}
            test['name'] = name
            test['intf_alias'] = data['members']
            test['acc_ports'] = [
                graph['minigraph_port_indices'][member]
                for member in data['members']
            ]
            vlan_id = int(name.replace('Vlan', ''))
            test['vni'] = vni_base + vlan_id
            test['src_ip'] = "8.8.8.8"

            gw = None
            prefixlen = None
            for d in graph['minigraph_vlan_interfaces']:
                if d['attachto'] == name:
                    gw = d['addr']
                    prefixlen = int(d['prefixlen'])
                    break
            else:
                raise Exception("Vlan '%s' is not found" % name)

            test['vlan_gw'] = gw
            test['vlan_ip_prefixes'] = self.generate_VlanPrefixes(
                gw, prefixlen, test['acc_ports'])

            self.tests.append(test)
        self.log('Collected tests: {}'.format(pprint.pformat(self.tests)))

        self.dut_mac = graph['dut_mac']

        ip = None
        for data in graph['minigraph_lo_interfaces']:
            if data['prefixlen'] == 32:
                ip = data['addr']
                break
        else:
            raise Exception("ipv4 lo interface not found")

        self.loopback_ip = ip

        self.ptf_mac_addrs = self.readMacs()

        self.generate_ArpResponderConfig()

        self.cmd(["supervisorctl", "restart", "arp_responder"])
        #Wait a short time for asp_reponder to be ready
        time.sleep(10)
        self.dataplane.flush()
        self.dut_connection = DeviceConnection(
            self.dut_host,
            self.sonic_admin_user,
            password=self.sonic_admin_password)

        return
Ejemplo n.º 4
0
class Vxlan(BaseTest):
    def __init__(self):
        BaseTest.__init__(self)

        self.vxlan_enabled = False
        self.random_mac = '8c:01:02:03:04:05'
        self.nr = 1
        current_time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        log_file_name = "/tmp/vxlan_decap_test.{}.log".format(current_time)
        self.log_fp = open(log_file_name, 'w')

    def cmd(self, cmds):
        process = subprocess.Popen(cmds,
                                   shell=False,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()
        return_code = process.returncode

        return stdout, stderr, return_code

    def log(self, message):
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.log_fp.write("{} : {}\n".format(current_time, message))
        self.log_fp.flush()

    def readMacs(self):
        addrs = {}
        for intf in os.listdir('/sys/class/net'):
            if os.path.isdir('/sys/class/net/%s' % intf):
                with open('/sys/class/net/%s/address' % intf) as fp:
                    addrs[intf] = fp.read().strip()

        return addrs

    def generate_ArpResponderConfig(self):
        config = {}
        for test in self.tests:
            for port, ip in test['vlan_ip_prefixes'].items():
                config['eth%d' % port] = [ip]

        with open('/tmp/vxlan_arpresponder.conf', 'w') as fp:
            json.dump(config, fp)

        return

    def generate_VlanPrefixes(self, gw, prefixlen, acc_ports):
        res = {}
        n_hosts = 2**(32 - prefixlen) - 3
        nr_of_dataplane_ports = len(self.dataplane.ports)

        if nr_of_dataplane_ports > n_hosts:
            raise Exception("The prefix len size is too small for the test")

        gw_addr_n = struct.unpack(">I", socket.inet_aton(gw))[0]
        mask = (2**32 - 1) ^ (2**(32 - prefixlen) - 1)
        net_addr_n = gw_addr_n & mask

        addr = 1
        for port in acc_ports:
            while True:
                host_addr_n = net_addr_n + addr
                host_ip = socket.inet_ntoa(struct.pack(">I", host_addr_n))
                if host_ip != gw:
                    break
                else:
                    addr += 1  # skip gw
            res[port] = host_ip
            addr += 1

        return res

    def setUp(self):
        self.dataplane = ptf.dataplane_instance

        self.test_params = testutils.test_params_get()
        if 'vxlan_enabled' in self.test_params and self.test_params[
                'vxlan_enabled']:
            self.vxlan_enabled = True

        if 'count' in self.test_params:
            self.nr = int(self.test_params['count'])

        if 'config_file' not in self.test_params:
            raise Exception("required parameter 'config_file' is not present")
        config = self.test_params['config_file']

        if 'dut_host' not in self.test_params:
            raise Exception("required parameter 'dut_host' is not present")
        self.dut_host = self.test_params['dut_host']

        if 'sonic_admin_user' not in self.test_params:
            raise Exception(
                "required parameter 'sonic_admin_user' is not present")
        self.sonic_admin_user = self.test_params['sonic_admin_user']

        if 'sonic_admin_password' not in self.test_params:
            raise Exception(
                "required parameter 'sonic_admin_password' is not present")
        self.sonic_admin_password = self.test_params['sonic_admin_password']

        if not os.path.isfile(config):
            raise Exception("the config file %s doesn't exist" % config)

        with open(config) as fp:
            graph = json.load(fp)

        self.pc_info = []
        self.net_ports = []
        for name, val in graph['minigraph_portchannels'].items():
            members = [
                graph['minigraph_port_indices'][member]
                for member in val['members']
            ]
            self.net_ports.extend(members)
            ip = None

            for d in graph['minigraph_portchannel_interfaces']:
                if d['attachto'] == name:
                    ip = d['peer_addr']
                    break
            else:
                raise Exception("Portchannel '%s' ip address is not found" %
                                name)

            self.pc_info.append((ip, members))

        self.tests = []
        vni_base = 336
        for name, data in graph['minigraph_vlans'].items():
            test = {}
            test['name'] = name
            test['intf_alias'] = data['members']
            test['acc_ports'] = [
                graph['minigraph_port_indices'][member]
                for member in data['members']
            ]
            vlan_id = int(name.replace('Vlan', ''))
            test['vni'] = vni_base + vlan_id
            test['src_ip'] = "8.8.8.8"

            gw = None
            prefixlen = None
            for d in graph['minigraph_vlan_interfaces']:
                if d['attachto'] == name:
                    gw = d['addr']
                    prefixlen = int(d['prefixlen'])
                    break
            else:
                raise Exception("Vlan '%s' is not found" % name)

            test['vlan_gw'] = gw
            test['vlan_ip_prefixes'] = self.generate_VlanPrefixes(
                gw, prefixlen, test['acc_ports'])

            self.tests.append(test)
        self.log('Collected tests: {}'.format(pprint.pformat(self.tests)))

        self.dut_mac = graph['dut_mac']

        ip = None
        for data in graph['minigraph_lo_interfaces']:
            if data['prefixlen'] == 32:
                ip = data['addr']
                break
        else:
            raise Exception("ipv4 lo interface not found")

        self.loopback_ip = ip

        self.ptf_mac_addrs = self.readMacs()

        self.generate_ArpResponderConfig()

        self.cmd(["supervisorctl", "restart", "arp_responder"])
        #Wait a short time for asp_reponder to be ready
        time.sleep(10)
        self.dataplane.flush()
        self.dut_connection = DeviceConnection(
            self.dut_host,
            self.sonic_admin_user,
            password=self.sonic_admin_password)

        return

    def check_arp_table_on_dut(self, test):
        COMMAND = 'show arp'
        stdout, stderr, return_code = self.dut_connection.execCommand(COMMAND)
        for idx, port in enumerate(test['acc_ports']):
            intf_alias = test['intf_alias'][idx]
            ip_prefix = test['vlan_ip_prefixes'][port]
            for line in stdout:
                if re.match(r"{}.*{}.*".format(ip_prefix, intf_alias), line,
                            re.IGNORECASE):
                    break
            else:
                return False
        return True

    def check_fdb_on_dut(self, test):
        COMMAND = 'fdbshow'
        stdout, stderr, return_code = self.dut_connection.execCommand(COMMAND)
        for idx, port in enumerate(test['acc_ports']):
            mac_addr = self.ptf_mac_addrs['eth%d' % port]
            intf_alias = test['intf_alias'][idx]
            for line in stdout:
                if re.match(r".*{}.*{}.*".format(mac_addr, intf_alias), line,
                            re.IGNORECASE):
                    break
            else:
                return False
        return True

    def wait_dut(self, test, timeout):
        start_time = datetime.datetime.now()
        while True:
            if self.check_fdb_on_dut(test) and self.check_arp_table_on_dut(
                    test):
                return True
            if (datetime.datetime.now() - start_time).seconds > timeout:
                return False
            time.sleep(3)

    def tearDown(self):
        self.cmd(["supervisorctl", "stop", "arp_responder"])
        self.log_fp.close()
        return

    def warmup(self):
        self.log("Warming up")
        err = ''
        trace = ''
        ret = 0
        TIMEOUT = 60
        try:
            for test in self.tests:
                self.RegularLAGtoVLAN(test, True)
                #wait sometime for DUT to build FDB and ARP table
                res = self.wait_dut(test, TIMEOUT)
                self.log_dut_status()
                self.assertTrue(
                    res, "DUT is not ready after {} seconds".format(TIMEOUT))

        except Exception as e:
            err = str(e)
            trace = traceback.format_exc()
            ret = -1
        if ret != 0:
            self.log("The warmup failed")
            self.log("Error: %s" % err)
            self.log(trace)
        else:
            self.log("Warmup successful")
        sys.stdout.flush()
        if ret != 0:
            raise AssertionError("Warmup failed")

    def log_dut_status(self):
        COMMAND = 'show arp'
        stdout, stderr, return_code = self.dut_connection.execCommand(COMMAND)
        self.log("ARP table on DUT \n{}".format(stdout))

        COMMAND = 'fdbshow'
        stdout, stderr, return_code = self.dut_connection.execCommand(COMMAND)
        self.log("MAC table on DUT \n{}".format(stdout))

        COMMAND = 'show vxlan tunnel'
        stdout, stderr, return_code = self.dut_connection.execCommand(COMMAND)
        self.log("vxlan config on DUT \n{}".format(stdout))

    def work_test(self):
        self.log("Testing")
        err = ''
        trace = ''
        ret = 0
        try:
            for test in self.tests:
                self.log(test['name'])

                res_f, out_f = self.RegularLAGtoVLAN(test)
                self.log("RegularLAGtoVLAN = {} {}".format(res_f, out_f))
                if not res_f:
                    self.log_dut_status()
                self.assertTrue(
                    res_f, "RegularLAGtoVLAN test failed:\n  %s\n" % (out_f))

                res_t, out_t = self.RegularVLANtoLAG(test)
                self.log("RegularVLANtoLAG = {} {}".format(res_t, out_t))
                if not res_t:
                    self.log_dut_status()
                self.assertTrue(
                    res_t, "RegularVLANtoLAG test failed:\n  %s\n" % (out_t))

                res_v, out_v = self.Vxlan(test)
                self.log("Vxlan = {} {}".format(res_v, out_v))
                if self.vxlan_enabled:
                    if not res_v:
                        self.log_dut_status()
                    self.assertTrue(res_v,
                                    "VxlanTest failed:\n  %s\n" % (out_v))
                else:
                    if res_v:
                        self.log_dut_status()
                    self.assertFalse(
                        res_v,
                        "VxlanTest: vxlan works, but it must have been disabled!\n"
                    )
        except AssertionError as e:
            err = str(e)
            trace = traceback.format_exc()
            ret = -1
        if ret != 0:
            self.log("The test failed")
            self.log("Error: {}".format(err))
            self.log(trace)
        else:
            self.log("The test was successful")
        sys.stdout.flush()
        if ret != 0:
            raise AssertionError(err)

    def runTest(self):
        # Warm-up first
        self.warmup()
        # test itself
        self.work_test()

    def Vxlan(self, test):
        for i, n in enumerate(test['acc_ports']):
            for j, a in enumerate(test['acc_ports']):
                res, out = self.checkVxlan(a, n, test)
                if not res:
                    return False, out + " | net_port_rel(acc)=%d acc_port_rel=%d" % (
                        i, j)

        for i, n in enumerate(self.net_ports):
            for j, a in enumerate(test['acc_ports']):
                res, out = self.checkVxlan(a, n, test)
                if not res:
                    return False, out + " | net_port_rel=%d acc_port_rel=%d" % (
                        i, j)
        return True, ""

    def RegularLAGtoVLAN(self, test, wu=False):
        for i, n in enumerate(self.net_ports):
            for j, a in enumerate(test['acc_ports']):
                res, out = self.checkRegularRegularLAGtoVLAN(a, n, test, wu)
                if wu:
                    #Wait a short time for building FDB and ARP table
                    time.sleep(0.5)
                if not res and not wu:
                    return False, out + " | net_port_rel=%d acc_port_rel=%d" % (
                        i, j)
            #We only loop all acc_ports in warmup
            if wu:
                break
        return True, ""

    def RegularVLANtoLAG(self, test):
        for i, (dst, ports) in enumerate(self.pc_info):
            for j, a in enumerate(test['acc_ports']):
                res, out = self.checkRegularRegularVLANtoLAG(
                    a, ports, dst, test)
                if not res:
                    return False, out + " | pc_info_rel=%d acc_port_rel=%d" % (
                        i, j)
        return True, ""

    def checkRegularRegularVLANtoLAG(self, acc_port, pc_ports, dst_ip, test):
        src_mac = self.ptf_mac_addrs['eth%d' % acc_port]
        dst_mac = self.dut_mac
        src_ip = test['vlan_ip_prefixes'][acc_port]

        packet = simple_tcp_packet(
            eth_dst=dst_mac,
            eth_src=src_mac,
            ip_src=src_ip,
            ip_dst=dst_ip,
        )
        exp_packet = simple_tcp_packet(
            eth_dst=self.random_mac,
            eth_src=dst_mac,
            ip_src=src_ip,
            ip_dst=dst_ip,
            ip_ttl=63,
        )

        exp_packet = Mask(exp_packet)
        exp_packet.set_do_not_care_scapy(scapy.Ether, "dst")

        self.dataplane.flush()
        for i in xrange(self.nr):
            testutils.send_packet(self, acc_port, packet)
        nr_rcvd = count_matched_packets_all_ports_helper(self,
                                                         exp_packet,
                                                         self.nr,
                                                         pc_ports,
                                                         timeout=20)
        rv = nr_rcvd == self.nr
        out = ""
        if not rv:
            arg = self.nr, nr_rcvd, str(acc_port), str(
                pc_ports), src_mac, dst_mac, src_ip, dst_ip
            out = "sent = %d rcvd = %d | src_port=%s dst_ports=%s | src_mac=%s dst_mac=%s src_ip=%s dst_ip=%s" % arg
        return rv, out

    def checkRegularRegularLAGtoVLAN(self, acc_port, net_port, test, wu):
        src_mac = self.random_mac
        dst_mac = self.dut_mac
        src_ip = test['src_ip']
        dst_ip = test['vlan_ip_prefixes'][acc_port]

        packet = simple_tcp_packet(
            eth_dst=dst_mac,
            eth_src=src_mac,
            ip_src=src_ip,
            ip_dst=dst_ip,
        )

        exp_packet = simple_tcp_packet(
            eth_dst=self.ptf_mac_addrs['eth%d' % acc_port],
            eth_src=dst_mac,
            ip_src=src_ip,
            ip_dst=dst_ip,
            ip_ttl=63,
        )

        self.dataplane.flush()
        for i in xrange(self.nr):
            testutils.send_packet(self, net_port, packet)
        # We don't care if expected packet is received during warming up
        if not wu:
            nr_rcvd = count_matched_packets_helper(self,
                                                   exp_packet,
                                                   self.nr,
                                                   acc_port,
                                                   timeout=20)
        else:
            nr_rcvd = 0
        rv = nr_rcvd == self.nr
        out = ""
        if not rv:
            arg = self.nr, nr_rcvd, str(net_port), str(
                acc_port), src_mac, dst_mac, src_ip, dst_ip
            out = "sent = %d rcvd = %d | src_port=%s dst_port=%s | src_mac=%s dst_mac=%s src_ip=%s dst_ip=%s" % arg
        return rv, out

    def checkVxlan(self, acc_port, net_port, test):
        inner_dst_mac = self.ptf_mac_addrs['eth%d' % acc_port]
        inner_src_mac = self.dut_mac
        inner_src_ip = test['vlan_gw']
        inner_dst_ip = test['vlan_ip_prefixes'][acc_port]
        dst_mac = self.dut_mac
        src_mac = self.random_mac
        ip_dst = self.loopback_ip

        inpacket = simple_arp_packet(eth_dst=inner_dst_mac,
                                     eth_src=inner_src_mac,
                                     arp_op=2,
                                     ip_snd=inner_src_ip,
                                     ip_tgt=inner_dst_ip,
                                     hw_snd=inner_src_mac,
                                     hw_tgt=inner_dst_mac)

        packet = simple_vxlan_packet(eth_dst=dst_mac,
                                     eth_src=src_mac,
                                     ip_src=test['src_ip'],
                                     ip_dst=ip_dst,
                                     vxlan_vni=test['vni'],
                                     inner_frame=inpacket)

        self.dataplane.flush()
        for i in xrange(self.nr):
            testutils.send_packet(self, net_port, packet)
        nr_rcvd = count_matched_packets_helper(self,
                                               inpacket,
                                               self.nr,
                                               acc_port,
                                               timeout=20)
        rv = nr_rcvd == self.nr
        out = ""
        if not rv:
            arg = self.nr, nr_rcvd, str(net_port), str(
                acc_port
            ), src_mac, dst_mac, test[
                'src_ip'], ip_dst, inner_src_mac, inner_dst_mac, inner_src_ip, inner_dst_ip, test[
                    'vni']
            out = "sent = %d rcvd = %d | src_port=%s dst_port=%s | src_mac=%s dst_mac=%s src_ip=%s dst_ip=%s | Inner: src_mac=%s dst_mac=%s src_ip=%s dst_ip=%s vni=%s" % arg
        return rv, out
Ejemplo n.º 5
0
    def setUp(self):
        self.dataplane = ptf.dataplane_instance

        config = self.get_param('config_file')
        self.ferret_ip = self.get_param('ferret_ip')
        self.dut_ssh = self.get_param('dut_ssh')
        self.dut_username = self.get_param('dut_username')
        self.dut_password = self.get_param('dut_password')
        self.dut_alt_password = self.get_param('alt_password')
        self.dut_connection = DeviceConnection(
            self.dut_ssh,
            username=self.dut_username,
            password=self.dut_password,
            alt_password=self.dut_alt_password)
        self.how_long = int(
            self.get_param('how_long', required=False, default=300))

        if not os.path.isfile(config):
            raise Exception("the config file %s doesn't exist" % config)

        with open(config) as fp:
            graph = json.load(fp)

        self.tests = []
        vni_base = 0
        for vlan, config in graph['vlan_facts'].items():
            test = {}
            test['acc_ports'] = []
            test['tagging_mode'] = {}
            for member, mode in config['members'].items():
                ptf_port_idx = graph['minigraph_port_indices'][member]
                test['acc_ports'].append(ptf_port_idx)
                test['tagging_mode'].update(
                    {ptf_port_idx: mode['tagging_mode']})
            test['vlan_id'] = int(config['vlanid'])
            test['vni'] = vni_base + test['vlan_id']

            prefixlen = None
            for d in config['interfaces']:
                if sys.version_info < (3, 0):
                    ip = ipaddress.ip_address(d['addr'].decode('utf8'))
                else:
                    ip = ipaddress.ip_address(d['addr'])
                if ip.version == 4:
                    test['vlan_gw'] = d['addr']
                    prefixlen = int(d['prefixlen'])
                    test['vlan_ip_prefixes'] = self.generate_VlanPrefixes(
                        d['addr'], prefixlen, test['acc_ports'])
                    break
            else:
                raise Exception("No invalid IPv4 address found for Vlan '%s'" %
                                vlan)

            self.tests.append(test)

        self.dut_mac = graph['dut_mac']

        self.ptf_mac_addrs = self.readMacs()

        self.generatePackets()

        self.cmd(["supervisorctl", "restart", "ferret"])

        self.dataplane.flush()

        return