Esempio n. 1
0
    def get_device_ids(cls, controller=None, olt_conf_file=''):
        '''If running under olt, we get the first switch connected to onos'''
        olt = OltConfig(olt_conf_file=olt_conf_file)
        did = 'of:' + get_mac()
        device_ids = []
        if olt.on_olt():
            devices = cls.get_devices(controller=controller)
            if devices:
                device_ids = map(lambda d: d['id'], devices)
        else:
            device_ids.append(did)

        return device_ids
Esempio n. 2
0
    def get_device_id(cls, controller=None, mfr=None, olt_conf_file=''):
        '''If running under olt, we get the first switch connected to onos'''
        olt = OltConfig(olt_conf_file=olt_conf_file)
        did = 'of:' + get_mac()
        if olt.on_olt():
            devices = cls.get_devices(controller=controller, mfr=mfr)
            if devices:
                dids = map(lambda d: d['id'], devices)
                if len(dids) == 1:
                    did = dids[0]
                else:
                    ###If we have more than 1, then check for env before using first one
                    did = os.getenv('OLT_DEVICE_ID', dids[0])

        return did
Esempio n. 3
0
class ACLTest:

    auth = ('karaf', 'karaf')
    controller = get_controller()
    add_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' % (controller)
    remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules/%s' % (controller,
                                                                   id)
    clear_all_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' % (controller)
    iface_create_onos_url = 'http://%s:8181/onos/v1/network/configuration' % (
        controller)
    device_id = 'of:' + get_mac()
    MAX_PORTS = 100

    def __init__(self,
                 ipv4Prefix='v4',
                 srcIp='null',
                 dstIp='null',
                 ipProto='null',
                 dstTpPort=0,
                 action='null',
                 ingress_iface=1,
                 egress_iface=2,
                 iface_num=0,
                 iface_name='null',
                 iface_count=0,
                 iface_ip='null'):
        self.ipv4Prefix = ipv4Prefix
        self.srcIp = srcIp
        self.ingress_iface = ingress_iface
        self.egress_iface = egress_iface
        self.dstIp = dstIp
        self.ipProto = ipProto
        self.dstTpPort = dstTpPort
        self.action = action
        self.iface_count = iface_count
        self.iface_num = iface_num
        self.iface_name = iface_name
        self.iface_ip = iface_ip
        self.device_id = OnosCtrl.get_device_id()

    def adding_acl_rule(self,
                        ipv4Prefix,
                        srcIp,
                        dstIp,
                        ipProto='null',
                        dstTpPort='null',
                        action='include',
                        controller=None):
        '''This function is generating ACL json file and post to ONOS for creating a ACL rule'''
        if ipv4Prefix is 'v4':
            acl_dict = {}
            if srcIp and dstIp and action:
                acl_dict['srcIp'] = '{}'.format(srcIp)
                acl_dict['dstIp'] = '{}'.format(dstIp)
                acl_dict['action'] = '{}'.format(action)
            if ipProto is not 'null':
                acl_dict['ipProto'] = '{}'.format(ipProto)
            if dstTpPort is not 'null':
                acl_dict['dstTpPort'] = '{}'.format(dstTpPort)
        json_data = json.dumps(acl_dict)
        if controller is None:
            # if controller  ip is not passed, it will default controller ip
            resp = requests.post(self.add_acl_rule_url,
                                 auth=self.auth,
                                 data=json_data)
        else:
            add_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' % (
                controller)
            log_test.info('add_acl_rule_acl url is %s' % add_acl_rule_url)
            resp = requests.post(add_acl_rule_url,
                                 auth=self.auth,
                                 data=json_data)
        return resp.ok, resp.status_code

    def get_acl_rules(self, controller=None):
        '''This function is getting a ACL rules from ONOS with json formate'''
        if controller is None:
            resp = requests.get(self.add_acl_rule_url, auth=self.auth)
        else:
            add_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' % (
                controller)
            log_test.info('get_acl_rule_url is %s' % add_acl_rule_url)
            resp = requests.get(add_acl_rule_url, auth=self.auth)
        return resp

    @classmethod
    def remove_acl_rule(cls, id=None, controller=None):
        '''This function is delete one or all  ACL rules in ONOS'''
        if id is None:
            if controller is None:
                remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' % (
                    cls.controller)
            else:
                remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' % (
                    controller)
        else:
            if controller is None:
                remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules/%s' % (
                    cls.controller, id)
            else:
                remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules/%s' % (
                    controller, id)
        log_test.info('remove_acl_rule_url is %s' % remove_acl_rule_url)
        resp = requests.delete(remove_acl_rule_url, auth=cls.auth)
        return resp.ok, resp.status_code

    def generate_onos_interface_config(self,
                                       iface_num=4,
                                       iface_name='null',
                                       iface_count=1,
                                       iface_ip='198.162.10.1'):
        '''This function is generate interface config data in json format and post to ONOS for creating it '''
        ''' To add interfaces on ONOS to test acl with trffic'''
        num = 0
        egress_host_list = []
        interface_list = []
        ip = iface_ip.split('/')[0]
        start_iface_ip = ip.split('.')
        start_ip = (int(start_iface_ip[0]) << 24) | (
            int(start_iface_ip[1]) << 16) | (int(start_iface_ip[2]) << 8) | 0
        end_ip = (200 << 24) | (168 << 16) | (10 << 8) | 0
        ports_dict = {'ports': {}}
        for n in xrange(start_ip, end_ip, 256):
            port_map = ports_dict['ports']
            port = iface_num if num < self.MAX_PORTS - 1 else self.MAX_PORTS - 1
            device_port_key = '{0}/{1}'.format(self.device_id, port)
            try:
                interfaces = port_map[device_port_key]['interfaces']
            except:
                port_map[device_port_key] = {'interfaces': []}
                interfaces = port_map[device_port_key]['interfaces']
            ip = n + 2
            peer_ip = n + 1
            ips = '%d.%d.%d.%d/%d' % ((ip >> 24) & 0xff, ((ip >> 16) & 0xff), (
                (ip >> 8) & 0xff), ip & 0xff, int(iface_ip.split('/')[1]))
            peer = '%d.%d.%d.%d' % ((peer_ip >> 24) & 0xff,
                                    ((peer_ip >> 16) & 0xff),
                                    ((peer_ip >> 8) & 0xff), peer_ip & 0xff)
            mac = RandMAC()._fix()
            egress_host_list.append((peer, mac))
            if num < self.MAX_PORTS - 1:
                interface_dict = {
                    'name': '{0}-{1}'.format(iface_name, port),
                    'ips': [ips],
                    'mac': mac
                }
                interfaces.append(interface_dict)
                interface_list.append(interface_dict['name'])
            else:
                interfaces[0]['ips'].append(ips)
            num += 1
            if num == iface_count:
                break
        json_data = json.dumps(ports_dict)
        resp = requests.post(self.iface_create_onos_url,
                             auth=self.auth,
                             data=json_data)
        return resp.ok, resp.status_code, egress_host_list
Esempio n. 4
0
class proxyarp_exchange(unittest.TestCase):

    apps = ('org.onosproject.vrouter', 'org.onosproject.proxyarp')
    device_id = 'of:' + get_mac()
    device_dict = {
        "devices": {
            "{}".format(device_id): {
                "basic": {
                    "driver": "softrouter"
                }
            }
        },
    }
    test_path = os.path.dirname(os.path.realpath(__file__))
    onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
    GATEWAY = '192.168.10.50'
    INGRESS_PORT = 1
    EGRESS_PORT = 2
    MAX_PORTS = 100
    hosts_list = [
        ('192.168.10.1', '00:00:00:00:00:01'),
        ('192.168.11.1', '00:00:00:00:02:01'),
    ]

    @classmethod
    def setUpClass(cls):
        cls.olt = OltConfig()
        cls.port_map, _ = cls.olt.olt_port_map()
        if not cls.port_map:
            cls.port_map = g_subscriber_port_map
        time.sleep(3)
        cls.load_device_id()

    @classmethod
    def tearDownClass(cls):
        '''Deactivate the vrouter apps'''
        #cls.vrouter_host_unload()

    @classmethod
    def load_device_id(cls):
        did = OnosCtrl.get_device_id()
        cls.device_id = did
        cls.device_dict = {
            "devices": {
                "{}".format(did): {
                    "basic": {
                        "driver": "softrouter"
                    }
                }
            },
        }

    def cliEnter(self):
        retries = 0
        while retries < 3:
            self.cli = OnosCliDriver(connect=True)
            if self.cli.handle:
                break
            else:
                retries += 1
                time.sleep(2)

    def cliExit(self):
        self.cli.disconnect()

    @classmethod
    def proxyarp_host_unload(cls):
        index = 1
        for host, _ in cls.hosts_list:
            iface = cls.port_map[index]
            index += 1
            config_cmds = ('ifconfig {} 0'.format(iface), )
            for cmd in config_cmds:
                log_test.info('host unload command %s' % cmd)
                os.system(cmd)

    @classmethod
    def interface_config_load(cls, interface_cfg=None):
        if type(interface_cfg) is tuple:
            res = []
            for v in interface_cfg:
                if type(v) == list:
                    pass
                else:
                    res += v.items()
                    config = dict(res)
        else:
            config = interface_cfg
        cfg = json.dumps(config)
        with open('{}/network-cfg.json'.format(cls.onos_config_path),
                  'w') as f:
            f.write(cfg)
        return cord_test_onos_restart()

    @classmethod
    def host_config_load(cls, host_config=None):
        for host in host_config:
            status, code = OnosCtrl.host_config(host)
            if status is False:
                log_test.info('JSON request returned status %d' % code)
                assert_equal(status, True)

    @classmethod
    def generate_interface_config(cls, hosts=1):
        num = 0
        start_host = (192 << 24) | (168 << 16) | (10 << 8) | 0
        end_host = (200 << 24) | (168 << 16) | (10 << 8) | 0
        ports_dict = {'ports': {}}
        interface_list = []
        hosts_list = []
        for n in xrange(start_host, end_host, 256):
            port_map = ports_dict['ports']
            port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
            device_port_key = '{0}/{1}'.format(cls.device_id, port)
            try:
                interfaces = port_map[device_port_key]['interfaces']
            except:
                port_map[device_port_key] = {'interfaces': []}
                interfaces = port_map[device_port_key]['interfaces']
            ip = n + 1
            host_ip = n + 2
            ips = '%d.%d.%d.%d/24' % ((ip >> 24) & 0xff, ((ip >> 16) & 0xff),
                                      ((ip >> 8) & 0xff), ip & 0xff)
            host = '%d.%d.%d.%d' % ((host_ip >> 24) & 0xff,
                                    ((host_ip >> 16) & 0xff),
                                    ((host_ip >> 8) & 0xff), host_ip & 0xff)
            mac = RandMAC()._fix()
            hosts_list.append((host, mac))
            if num < cls.MAX_PORTS - 1:
                interface_dict = {
                    'name': 'b1-{}'.format(port),
                    'ips': [ips],
                    'mac': mac
                }
                interfaces.append(interface_dict)
                interface_list.append(interface_dict['name'])
            else:
                interfaces[0]['ips'].append(ips)
            num += 1
            if num == hosts:
                break
        cls.hosts_list = hosts_list
        return (cls.device_dict, ports_dict, hosts_list)

    @classmethod
    def generate_host_config(cls):
        num = 0
        hosts_dict = {}
        for host, mac in cls.hosts_list:
            port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
            hosts_dict[host] = {
                'mac': mac,
                'vlan': 'none',
                'ipAddresses': [host],
                'location': {
                    'elementId': '{}'.format(cls.device_id),
                    'port': port
                }
            }
            num += 1
        return hosts_dict.values()

    @classmethod
    def proxyarp_activate(cls, deactivate=False):
        app = 'org.onosproject.proxyarp'
        onos_ctrl = OnosCtrl(app)
        if deactivate is True:
            onos_ctrl.deactivate()
        else:
            onos_ctrl.activate()
        time.sleep(3)

    @classmethod
    def proxyarp_config(cls, hosts=1):
        proxyarp_configs = cls.generate_interface_config(hosts=hosts)
        cls.interface_config_load(interface_cfg=proxyarp_configs)
        hostcfg = cls.generate_host_config()
        cls.host_config_load(host_config=hostcfg)
        return proxyarp_configs

    def proxyarp_arpreply_verify(self,
                                 ingress,
                                 hostip,
                                 hostmac,
                                 PositiveTest=True):
        log_test.info(
            'verifying arp reply for host ip %s host mac %s on interface %s' %
            (hostip, hostmac, self.port_map[ingress]))
        self.success = False

        def recv_task():
            def recv_cb(pkt):
                log_test.info('Arp Reply seen with source Mac is %s' %
                              (pkt[ARP].hwsrc))
                self.success = True if PositiveTest == True else False

            sniff(count=1,
                  timeout=2,
                  lfilter=lambda p: ARP in p and p[ARP].op == 2 and p[ARP].
                  hwsrc == hostmac,
                  prn=recv_cb,
                  iface=self.port_map[ingress])

        t = threading.Thread(target=recv_task)
        t.start()
        pkt = (Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(op=1, pdst=hostip))
        log_test.info('sending arp request  for dest ip %s on interface %s' %
                      (hostip, self.port_map[ingress]))
        sendp(pkt, count=10, iface=self.port_map[ingress])
        t.join()
        if PositiveTest:
            assert_equal(self.success, True)
        else:
            assert_equal(self.success, False)

    def __proxyarp_hosts_verify(self, hosts=1, PositiveTest=True):
        _, _, hosts_config = self.proxyarp_config(hosts=hosts)
        log_test.info('\nhosts_config %s and its type %s' %
                      (hosts_config, type(hosts_config)))
        self.cliEnter()
        connected_hosts = json.loads(self.cli.hosts(jsonFormat=True))
        log_test.info('Discovered hosts: %s' % connected_hosts)
        #We read from cli if we expect less number of routes to avoid cli timeouts
        if hosts <= 10000:
            assert_equal(len(connected_hosts), hosts)
        ingress = hosts + 1
        for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,
                                          hostip,
                                          hostmac,
                                          PositiveTest=PositiveTest)
            time.sleep(1)
        self.cliExit()
        return True

    def test_proxyarp_with_1_host(self, hosts=1):
        res = self.__proxyarp_hosts_verify(hosts=hosts)
        assert_equal(res, True)
#cls.proxyarp_host_unload()

    def test_proxyarp_with_10_hosts(self, hosts=10):
        res = self.__proxyarp_hosts_verify(hosts=hosts)
        assert_equal(res, True)

    def test_proxyarp_with_50_hosts(self, hosts=50):
        res = self.__proxyarp_hosts_verify(hosts=hosts)
        assert_equal(res, True)

    def test_proxyarp_app_with_disabling_and_re_enabling(self, hosts=3):
        ports_map, egress_map, hosts_config = self.proxyarp_config(hosts=hosts)
        ingress = hosts + 1
        for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,
                                          hostip,
                                          hostmac,
                                          PositiveTest=True)
            time.sleep(1)
        log_test.info(
            'Deactivating proxyarp  app and expecting not to get arp reply from ONOS'
        )
        self.proxyarp_activate(deactivate=True)
        for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,
                                          hostip,
                                          hostmac,
                                          PositiveTest=False)
            time.sleep(1)
        log_test.info(
            'activating proxyarp  app and expecting to get arp reply from ONOS'
        )
        self.proxyarp_activate(deactivate=False)
        for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,
                                          hostip,
                                          hostmac,
                                          PositiveTest=True)
            time.sleep(1)

    def test_proxyarp_nonexisting_host(self, hosts=1):
        _, _, hosts_config = self.proxyarp_config(hosts=hosts)
        ingress = hosts + 2
        for host, mac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,
                                          host,
                                          mac,
                                          PositiveTest=True)
        new_host = hosts_config[-1][0].split('.')
        new_host[2] = str(int(new_host[2]) + 1)
        new_host = '.'.join(new_host)
        new_mac = RandMAC()._fix()
        log_test.info('verifying arp reply for host ip %s on interface %s' %
                      (new_host, self.port_map[ingress]))
        res = srp1(Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(op=1, pdst=new_host),
                   timeout=2,
                   iface=self.port_map[ingress])
        assert_equal(res, None)
        log_test.info(
            'arp reply not seen for host ip %s on interface %s as expected' %
            (new_host, self.port_map[ingress]))
        hosts = hosts + 1
        _, _, hosts_config = self.proxyarp_config(hosts=hosts)
        for host in hosts_config:
            if host[0] == new_host:
                new_mac = host[1]
        self.proxyarp_arpreply_verify(ingress,
                                      new_host,
                                      new_mac,
                                      PositiveTest=True)

    def test_proxyarp_removing_host(self, hosts=3):
        ports_map, egress_map, hosts_config = self.proxyarp_config(hosts=hosts)
        ingress = hosts + 1
        for hostip, hostmac in hosts_config:
            self.proxyarp_arpreply_verify(ingress,
                                          hostip,
                                          hostmac,
                                          PositiveTest=True)
            time.sleep(1)
        host_mac = hosts_config[0][1]
        log_test.info('removing host entry %s' % host_mac)
        self.cliEnter()
        hostentries = json.loads(self.cli.hosts(jsonFormat=True))
        for host in hostentries:
            res = host_mac.upper() in host.values()
            if res:
                break
        assert_equal(res, True)
        hostid = host_mac + '/' + 'None'
        delete_host = self.cli.host_remove(hostid)
        hostentries = json.loads(self.cli.hosts(jsonFormat=True))
        for host in hostentries:
            res = host_mac.upper() in host.values()
            if res:
                break
        assert_equal(res, False)
        self.proxyarp_arpreply_verify(ingress,
                                      hosts_config[0][0],
                                      host_mac,
                                      PositiveTest=False)
        time.sleep(1)
        self.cliExit()

    def test_proxyarp_concurrent_requests_with_multiple_host_and_different_interfaces(
            self, hosts=10):
        ports_map, egress_map, hosts_config = self.proxyarp_config(hosts=hosts)
        self.success = True
        ingress = hosts + 1
        ports = range(ingress, ingress + 10)
        hostmac = []
        hostip = []
        for ip, mac in hosts_config:
            hostmac.append(mac)
            hostip.append(ip)
        success_dir = {}

        def verify_proxyarp(*r):
            ingress, hostmac, hostip = r[0], r[1], r[2]

            def mac_recv_task():
                def recv_cb(pkt):
                    log_test.info('Arp Reply seen with source Mac is %s' %
                                  (pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True

                sniff(count=1,
                      timeout=5,
                      lfilter=lambda p: ARP in p and p[ARP].op == 2 and p[ARP].
                      hwsrc == hostmac,
                      prn=recv_cb,
                      iface=self.port_map[ingress])

            t = threading.Thread(target=mac_recv_task)
            t.start()
            pkt = (Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(op=1, pdst=hostip))
            log_test.info(
                'sending arp request  for dest ip %s on interface %s' %
                (hostip, self.port_map[ingress]))
            sendp(pkt, count=10, iface=self.port_map[ingress])
            t.join()

        t = []
        for i in range(10):
            t.append(
                threading.Thread(target=verify_proxyarp,
                                 args=[ports[i], hostmac[i], hostip[i]]))
        for i in range(10):
            t[i].start()
        for i in range(10):
            t[i].join()
        if len(success_dir) != 10:
            self.success = False
        assert_equal(self.success, True)

    def test_proxyarp_disabling_enabling_app_initiating_concurrent_requests(
            self, hosts=10):
        '''Test sending arp requests to multiple host ips at once from different interfaces by disabling and re-enabling proxyarp app'''
        ports_map, egress_map, hosts_config = self.proxyarp_config(hosts=hosts)
        self.success = True
        ingress = hosts + 1
        ports = range(ingress, ingress + 10)
        hostmac = []
        hostip = []
        for ip, mac in hosts_config:
            hostmac.append(mac)
            hostip.append(ip)
        success_dir = {}

        def verify_proxyarp(*r):
            ingress, hostmac, hostip = r[0], r[1], r[2]

            def mac_recv_task():
                def recv_cb(pkt):
                    log_test.info('Arp Reply seen with source Mac is %s' %
                                  (pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True

                sniff(count=1,
                      timeout=5,
                      lfilter=lambda p: ARP in p and p[ARP].op == 2 and p[ARP].
                      hwsrc == hostmac,
                      prn=recv_cb,
                      iface=self.port_map[ingress])

            t = threading.Thread(target=mac_recv_task)
            t.start()
            pkt = (Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(op=1, pdst=hostip))
            log_test.info(
                'sending arp request  for dest ip %s on interface %s' %
                (hostip, self.port_map[ingress]))
            sendp(pkt, count=10, iface=self.port_map[ingress])
            t.join()

        t1 = []
        #starting multi threading before proxyarp disable
        for i in range(10):
            t1.append(
                threading.Thread(target=verify_proxyarp,
                                 args=[ports[i], hostmac[i], hostip[i]]))
        for i in range(10):
            t1[i].start()
        for i in range(10):
            t1[i].join()
        if len(success_dir) != 10:
            self.success = False
        assert_equal(self.success, True)
        self.proxyarp_activate(deactivate=True)
        #starting multi threading after proxyarp disable
        t2 = []
        self.success = False
        for i in range(10):
            t2.append(
                threading.Thread(target=verify_proxyarp,
                                 args=[ports[i], hostmac[i], hostip[i]]))
        for i in range(10):
            t2[i].start()
        for i in range(10):
            t2[i].join()
        if len(success_dir) != 10:
            self.success = True
        assert_equal(self.success, False)
        self.proxyarp_activate(deactivate=False)
        #starting multi threading after proxyarp re-enable
        self.success = True
        t3 = []
        for i in range(10):
            t3.append(
                threading.Thread(target=verify_proxyarp,
                                 args=[ports[i], hostmac[i], hostip[i]]))
        for i in range(10):
            t3[i].start()
        for i in range(10):
            t3[i].join()
        if len(success_dir) != 20:
            self.success = False
        assert_equal(self.success, True)

    def test_proxyarp_with_existing_and_non_existing_hostIPs_initiating_concurrent_requests(
            self, hosts=5):
        ports_map, egress_map, hosts_config = self.proxyarp_config(hosts=hosts)
        self.success = True
        ingress = hosts + 1
        ports = range(ingress, ingress + 10)
        hostmac = []
        hostip = []
        for ip, mac in hosts_config:
            hostmac.append(mac)
            hostip.append(ip)
#adding 5 non-existing host IPs to hostip list
        for i in range(1, 6):
            ip = hostip[-1].split('.')
            ip[3] = str(int(ip[3]) + int(i))
            ip = '.'.join(ip)
            hostip.append(ip)
            hostmac.append(RandMAC()._fix())
        success_dir = {}
        replied_hosts = []

        def verify_proxyarp(*r):
            ingress, hostmac, hostip = r[0], r[1], r[2]

            def mac_recv_task():
                def recv_cb(pkt):
                    log_test.info('Arp Reply seen with source Mac is %s' %
                                  (pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True
                    replied_hosts.append(hostip)

                sniff(count=1,
                      timeout=5,
                      lfilter=lambda p: ARP in p and p[ARP].op == 2 and p[ARP].
                      psrc == hostip,
                      prn=recv_cb,
                      iface=self.port_map[ingress])

            t = threading.Thread(target=mac_recv_task)
            t.start()
            pkt = (Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(op=1, pdst=hostip))
            log_test.info(
                'sending arp request  for dest ip %s on interface %s' %
                (hostip, self.port_map[ingress]))
            sendp(pkt, count=10, iface=self.port_map[ingress])
            t.join()

        t = []
        for i in range(10):
            t.append(
                threading.Thread(target=verify_proxyarp,
                                 args=[ports[i], hostmac[i], hostip[i]]))
        for i in range(10):
            t[i].start()
        for i in range(10):
            t[i].join()
        if len(success_dir) != 5 and len(replied_hosts) != 5:
            self.success = False
        assert_equal(self.success, True)
        for i in range(5):
            if hostip[i] not in replied_hosts:
                self.success = False
        assert_equal(self.success, True)
Esempio n. 5
0
class ipv6vrouter_exchange(CordLogger):

    apps = ('org.onosproject.vrouter', 'org.onosproject.fwd')
    device_id = 'of:' + get_mac()
    vrouter_device_dict = {
        "devices": {
            "{}".format(device_id): {
                "basic": {
                    "driver": "softrouter"
                }
            }
        },
    }
    zebra_conf = '''
password zebra
log stdout
service advanced-vty
!
!debug zebra rib
!debug zebra kernel
!debug zebra fpm
!
interface eth1
 ipv6 address 2001::10/32
line vty
 exec-timeout 0 0
'''

    #! ip address 10.10.0.3/16
    test_path = os.path.dirname(os.path.realpath(__file__))
    quagga_config_path = os.path.join(test_path, '..', 'setup/quagga-config')
    onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
    GATEWAY = '1000:10:0:0:0:0:0:164'
    INGRESS_PORT = 1
    EGRESS_PORT = 2
    MAX_PORTS = 100
    peer_list = [
        ('2001:0:10:0:0:0:10:1', '00:00:00:00:00:01'),
        ('2001:0:20:0:0:0:20:1', '00:00:00:00:02:01'),
    ]
    network_list = []
    network_mask = 64
    default_routes_address = ('1001:0:10:0::/32', )
    default_peer_address = peer_list
    quagga_ip = os.getenv('QUAGGA_IP')

    @classmethod
    def setUpClass(cls):
        ''' Activate the vrouter apps'''
        cls.olt = OltConfig()
        cls.port_map, _ = cls.olt.olt_port_map()
        if not cls.port_map:
            cls.port_map = g_subscriber_port_map
        time.sleep(3)
        cls.load_device_id()

    @classmethod
    def tearDownClass(cls):
        '''Deactivate the vrouter apps'''
        cls.vrouter_host_unload()
        cls.start_onos(network_cfg={})

    @classmethod
    def load_device_id(cls):
        did = OnosCtrl.get_device_id()
        cls.device_id = did
        cls.vrouter_device_dict = {
            "devices": {
                "{}".format(did): {
                    "basic": {
                        "driver": "softrouter"
                    }
                }
            },
        }

    def cliEnter(self):
        retries = 0
        while retries < 3:
            self.cli = OnosCliDriver(connect=True)
            if self.cli.handle:
                break
            else:
                retries += 1
                time.sleep(2)

    def cliExit(self):
        self.cli.disconnect()

    @classmethod
    def onos_load_config(cls, config):
        status, code = OnosCtrl.config(config)
        if status is False:
            log_test.info('JSON request returned status %d' % code)
            assert_equal(status, True)

    @classmethod
    def vrouter_config_get(cls,
                           networks=4,
                           peers=1,
                           peer_address=None,
                           route_update=None,
                           router_address=None,
                           specific_peer=None):
        vrouter_configs = cls.generate_vrouter_conf(
            networks=networks,
            peers=peers,
            specific_peer=specific_peer,
            peer_address=peer_address,
            router_address=router_address)
        return vrouter_configs

    @classmethod
    def host_config_load(cls, host_config=None):
        for host in host_config:
            status, code = OnosCtrl.host_config(host)
            if status is False:
                log_test.info('JSON request returned status %d' % code)
                assert_equal(status, True)

    @classmethod
    def generate_host_config(cls, hosts_list=None):
        num = 1
        hosts_dict = {}
        if hosts_list is not None:
            hosts = hosts_list
        else:
            hosts = cls.peer_list
        for host, mac in hosts:
            port = num if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
            hosts_dict[host] = {
                'mac': mac,
                'vlan': 'none',
                'ipAddresses': [host],
                'location': {
                    'elementId': '{}'.format(cls.device_id),
                    'port': port
                }
            }
            num += 1
            return hosts_dict.values()

    @classmethod
    def vrouter_host_load(cls, peer_address=None):
        index = 1
        peer_info = peer_address if peer_address is not None else cls.peer_list

        for host, _ in peer_info:
            iface = cls.port_map[index]
            index += 1
            log_test.info('Assigning ip %s to interface %s' % (host, iface))
            config_cmds = (
                'ifconfig {} 0'.format(iface),
                'ifconfig {0} inet6 add {1}/64'.format(iface, host),
                'arping -I {0} {1} -c 2'.format(iface, host),
            )
            for cmd in config_cmds:
                os.system(cmd)

    @classmethod
    def vrouter_host_unload(cls, peer_address=None):
        index = 1
        peer_info = peer_address if peer_address is not None else cls.peer_list

        for host, _ in peer_info:
            iface = cls.port_map[index]
            index += 1
            config_cmds = ('ifconfig {} 0'.format(iface), )
            for cmd in config_cmds:
                os.system(cmd)

    @classmethod
    def start_onos(cls, network_cfg=None):
        if type(network_cfg) is tuple:
            res = []
            for v in network_cfg:
                res += v.items()
            config = dict(res)
        else:
            config = network_cfg
        log_test.info('Restarting ONOS with new network configuration %s' %
                      config)
        return cord_test_onos_restart(config=config)

    @classmethod
    def randomipv6(cls, subnet='2001::', prefix=64):
        random.seed()
        ipv6_address = IPAddress(subnet) + random.getrandbits(16)
        ipv6_network = IPNetwork(ipv6_address)
        ipv6_network.prefixlen = prefix
        output = '{},{}'.format(ipv6_address, ipv6_network)
        return '{}'.format(ipv6_address), '{}'.format(ipv6_network)

    @classmethod
    def start_quagga(cls, networks=4, peer_address=None, router_address=None):
        log_test.info('Peer address in quagga start is %s' % peer_address)
        log_test.info(
            'Restarting Quagga container with configuration for %d networks' %
            (networks))
        config = cls.generate_conf(networks=networks,
                                   peer_address=peer_address,
                                   router_address=router_address)
        if networks <= 10000:
            boot_delay = 25
        else:
            delay_map = [60, 100, 150, 200, 300, 450, 600, 800, 1000, 1200]
            n = min(networks / 100000, len(delay_map) - 1)
            boot_delay = delay_map[n]
        cord_test_quagga_restart(config=config, boot_delay=boot_delay)

    @classmethod
    def generate_vrouter_conf(cls,
                              networks=4,
                              peers=1,
                              peer_address=None,
                              specific_peer=None,
                              router_address=None):
        num = 0
        count = 0
        if peer_address is None:
            start_peer = (10 << 16)
            end_peer = (9999 << 16)
        else:
            ip = peer_address[0][0]
            start_ip = ip.split(':')
            start_peer = (int(start_ip[6]) << 16)
            end_peer = (9999 << 16)
        local_network = end_peer + 1
        ports_dict = {'ports': {}}
        interface_list = []
        peer_list = []
        for n in xrange(start_peer, end_peer, 65536):
            port_map = ports_dict['ports']
            port = num + 1 if count < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
            device_port_key = '{0}/{1}'.format(cls.device_id, port)
            try:
                interfaces = port_map[device_port_key]['interfaces']
            except:
                port_map[device_port_key] = {'interfaces': []}
                interfaces = port_map[device_port_key]['interfaces']
            if specific_peer is None:
                peer_ip = '2001:0:0:0:0:0:' + '%s:1' % ((n >> 16) & 0xffff)
            else:
                start_ip[6] = '%s' % ((n >> 16) & 0xffff)
                start_ip[-1] = '1'
                peer_ip = ':'.join(start_ip)
            peer_nt = peer_ip + '/112'
            mac = RandMAC()._fix()
            peer_list.append((peer_ip, mac))
            log_test.info('peer ip is %s and and peer network is %s' %
                          (peer_ip, peer_nt))
            if num < cls.MAX_PORTS - 1:
                interface_dict = {
                    'name': 'b1-{}'.format(port),
                    'ips': [peer_nt],
                    'mac': mac
                }
                interfaces.append(interface_dict)
                interface_list.append(interface_dict['name'])
            else:
                interfaces[0]['ips'].append(peer_nt)
            num += 1
            if num == peers:
                break
        quagga_dict = {
            'apps': {
                'org.onosproject.router': {
                    'router': {},
                    'bgp': {
                        'bgpSpeakers': []
                    }
                }
            }
        }
        quagga_router_dict = quagga_dict['apps']['org.onosproject.router'][
            'router']
        quagga_router_dict['ospfEnabled'] = True
        quagga_router_dict['interfaces'] = interface_list
        quagga_router_dict['controlPlaneConnectPoint'] = '{0}/{1}'.format(
            cls.device_id, peers + 1)

        #bgp_speaker_dict = { 'apps': { 'org.onosproject.router' : { 'bgp' : { 'bgpSpeakers' : [] } } } }
        bgp_speakers_list = quagga_dict['apps']['org.onosproject.router'][
            'bgp']['bgpSpeakers']
        speaker_dict = {}
        speaker_dict['name'] = 'bgp{}'.format(peers + 1)
        speaker_dict['connectPoint'] = '{0}/{1}'.format(
            cls.device_id, peers + 1)
        speaker_dict['peers'] = peer_list
        bgp_speakers_list.append(speaker_dict)
        cls.peer_list = peer_list
        return (cls.vrouter_device_dict, ports_dict, quagga_dict)

    @classmethod
    def generate_conf(cls, networks=4, peer_address=None, router_address=None):
        num = 0
        if router_address is None:
            start_network = (10 << 16)
            end_network = (9999 << 16)
            network_mask = 112
        else:
            ip = router_address
            start_ip = ip.split(':')
            network_mask = int(start_ip[7].split('/')[1])
            start_network = (int(start_ip[6]) << 16)
            end_network = (9999 << 16)
        net_list = []
        peer_list = peer_address if peer_address is not None else cls.peer_list
        network_list = []
        for n in xrange(start_network, end_network, 65536):
            if router_address is None:
                net = '3001:0:0:0:0:0:' + '%s:0' % ((n >> 16) & 0xffff)
            else:
                start_ip[6] = '%s' % ((n >> 16) & 0xffff)
                net = ':'.join(
                    (start_ip[0], start_ip[1], start_ip[2], start_ip[3],
                     start_ip[4], start_ip[5], start_ip[6], start_ip[7][0]))
            network_list.append(net)
            gateway = peer_list[num % len(peer_list)][0]
            net_route = 'ipv6 route {0}/{1} {2}'.format(
                net, network_mask, gateway)
            net_list.append(net_route)
            num += 1
            if num == networks:
                break
        cls.network_list = network_list
        cls.network_mask = network_mask
        zebra_routes = '\n'.join(net_list)
        return cls.zebra_conf + zebra_routes

    @classmethod
    def vrouter_activate(cls, deactivate=False):
        app = 'org.onosproject.vrouter'
        onos_ctrl = OnosCtrl(app)
        if deactivate is True:
            onos_ctrl.deactivate()
        else:
            onos_ctrl.activate()
        time.sleep(3)

    @classmethod
    def vrouter_configure(cls,
                          networks=4,
                          peers=1,
                          peer_address=None,
                          specific_peer=None,
                          route_update=None,
                          router_address=None,
                          time_expire=None,
                          adding_new_routes=None):
        vrouter_configs = cls.vrouter_config_get(networks=networks,
                                                 peers=peers,
                                                 specific_peer=specific_peer,
                                                 peer_address=peer_address,
                                                 route_update=route_update)
        cls.start_onos(network_cfg=vrouter_configs)
        hostcfg = cls.generate_host_config()
        cls.host_config_load(host_config=hostcfg)
        ##Start quagga
        cls.start_quagga(networks=networks,
                         peer_address=peer_address,
                         router_address=router_address)
        return vrouter_configs

    def vrouter_port_send_recv(self,
                               ingress,
                               egress,
                               dst_mac,
                               dst_ip,
                               positive_test=True):
        src_mac = '00:00:00:00:00:02'
        src_ip = '1000:11:12:13:14:15:16:17'
        self.success = False if positive_test else True
        timeout = 10 if positive_test else 1
        count = 2 if positive_test else 1
        self.start_sending = True

        def recv_task():
            def recv_cb(pkt):
                log_test.info('Pkt seen with ingress ip %s, egress ip %s' %
                              (pkt[IP].src, pkt[IP].dst))
                self.success = True if positive_test else False

            sniff(count=count,
                  timeout=timeout,
                  lfilter=lambda p: IP in p and p[IP].dst == dst_ip and p[IP].
                  src == src_ip,
                  prn=recv_cb,
                  iface=self.port_map[ingress])
            self.start_sending = False

        t = threading.Thread(target=recv_task)
        t.start()
        L2 = Ether(src=src_mac, dst=dst_mac)
        L3 = IPv6(src=src_ip, dst=dst_ip)
        pkt = L2 / L3
        log_test.info(
            'Sending a packet with dst ip %s, dst mac %s on port %s to verify if flows are correct'
            % (dst_ip, dst_mac, self.port_map[egress]))
        while self.start_sending is True:
            sendp(pkt, count=50, iface=self.port_map[egress])
        t.join()
        assert_equal(self.success, True)

    def vrouter_traffic_verify(self, positive_test=True, peer_address=None):
        if peer_address is None:
            peers = len(self.peer_list)
            peer_list = self.peer_list
        else:
            peers = len(peer_address)
            peer_list = peer_address
        egress = peers + 1
        num = 0
        num_hosts = 5 if positive_test else 1
        src_mac = '00:00:00:00:00:02'
        src_ip = '1000:11:12:13:14:15:16:17'
        last_bytes = [1234, 8364, 7360, '0af3', 'fdac']
        for network in self.network_list:
            num_ips = num_hosts
            octets = network.split(':')
            for byte in last_bytes:
                octets[-1] = str(byte)
                dst_ip = ':'.join(octets)
                dst_mac = peer_list[num % peers][1]
                port = (num % peers)
                ingress = port + 1
                #Since peers are on the same network
                ##Verify if flows are setup by sending traffic across
                self.vrouter_port_send_recv(ingress,
                                            egress,
                                            dst_mac,
                                            dst_ip,
                                            positive_test=positive_test)
            num += 1

    def __vrouter_network_verify(self,
                                 networks,
                                 peers=1,
                                 positive_test=True,
                                 start_network=None,
                                 start_peer_address=None,
                                 route_update=None,
                                 invalid_peers=None,
                                 time_expire=None,
                                 unreachable_route_traffic=None,
                                 deactivate_activate_vrouter=None,
                                 adding_new_routes=None,
                                 specific_peer=None):

        _, ports_map, egress_map = self.vrouter_configure(
            networks=networks,
            peers=peers,
            peer_address=start_peer_address,
            route_update=route_update,
            router_address=start_network,
            time_expire=time_expire,
            adding_new_routes=adding_new_routes,
            specific_peer=specific_peer)
        if self.network_list > 50:
            wait = len(self.network_list) / 20
            time.sleep(wait)
            log_test.info('waiting for %d seconds to verify routes in ONOS' %
                          wait)
        else:
            time.sleep(5)
        self.cliEnter()
        routes = json.loads(self.cli.routes(jsonFormat=True))
        assert_equal(len(routes['routes6']), networks)
        if invalid_peers is None:
            self.vrouter_traffic_verify()
        if time_expire is True:
            self.start_quagga(networks=networks,
                              peer_address=start_peer_address,
                              router_address='12.10.10.1/24')
            self.vrouter_traffic_verify()
        if unreachable_route_traffic is True:
            network_list_backup = self.network_list
            self.network_list = [
                '1:1:1:1:1:1:1:1', '2:2:2:2:2:2:2:2', '3:3:3:3:3:3:3:3',
                '4:4:4:4:4:4:4:4'
            ]
            self.vrouter_traffic_verify(positive_test=False)
            self.network_list = network_list_backup
        if deactivate_activate_vrouter is True:
            log_test.info(
                'Deactivating vrouter app in ONOS controller for negative scenario'
            )
            self.vrouter_activate(deactivate=True)
            #routes = json.loads(self.cli.routes(jsonFormat = False, cmd_exist = False))
            #assert_equal(len(routes['routes4']), 'Command not found')
            log_test.info(
                'Activating vrouter app again in ONOS controller for negative scenario'
            )
            self.vrouter_activate(deactivate=False)
            if self.network_list > 50:
                wait = len(self.network_list) / 20
                time.sleep(wait)
                log_test.info(
                    'waiting for %d seconds to verify routes in ONOS' % wait)
            else:
                time.sleep(5)
            routes = json.loads(self.cli.routes(jsonFormat=True))
            assert_equal(len(routes['routes4']), networks)
            self.vrouter_traffic_verify()
        self.cliExit()
        return True

    def __vrouter_network_verify_negative(self, networks, peers=1):
        ##Stop quagga. Test traffic again to see if flows were removed
        log_test.info('Stopping Quagga container')
        cord_test_quagga_stop()
        self.vrouter_traffic_verify(positive_test=False)
        log_test.info(
            'OVS flows have been removed successfully after Quagga was stopped'
        )
        self.start_quagga(networks=networks)
        self.vrouter_traffic_verify()
        log_test.info(
            'OVS flows have been successfully reinstalled after Quagga was restarted'
        )

    def quagga_shell(self, cmd):
        shell_cmds = ('vtysh', '"conf t"', '"{}"'.format(cmd))
        quagga_cmd = ' -c '.join(shell_cmds)
        return cord_test_quagga_shell(quagga_cmd)

    def test_vrouter_ipv6_with_5_routes(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_5_routes_quagga_restart_without_config(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info('Restart Quagga container without config retain')
        cord_test_quagga_restart()
        self.vrouter_traffic_verify(positive_test=False)

    def test_vrouter_ipv6_with_5_routes_quagga_restart_with_config(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info(
            'verifying vrouter traffic after Quagga restart with config retain'
        )
        #cord_test_quagga_restart()
        self.start_quagga(networks=5)
        self.vrouter_traffic_verify(positive_test=True)

    def test_vrouter_ipv6_with_5_routes_quagga_stop(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info('verifying vrouter traffic after Quagga stop')
        cord_test_quagga_stop()
        self.vrouter_traffic_verify(positive_test=False)

    def test_vrouter_ipv6_with_5_routes_quagga_stop_and_start(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info(
            'verifying vrouter traffic after Quagga stop and start again')
        cord_test_quagga_stop()
        self.vrouter_traffic_verify(positive_test=False)
        self.start_quagga(networks=5)
        self.vrouter_traffic_verify(positive_test=True)

    def test_vrouter_ipv6_with_5_routes_onos_restart_without_config(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info(
            'verifying vrouter traffic after ONOS restart without config retain'
        )
        cord_test_onos_restart()
        self.vrouter_traffic_verify(positive_test=False)

    def test_vrouter_ipv6_with_5_routes_onos_restart_with_config(self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info(
            'verifying vrouter traffic after ONOS restart with config retain')
        vrouter_configs = self.vrouter_config_get(networks=5,
                                                  peers=1,
                                                  peer_address=None,
                                                  route_update=None)
        self.start_onos(network_cfg=vrouter_configs)
        mac = RandMAC()._fix()
        hostcfg = self.generate_host_config(hosts_list=[('2001:0:0:0:0:0:10:1',
                                                         mac)])
        self.host_config_load(host_config=hostcfg)
        time.sleep(10)
        self.vrouter_traffic_verify(positive_test=True)

    def test_vrouter_ipv6_with_5_routes_restart_quagga_and_onos_with_config(
            self):
        res = self.__vrouter_network_verify(5, peers=1)
        assert_equal(res, True)
        log_test.info(
            'verifying vrouter traffic after Quagga and ONOS restart with config retain'
        )
        #cord_test_quagga_restart()
        self.start_quagga(networks=5)
        vrouter_configs = self.vrouter_config_get(networks=5,
                                                  peers=1,
                                                  peer_address=None,
                                                  route_update=None)
        self.start_onos(network_cfg=vrouter_configs)
        mac = RandMAC()._fix()
        hostcfg = self.generate_host_config(hosts_list=[('2001:0:0:0:0:0:10:1',
                                                         mac)])
        self.host_config_load(host_config=hostcfg)
        time.sleep(10)
        self.vrouter_traffic_verify(positive_test=True)

    def test_vrouter_ipv6_with_5_routes_2_peers(self):
        res = self.__vrouter_network_verify(5, peers=2)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_6_routes_3_peers(self):
        res = self.__vrouter_network_verify(6, peers=3)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_50_routes(self):
        res = self.__vrouter_network_verify(50, peers=1)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_50_routes_5_peers(self):
        res = self.__vrouter_network_verify(50, peers=5)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_100_routes(self):
        res = self.__vrouter_network_verify(100, peers=1)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_100_routes_10_peers(self):
        res = self.__vrouter_network_verify(100, peers=10)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_300_routes(self):
        res = self.__vrouter_network_verify(300, peers=1)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_1k_routes(self):
        res = self.__vrouter_network_verify(1000, peers=1)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_9k_routes(self):
        res = self.__vrouter_network_verify(9000, peers=1)
        assert_equal(res, True)

    @nottest  # Need to implement logic for generating more than 10000 routes
    def test_vrouter_ipv6_with_100000_routes(self):
        res = self.__vrouter_network_verify(100000, peers=1)
        assert_equal(res, True)

    @nottest  # Need to implement logic for generating more than 10000 routes
    def test_vrouter_ipv6_with_1000000_routes(self):
        res = self.__vrouter_network_verify(1000000, peers=1)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_route_update(self):
        res = self.__vrouter_network_verify(5, peers=2, positive_test=True)
        assert_equal(res, True)
        peer_info = [('2001:0:0:0:0:0:72:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:73:1', '00:00:00:00:02:01')]
        res = self.__vrouter_network_verify(5,
                                            peers=2,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            route_update=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_64bit_mask_route_update(self):
        router_address = '3001:0:0:0:0:0:56:0/64'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_network=router_address)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_32bit_route_update(self):
        router_address = '3112:90c4:836a:7e56:0:0:06:0/32'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_network=router_address)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_16bit_route_update(self):
        router_address = '9961:9474:0:8472:f30a:0:06:0/16'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_network=router_address)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_48bit_route_update(self):
        router_address = 'c34a:9737:14cd:8730:0:0:06:0/48'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_network=router_address)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_classless_route_update(self):
        router_address = '3001:430d:76cb:f56e:873:0:677:0/67'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_network=router_address)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_classless_duplicate_route_update(self):
        router_address = '3001:8730:732:723:0:0:677:0/116'
        res = self.__vrouter_network_verify(5,
                                            peers=1,
                                            positive_test=True,
                                            start_network=router_address)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_invalid_peers(self):
        peer_info = [('FE80:0:0:0:C800:27FF:10:8', '00:00:00:00:01:01'),
                     ('FE80:0:0:0:C800:27FF:11:8', '00:00:00:00:02:01')]
        res = self.__vrouter_network_verify(5,
                                            peers=2,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            specific_peer=True,
                                            invalid_peers=True)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_traffic_sent_between_peers_connected_to_onos(self):
        res = self.__vrouter_network_verify(5,
                                            peers=2,
                                            positive_test=True,
                                            traffic_running_between_peers=True)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_routes_time_expire(self):
        res = self.__vrouter_network_verify(5,
                                            peers=2,
                                            positive_test=True,
                                            time_expire=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_unreachable_route(self):
        res = self.__vrouter_network_verify(5,
                                            peers=2,
                                            positive_test=True,
                                            unreachable_route_traffic=True)
        assert_equal(res, True)

    @nottest
    def test_vrouter_ipv6_with_enabling_disabling_vrouter_app(self):
        res = self.__vrouter_network_verify(5,
                                            peers=2,
                                            positive_test=True,
                                            deactivate_activate_vrouter=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_adding_new_routes_in_routing_table(self):
        res = self.__vrouter_network_verify(5, peers=2, positive_test=True)
        cmd = 'ipv6 route 4001:0:0:0:0:0:677:0/64 2001:0:0:0:0:0:10:1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify()
        self.network_list = ['4001:0:0:0:0:0:677:0']
        self.network_mask = 64
        self.vrouter_traffic_verify()
        assert_equal(res, True)

    def test_vrouter_ipv6_with_adding_new_routes_in_quagga_routing_table_and_restart(
            self):
        res = self.__vrouter_network_verify(5, peers=2, positive_test=True)
        cmd = 'ipv6 route 4001:0:0:0:0:0:677:0/64 2001:0:0:0:0:0:10:1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify()
        self.network_list = ['4001:0:0:0:0:0:677:0']
        self.network_mask = 64
        self.vrouter_traffic_verify()
        log_test.info(
            'verifying vrouter traffic for added  routes after Quagga restart with old config only retain'
        )
        #cord_test_quagga_restart()
        self.start_quagga(networks=5)
        self.vrouter_traffic_verify(positive_test=False)
        assert_equal(res, True)

    def test_vrouter_ipv6_with_removing_old_routes_in_routing_table(self):
        res = self.__vrouter_network_verify(5, peers=2, positive_test=True)
        cmd = 'ipv6 route 4001:0:0:0:0:0:677:0/64 2001:0:0:0:0:0:10:1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify()
        old_network_list = self.network_list
        old_network_mask = self.network_mask
        self.network_list = ['4001:0:0:0:0:0:677:0']
        self.network_mask = 64
        self.vrouter_traffic_verify()
        assert_equal(res, True)
        cmd = 'no ipv6 route 4001:0:0:0:0:0:677:0/64 2001:0:0:0:0:0:10:1'
        self.quagga_shell(cmd)
        time.sleep(5)
        self.vrouter_traffic_verify(positive_test=False)
        self.network_mask = old_network_mask
        self.network_list = old_network_list
        self.vrouter_traffic_verify(positive_test=True)

    def test_vrouter_ipv6_modifying_nexthop_route_in_routing_table(self):
        peer_info = [('2001:0:0:0:0:0:12:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:13:1', '00:00:00:00:02:01')]
        router_address = '3001:0:0:0:0:0:677:0/112'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            start_network=router_address)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:677:0/112 2001:0:0:0:0:0:18:1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify(positive_test=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_deleting_alternative_nexthop_in_routing_table(self):
        peer_info = [('2001:0:0:0:0:0:12:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:13:1', '00:00:00:00:02:01')]
        router_address = '3001:0:0:0:0:0:677:0/112'
        res = self.__vrouter_network_verify(1,
                                            peers=2,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            start_network=router_address)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:677:0/112 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        time.sleep(5)
        self.vrouter_traffic_verify(positive_test=False)
        assert_equal(res, True)

    def test_vrouter_ipv6_deleting_some_routes_in_routing_table(self):
        peer_info = [('2001:0:0:0:0:0:12:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:13:1', '00:00:00:00:02:01')]
        router_address = '3001:0:0:0:0:0:677:0/112'
        res = self.__vrouter_network_verify(10,
                                            peers=2,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            start_network=router_address)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:677:0/112 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:678:0/112 2001:0:0:0:0:0:13:1'
        self.quagga_shell(cmd)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:679:0/112 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify(positive_test=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_deleting_some_routes_in_quagga_routing_table_and_restart(
            self):
        peer_info = [('2001:0:0:0:0:0:12:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:13:1', '00:00:00:00:02:01')]
        router_address = '3001:0:0:0:0:0:677:0/112'
        res = self.__vrouter_network_verify(10,
                                            peers=2,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            start_network=router_address)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:677:0/112 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:678:0/112 2001:0:0:0:0:0:13:1'
        self.quagga_shell(cmd)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:679:0/112 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        self.network_list = [
            '3001:0:0:0:0:0:677:0', '3001:0:0:0:0:0:678:0',
            '3001:0:0:0:0:0:679:0'
        ]
        self.network_mask = 112
        self.vrouter_traffic_verify(positive_test=False)
        self.network_list = ['3001:0:0:0:0:0:680:0', '3001:0:0:0:0:0:681:0']
        self.vrouter_traffic_verify(positive_test=True)
        #cord_test_quagga_restart()
        self.start_quagga(networks=10)
        self.network_list = ['3001:0:0:0:0:0:677:0', '3001:0:0:0:0:0:681:0']
        self.vrouter_traffic_verify(positive_test=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_deleting_and_adding_routes_in_routing_table(self):
        peer_info = [('2001:0:0:0:0:0:12:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:13:1', '00:00:00:00:02:01')]
        router_address = '3001:0:0:0:0:0:677:0/64'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            start_network=router_address)
        cmd = 'no ipv6 route 3001:0:0:0:0:0:677:0/64 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        cmd = 'ipv6 route 3001:0:0:0:0:0:677:0/64 2001:0:0:0:0:0:12:1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify(positive_test=True)
        assert_equal(res, True)

    def test_vrouter_ipv6_toggling_nexthop_interface(self):
        peer_info = [('2001:0:0:0:0:0:12:1', '00:00:00:00:01:01'),
                     ('2001:0:0:0:0:0:13:1', '00:00:00:00:02:01')]
        router_address = '3001:0:0:0:0:0:677:0/64'
        res = self.__vrouter_network_verify(1,
                                            peers=1,
                                            positive_test=True,
                                            start_peer_address=peer_info,
                                            start_network=router_address)
        iface = self.port_map[1]
        #toggle the interface to trigger host removal.
        cmds = (
            'ifconfig {} down'.format(iface),
            'sleep 2',
            'ifconfig {} 0'.format(iface),
        )
        for cmd in cmds:
            os.system(cmd)
        self.vrouter_traffic_verify(positive_test=False)
        host = "2001:0:0:0:0:0:12:1"
        cmd = 'ifconfig {0} {1} up'.format(iface, host)
        os.system(cmd)
        #wait for arp refresh
        time.sleep(60)
        self.vrouter_traffic_verify(positive_test=True)
        assert_equal(res, True)
Esempio n. 6
0
class vrouter_exchange(CordLogger):

    apps = ('org.onosproject.proxyarp', 'org.onosproject.hostprovider', 'org.onosproject.vrouter', 'org.onosproject.fwd')
    device_id = 'of:' + get_mac()
    vrouter_device_dict = { "devices" : {
                "{}".format(device_id) : {
                    "basic" : {
                        "driver" : "softrouter"
                    }
                }
             },
          }
    zebra_conf = '''
password zebra
log stdout
service advanced-vty
!
!debug zebra rib
!debug zebra kernel
!debug zebra fpm
!
!interface eth1
! ip address 10.10.0.3/16
line vty
 exec-timeout 0 0
'''
    test_path = os.path.dirname(os.path.realpath(__file__))
    quagga_config_path = os.path.join(test_path, '..', 'setup/quagga-config')
    onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
    GATEWAY = '192.168.10.50'
    INGRESS_PORT = 1
    EGRESS_PORT = 2
    MAX_PORTS = 100
    peer_list = [ ('192.168.10.1', '00:00:00:00:00:01'), ('192.168.11.1', '00:00:00:00:02:01'), ]
    network_list = []
    network_mask = 24
    default_routes_address = ('11.10.10.0/24',)
    default_peer_address = peer_list
    quagga_ip = os.getenv('QUAGGA_IP')

    @classmethod
    def setUpClass(cls):
        ''' Activate the vrouter apps'''
        cls.olt = OltConfig()
        cls.port_map, _ = cls.olt.olt_port_map()
        if not cls.port_map:
            cls.port_map = g_subscriber_port_map
        time.sleep(3)
        cls.load_device_id()

    @classmethod
    def tearDownClass(cls):
        '''Deactivate the vrouter apps'''
        #cls.vrouter_host_unload()
        cls.start_onos(network_cfg = {})

    @classmethod
    def load_device_id(cls):
        did = OnosCtrl.get_device_id()
        cls.device_id = did
        cls.vrouter_device_dict = { "devices" : {
                "{}".format(did) : {
                    "basic" : {
                        "driver" : "softrouter"
                    }
                }
            },
        }

    @classmethod
    def activate_apps(cls, deactivate = False):
        for app in cls.apps:
            onos_ctrl = OnosCtrl(app)
            if deactivate is False:
                onos_ctrl.activate()
            else:
                onos_ctrl.deactivate()
            time.sleep(2)

    def cliEnter(self):
        retries = 0
        while retries < 3:
            self.cli = OnosCliDriver(connect = True)
            if self.cli.handle:
                break
            else:
                retries += 1
                time.sleep(2)

    def cliExit(self):
        self.cli.disconnect()

    @classmethod
    def onos_load_config(cls, config):
        status, code = OnosCtrl.config(config)
        if status is False:
            log_test.info('JSON request returned status %d' %code)
            assert_equal(status, True)

    @classmethod
    def vrouter_config_get(cls, networks = 4, peers = 1, peer_address = None,
                           route_update = None, router_address = None):
        vrouter_configs = cls.generate_vrouter_conf(networks = networks, peers = peers,
                                                    peer_address = peer_address, router_address = router_address)
        return vrouter_configs
        ##ONOS router does not support dynamic reconfigurations
        #for config in vrouter_configs:
        #    cls.onos_load_config(config)
        #    time.sleep(5)

    @classmethod
    def vrouter_host_load(cls, peer_address = None):
        index = 1
        peer_info = peer_address if peer_address is not None else cls.peer_list

        for host,_ in peer_info:
            iface = cls.port_map[index]
            index += 1
            log_test.info('Assigning ip %s to interface %s' %(host, iface))
            config_cmds = ( 'ifconfig {} 0'.format(iface),
                            'ifconfig {0} {1}'.format(iface, host),
                            'arping -I {0} {1} -c 2'.format(iface, host),
                            )
            for cmd in config_cmds:
                os.system(cmd)

    @classmethod
    def vrouter_host_unload(cls, peer_address = None):
        index = 1
        peer_info = peer_address if peer_address is not None else cls.peer_list

        for host,_ in peer_info:
            iface = cls.port_map[index]
            index += 1
            config_cmds = ('ifconfig {} 0'.format(iface), )
            for cmd in config_cmds:
                os.system(cmd)

    @classmethod
    def start_onos(cls, network_cfg = None):
        if type(network_cfg) is tuple:
            res = []
            for v in network_cfg:
                res += v.items()
            config = dict(res)
        else:
            config = network_cfg
        log_test.info('Restarting ONOS with new network configuration')
        return cord_test_onos_restart(config = config)

    @classmethod
    def start_quagga(cls, networks = 4, peer_address = None, router_address = None):
        log_test.info('Restarting Quagga container with configuration for %d networks' %(networks))
        config = cls.generate_conf(networks = networks, peer_address = peer_address, router_address = router_address)
        if networks <= 10000:
            boot_delay = 25
        else:
            delay_map = [60, 100, 150, 200, 300, 450, 600, 800, 1000, 1200]
            n = min(networks/100000, len(delay_map)-1)
            boot_delay = delay_map[n]
        cord_test_quagga_restart(config = config, boot_delay = boot_delay)

    @classmethod
    def generate_vrouter_conf(cls, networks = 4, peers = 1, peer_address = None, router_address = None):
        num = 0
        if peer_address is None:
           start_peer = ( 192 << 24) | ( 168 << 16)  |  (10 << 8) | 0
           end_peer =   ( 200 << 24 ) | (168 << 16)  |  (10 << 8) | 0
        else:
           ip = peer_address[0][0]
           start_ip = ip.split('.')
           start_peer = ( int(start_ip[0]) << 24) | ( int(start_ip[1]) << 16)  |  ( int(start_ip[2]) << 8) | 0
           end_peer =   ((int(start_ip[0]) + 8) << 24 ) | (int(start_ip[1]) << 16)  |  (int(start_ip[2]) << 8) | 0
        local_network = end_peer + 1
        ports_dict = { 'ports' : {} }
        interface_list = []
        peer_list = []
        for n in xrange(start_peer, end_peer, 256):
            port_map = ports_dict['ports']
            port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
            device_port_key = '{0}/{1}'.format(cls.device_id, port)
            try:
                interfaces = port_map[device_port_key]['interfaces']
            except:
                port_map[device_port_key] = { 'interfaces' : [] }
                interfaces = port_map[device_port_key]['interfaces']
            ip = n + 2
            peer_ip = n + 1
            ips = '%d.%d.%d.%d/24'%( (ip >> 24) & 0xff, ( (ip >> 16) & 0xff ), ( (ip >> 8 ) & 0xff ), ip & 0xff)
            peer = '%d.%d.%d.%d' % ( (peer_ip >> 24) & 0xff, ( ( peer_ip >> 16) & 0xff ), ( (peer_ip >> 8 ) & 0xff ), peer_ip & 0xff )
            mac = RandMAC()._fix()
            peer_list.append((peer, mac))
            if num < cls.MAX_PORTS - 1:
                interface_dict = { 'name' : 'b1-{}'.format(port), 'ips': [ips], 'mac' : mac }
                interfaces.append(interface_dict)
                interface_list.append(interface_dict['name'])
            else:
                interfaces[0]['ips'].append(ips)
            num += 1
            if num == peers:
                break
        quagga_dict = { 'apps': { 'org.onosproject.router' : { 'router' : {}, 'bgp' : { 'bgpSpeakers' : [] } } } }
        quagga_router_dict = quagga_dict['apps']['org.onosproject.router']['router']
        quagga_router_dict['ospfEnabled'] = True
        quagga_router_dict['interfaces'] = interface_list
        quagga_router_dict['controlPlaneConnectPoint'] = '{0}/{1}'.format(cls.device_id, peers + 1)

        #bgp_speaker_dict = { 'apps': { 'org.onosproject.router' : { 'bgp' : { 'bgpSpeakers' : [] } } } }
        bgp_speakers_list = quagga_dict['apps']['org.onosproject.router']['bgp']['bgpSpeakers']
        speaker_dict = {}
        speaker_dict['name'] = 'bgp{}'.format(peers+1)
        speaker_dict['connectPoint'] = '{0}/{1}'.format(cls.device_id, peers + 1)
        speaker_dict['peers'] = peer_list
        bgp_speakers_list.append(speaker_dict)
        cls.peer_list = peer_list
        return (cls.vrouter_device_dict, ports_dict, quagga_dict)

    @classmethod
    def generate_conf(cls, networks = 4, peer_address = None, router_address = None):
        num = 0
        if router_address is None:
            start_network = ( 11 << 24) | ( 10 << 16) | ( 10 << 8) | 0
            end_network =   ( 172 << 24 ) | ( 0 << 16)  | (0 << 8) | 0
            network_mask = 24
        else:
           ip = router_address
           start_ip = ip.split('.')
           network_mask = int(start_ip[3].split('/')[1])
           start_ip[3] = (start_ip[3].split('/'))[0]
           start_network = (int(start_ip[0]) << 24) | ( int(start_ip[1]) << 16)  |  ( int(start_ip[2]) << 8) | 0
           end_network = (172 << 24 ) | (int(start_ip[1]) << 16)  |  (int(start_ip[2]) << 8) | 0
        net_list = []
        peer_list = peer_address if peer_address is not None else cls.peer_list
        network_list = []
        for n in xrange(start_network, end_network, 256):
            net = '%d.%d.%d.0'%( (n >> 24) & 0xff, ( ( n >> 16) & 0xff ), ( (n >> 8 ) & 0xff ) )
            network_list.append(net)
            gateway = peer_list[num % len(peer_list)][0]
            net_route = 'ip route {0}/{1} {2}'.format(net, network_mask, gateway)
            net_list.append(net_route)
            num += 1
            if num == networks:
                break
        cls.network_list = network_list
        cls.network_mask = network_mask
        zebra_routes = '\n'.join(net_list)
        #log_test.info('Zebra routes: \n:%s\n' %cls.zebra_conf + zebra_routes)
        return cls.zebra_conf + zebra_routes

    @classmethod
    def vrouter_activate(cls, deactivate = False):
        app = 'org.onosproject.vrouter'
        onos_ctrl = OnosCtrl(app)
        if deactivate is True:
            onos_ctrl.deactivate()
        else:
            onos_ctrl.activate()
        time.sleep(3)

    @classmethod
    def vrouter_configure(cls, networks = 4, peers = 1, peer_address = None,
                          route_update = None, router_address = None, time_expire = None, adding_new_routes = None):
        vrouter_configs = cls.vrouter_config_get(networks = networks, peers = peers,
                                                 peer_address = peer_address, route_update = route_update)
        cls.start_onos(network_cfg = vrouter_configs)
        cls.activate_apps()
        time.sleep(5)
        cls.vrouter_host_load()
        ##Start quagga
        cls.start_quagga(networks = networks, peer_address = peer_address, router_address = router_address)
        return vrouter_configs

    def vrouter_port_send_recv(self, ingress, egress, dst_mac, dst_ip, positive_test = True):
        src_mac = '00:00:00:00:00:02'
        src_ip = '1.1.1.1'
        self.success = False if positive_test else True
        timeout = 10 if positive_test else 1
        count = 2 if positive_test else 1
        self.start_sending = True
        def recv_task():
            def recv_cb(pkt):
                log_test.info('Pkt seen with ingress ip %s, egress ip %s' %(pkt[IP].src, pkt[IP].dst))
                self.success = True if positive_test else False
            sniff(count=count, timeout=timeout,
                  lfilter = lambda p: IP in p and p[IP].dst == dst_ip and p[IP].src == src_ip,
                  prn = recv_cb, iface = self.port_map[ingress])
            self.start_sending = False

        t = threading.Thread(target = recv_task)
        t.start()
        L2 = Ether(src = src_mac, dst = dst_mac)
        L3 = IP(src = src_ip, dst = dst_ip)
        pkt = L2/L3
        log_test.info('Sending a packet with dst ip %s, dst mac %s on port %s to verify if flows are correct' %
                 (dst_ip, dst_mac, self.port_map[egress]))
        while self.start_sending is True:
            sendp(pkt, count=50, iface = self.port_map[egress])
        t.join()
        assert_equal(self.success, True)

    def vrouter_traffic_verify(self, positive_test = True, peer_address = None):
        if peer_address is None:
            peers = len(self.peer_list)
            peer_list = self.peer_list
        else:
            peers = len(peer_address)
            peer_list = peer_address
        egress = peers + 1
        num = 0
        num_hosts = 5 if positive_test else 1
        src_mac = '00:00:00:00:00:02'
        src_ip = '1.1.1.1'
        if self.network_mask != 24:
            peers = 1
        for network in self.network_list:
            num_ips = num_hosts
            octets = network.split('.')
            for i in xrange(num_ips):
                octets[-1] = str(int(octets[-1]) + 1)
                dst_ip = '.'.join(octets)
                dst_mac = peer_list[ num % peers ] [1]
                port = (num % peers)
                ingress = port + 1
                #Since peers are on the same network
                ##Verify if flows are setup by sending traffic across
                self.vrouter_port_send_recv(ingress, egress, dst_mac, dst_ip, positive_test = positive_test)
            num += 1

    def __vrouter_network_verify(self, networks, peers = 1, positive_test = True,
                                 start_network = None, start_peer_address = None, route_update = None,
                                 invalid_peers = None, time_expire = None, unreachable_route_traffic = None,
                                 deactivate_activate_vrouter = None, adding_new_routes = None):

        _, ports_map, egress_map = self.vrouter_configure(networks = networks, peers = peers,
                                                          peer_address = start_peer_address,
                                                          route_update = route_update,
                                                          router_address = start_network,
                                                          time_expire = time_expire,
                                                          adding_new_routes = adding_new_routes)
        self.cliEnter()
        ##Now verify
        hosts = json.loads(self.cli.hosts(jsonFormat = True))
        log_test.info('Discovered hosts: %s' %hosts)
        ##We read from cli if we expect less number of routes to avoid cli timeouts
        if networks <= 10000:
            routes = json.loads(self.cli.routes(jsonFormat = True))
            #log_test.info('Routes: %s' %routes)
            if start_network is not None:
               if start_network.split('/')[1] is 24:
                  assert_equal(len(routes['routes4']), networks)
               if start_network.split('/')[1] is not 24:
                  assert_equal(len(routes['routes4']), 1)
            if start_network is None and invalid_peers is None:
               assert_equal(len(routes['routes4']), networks)
            if invalid_peers is not None:
               assert_equal(len(routes['routes4']), 0)
            flows = json.loads(self.cli.flows(jsonFormat = True))
            flows = filter(lambda f: f['flows'], flows)
            #log_test.info('Flows: %s' %flows)
            assert_not_equal(len(flows), 0)
        if invalid_peers is None:
            self.vrouter_traffic_verify()
        if positive_test is False:
            self.__vrouter_network_verify_negative(networks, peers = peers)
        if time_expire is True:
            self.start_quagga(networks = networks, peer_address = start_peer_address, router_address = '12.10.10.1/24')
            self.vrouter_traffic_verify()
        if unreachable_route_traffic is True:
            network_list_backup = self.network_list
            self.network_list = ['2.2.2.2','3.3.3.3','4.4.4.4','5.5.5.5']
            self.vrouter_traffic_verify(positive_test = False)
            self.network_list = network_list_backup
        if deactivate_activate_vrouter is True:
            log_test.info('Deactivating vrouter app in ONOS controller for negative scenario')
            self.vrouter_activate(deactivate = True)
            #routes = json.loads(self.cli.routes(jsonFormat = False, cmd_exist = False))
            #assert_equal(len(routes['routes4']), 'Command not found')
            log_test.info('Activating vrouter app again in ONOS controller for negative scenario')
            self.vrouter_activate(deactivate = False)
            routes = json.loads(self.cli.routes(jsonFormat = True))
            assert_equal(len(routes['routes4']), networks)
            self.vrouter_traffic_verify()
        self.cliExit()
        self.vrouter_host_unload()
        return True

    def __vrouter_network_verify_negative(self, networks, peers = 1):
        ##Stop quagga. Test traffic again to see if flows were removed
        log_test.info('Stopping Quagga container')
        cord_test_quagga_stop()
        if networks <= 10000:
            routes = json.loads(self.cli.routes(jsonFormat = True))
            #Verify routes have been removed
            if routes and routes.has_key('routes4'):
                assert_equal(len(routes['routes4']), 0)
        self.vrouter_traffic_verify(positive_test = False)
        log_test.info('OVS flows have been removed successfully after Quagga was stopped')
        self.start_quagga(networks = networks)
        ##Verify the flows again after restarting quagga back
        if networks <= 10000:
            routes = json.loads(self.cli.routes(jsonFormat = True))
            assert_equal(len(routes['routes4']), networks)
        self.vrouter_traffic_verify()
        log_test.info('OVS flows have been successfully reinstalled after Quagga was restarted')

    def quagga_shell(self, cmd):
        shell_cmds = ('vtysh', '"conf t"', '"{}"'.format(cmd))
        quagga_cmd = ' -c '.join(shell_cmds)
        return cord_test_quagga_shell(quagga_cmd)

    def test_vrouter_with_5_routes(self):
        res = self.__vrouter_network_verify(5, peers = 1)
        assert_equal(res, True)

    def test_vrouter_with_5_routes_2_peers(self):
        res = self.__vrouter_network_verify(5, peers = 2)
        assert_equal(res, True)

    def test_vrouter_with_6_routes_3_peers(self):
        res = self.__vrouter_network_verify(6, peers = 3)
        assert_equal(res, True)

    def test_vrouter_with_50_routes(self):
        res = self.__vrouter_network_verify(50, peers = 1)
        assert_equal(res, True)

    def test_vrouter_with_50_routes_5_peers(self):
        res = self.__vrouter_network_verify(50, peers = 5)
        assert_equal(res, True)

    def test_vrouter_with_100_routes(self):
        res = self.__vrouter_network_verify(100, peers = 1)
        assert_equal(res, True)

    def test_vrouter_with_100_routes_10_peers(self):
        res = self.__vrouter_network_verify(100, peers = 10)
        assert_equal(res, True)

    def test_vrouter_with_300_routes(self):
        res = self.__vrouter_network_verify(300, peers = 1)
        assert_equal(res, True)

    def test_vrouter_with_1000_routes(self):
        res = self.__vrouter_network_verify(1000, peers = 1)
        assert_equal(res, True)

    def test_vrouter_with_10000_routes(self):
        res = self.__vrouter_network_verify(10000, peers = 1)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_100000_routes(self):
        res = self.__vrouter_network_verify(100000, peers = 1)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_1000000_routes(self):
        res = self.__vrouter_network_verify(1000000, peers = 1)
        assert_equal(res, True)

    def test_vrouter_with_5_routes_stopping_quagga(self):
        res = self.__vrouter_network_verify(5, peers = 1, positive_test = False)

    def test_vrouter_with_50_routes_stopping_quagga(self):
        res = self.__vrouter_network_verify(50, peers = 1, positive_test = False)

    def test_vrouter_with_route_update(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True)
        assert_equal(res, True)
        peer_info = [('192.168.20.1', '00:00:00:00:01:01'), ('192.168.21.1', '00:00:00:00:02:01')]
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True,
                                            start_peer_address = peer_info, route_update = True)
        assert_equal(res, True)

    def test_vrouter_with_classA_route_update(self):
        router_address = '11.10.10.0/8'
        res = self.__vrouter_network_verify(1, peers = 1, positive_test = True, start_network = router_address)
        assert_equal(res, True)

    def test_vrouter_with_classB_route_update(self):
        router_address = '11.10.10.0/16'
        res = self.__vrouter_network_verify(1, peers = 1, positive_test = True, start_network = router_address)
        assert_equal(res, True)

    def test_vrouter_with_classless_route_update(self):
        router_address = '11.10.10.0/12'
        res = self.__vrouter_network_verify(1, peers = 1, positive_test = True, start_network = router_address)
        assert_equal(res, True)

    def test_vrouter_with_classA_duplicate_route_update(self):
        router_address = '11.10.10.0/8'
        res = self.__vrouter_network_verify(5, peers = 1, positive_test = True, start_network = router_address)
        assert_equal(res, True)

    def test_vrouter_with_classB_duplicate_route_update(self):
        router_address = '11.10.10.0/16'
        res = self.__vrouter_network_verify(5, peers = 1, positive_test = True, start_network = router_address)
        assert_equal(res, True)

    def test_vrouter_with_classless_duplicate_route_update(self):
        router_address = '11.10.10.0/12'
        res = self.__vrouter_network_verify(5, peers = 1, positive_test = True, start_network = router_address)
        assert_equal(res, True)

    def test_vrouter_with_invalid_peers(self):
        peer_info = [('239.255.255.250', '00:00:00:00:01:01'), ('239.255.255.240', '00:00:00:00:02:01')]
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True,
                                            start_peer_address = peer_info, invalid_peers= True)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_traffic_sent_between_peers_connected_to_onos(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True, traffic_running_between_peers = True)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_routes_time_expire(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True, time_expire = True)
        assert_equal(res, True)

    def test_vrouter_with_unreachable_route(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True, unreachable_route_traffic = True)
        assert_equal(res, True)

    @nottest
    def test_vrouter_with_enabling_disabling_vrouter_app(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True, deactivate_activate_vrouter = True)
        assert_equal(res, True)

    def test_vrouter_with_adding_new_routes_in_routing_table(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True)
        cmd = 'ip route 21.10.20.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify()
        self.network_list = [ '21.10.20.0' ]
        self.network_mask = 24
        self.vrouter_traffic_verify()
        assert_equal(res, True)

    def test_vrouter_with_removing_old_routes_in_routing_table(self):
        res = self.__vrouter_network_verify(5, peers = 2, positive_test = True)
        cmd = 'ip route 21.10.20.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify()
        old_network_list = self.network_list
        old_network_mask = self.network_mask
        self.network_list = [ '21.10.20.0' ]
        self.network_mask = 24
        self.vrouter_traffic_verify()
        assert_equal(res, True)
        cmd = 'no ip route 21.10.20.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        time.sleep(5)
        self.vrouter_traffic_verify(positive_test = False)
        self.network_mask = old_network_mask
        self.network_list = old_network_list
        self.vrouter_traffic_verify(positive_test = True)

    def test_vrouter_modifying_nexthop_route_in_routing_table(self):
        peer_info = [('192.168.10.1', '00:00:00:00:01:01'), ('192.168.11.1', '00:00:00:00:02:01')]
        router_address = '11.10.10.0/24'
        res = self.__vrouter_network_verify(1, peers = 1, positive_test = True,
                                            start_peer_address = peer_info, start_network  = router_address)
        cmd = 'ip route 11.10.10.0/24 192.168.20.1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify(positive_test = True)
        assert_equal(res, True)


    def test_vrouter_deleting_alternative_nexthop_in_routing_table(self):
        peer_info = [('192.168.10.1', '00:00:00:00:01:01'), ('192.168.11.1', '00:00:00:00:02:01')]
        router_address = '11.10.10.0/24'
        res = self.__vrouter_network_verify(1, peers = 2, positive_test = True,
                                            start_peer_address = peer_info, start_network  = router_address)
        cmd = 'no ip route 11.10.10.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        time.sleep(5)
        self.vrouter_traffic_verify(positive_test = False)
        assert_equal(res, True)

    def test_vrouter_deleting_some_routes_in_routing_table(self):
        peer_info = [('192.168.10.1', '00:00:00:00:01:01'), ('192.168.11.1', '00:00:00:00:02:01')]
        router_address = '11.10.10.0/24'
        res = self.__vrouter_network_verify(10, peers = 2, positive_test = True,
                                            start_peer_address = peer_info, start_network  = router_address)
        cmd = 'no ip route 11.10.10.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        cmd = 'no ip route 11.10.13.0/24 192.168.11.1'
        self.quagga_shell(cmd)
        cmd = 'no ip route 11.10.14.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify(positive_test = True)
        assert_equal(res, True)


    def test_vrouter_deleting_and_adding_routes_in_routing_table(self):
        peer_info = [('192.168.10.1', '00:00:00:00:01:01'), ('192.168.11.1', '00:00:00:00:02:01')]
        router_address = '11.10.10.0/24'
        res = self.__vrouter_network_verify(1, peers = 1, positive_test = True, start_peer_address = peer_info, start_network  = router_address)
        cmd = 'no ip route 11.10.10.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        cmd = 'ip route 11.10.10.0/24 192.168.10.1'
        self.quagga_shell(cmd)
        self.vrouter_traffic_verify(positive_test = True)
        assert_equal(res, True)

    def test_vrouter_toggling_nexthop_interface(self):
        peer_info = [('192.168.10.1', '00:00:00:00:01:01'), ('192.168.11.1', '00:00:00:00:02:01')]
        router_address = '11.10.10.0/24'
        res = self.__vrouter_network_verify(1, peers = 1, positive_test = True, start_peer_address = peer_info, start_network  = router_address)
        iface = self.port_map[1]
        #toggle the interface to trigger host removal.
        cmds = ('ifconfig {} down'.format(iface),
                'sleep 2',
                'ifconfig {} 0'.format(iface),)
        for cmd in cmds:
            os.system(cmd)
        self.vrouter_traffic_verify(positive_test = False)
        host = "192.168.10.1"
        cmd = 'ifconfig {0} {1} up'.format(iface, host)
        os.system(cmd)
        #wait for arp refresh
        time.sleep(60)
        self.vrouter_traffic_verify(positive_test = True)
        assert_equal(res, True)

    def vrouter_scale(self, num_routes, peers = 1):
        '''Called from scale test'''
        return self.__vrouter_network_verify(num_routes, peers = peers)