Exemple #1
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65001, router_id='192.168.0.2')
        q2 = QuaggaBGPContainer(name='q2', asn=65002, router_id='192.168.0.3')
        q3 = QuaggaBGPContainer(name='q3', asn=65003, router_id='192.168.0.4')

        qs = [q1, q2, q3]
        ctns = [g1, q1, q2, q3]

        initial_wait_time = max(ctn.run() for ctn in ctns)
        time.sleep(initial_wait_time)

        for q in qs:
            g1.add_peer(q, passwd='passwd')
            q.add_peer(g1, passwd='passwd', passive=True)

        # advertise a route from q1, q2, q3
        for idx, q in enumerate(qs):
            route = '10.0.{0}.0/24'.format(idx + 1)
            q.add_route(route)

        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3}
Exemple #2
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65000, router_id='192.168.0.2')
        q2 = QuaggaBGPContainer(name='q2', asn=65000, router_id='192.168.0.3')

        qs = [q1, q2]
        ctns = [g1, q1, q2]

        initial_wait_time = max(ctn.run() for ctn in ctns)
        time.sleep(initial_wait_time)

        # ibgp peer. loop topology
        for a, b in combinations(ctns, 2):
            a.add_peer(b)
            b.add_peer(a)

        # advertise a route from q1, q2
        for idx, c in enumerate(qs):
            route = '10.0.{0}.0/24'.format(idx + 1)
            c.add_route(route)

        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2}
Exemple #3
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1', asn=65001, router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65002, router_id='192.168.0.2')
        g2 = GoBGPContainer(name='g2', asn=65001, router_id='192.168.0.3',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        ctns = [g1, g2, q1]

        initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(initial_wait_time)

        g1.add_peer(q1)
        q1.add_peer(g1)

        q1.add_peer(g2)
        g2.add_peer(q1)

        g1.add_route('10.0.0.0/24')

        cls.g1 = g1
        cls.g2 = g2
        cls.q1 = q1
        cls.ctns = {n.name: n for n in ctns}
    def test_15_add_ebgp_peer(self):
        q4 = QuaggaBGPContainer(name='q4', asn=65001, router_id='192.168.0.5')
        self.quaggas['q4'] = q4
        initial_wait_time = q4.run()
        time.sleep(initial_wait_time)

        self.gobgp.add_peer(q4)
        q4.add_peer(self.gobgp)

        prefix = '10.0.4.0/24'
        q4.add_route(prefix)

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q4)

        q1 = self.quaggas['q1']
        q2 = self.quaggas['q2']
        for q in [q1, q2]:

            def _f():
                return prefix in [
                    p['nlri']['prefix'] for p in self.gobgp.get_adj_rib_out(q)
                ]

            wait_for_completion(_f)

        def f():
            return len(q2.get_global_rib(prefix)) == 1

        wait_for_completion(f)
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1',
                            asn=65002,
                            router_id='192.168.0.2',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65003, router_id='192.168.0.3')
        q2 = QuaggaBGPContainer(name='q2', asn=65004, router_id='192.168.0.4')
        q3 = QuaggaBGPContainer(name='q3', asn=65005, router_id='192.168.0.5')
        q4 = QuaggaBGPContainer(name='q4', asn=65006, router_id='192.168.0.6')

        ctns = [g1, q1, q2, q3, q4]
        v4 = [q1, q2]
        v6 = [q3, q4]

        for idx, q in enumerate(v4):
            route = '10.0.{0}.0/24'.format(idx + 1)
            q.add_route(route)

        for idx, q in enumerate(v6):
            route = '2001:{0}::/96'.format(idx + 1)
            q.add_route(route, rf='ipv6')

        initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(initial_wait_time)

        for ctn in v4:
            g1.add_peer(ctn, is_rs_client=True)
            ctn.add_peer(g1)

        for ctn in v6:
            g1.add_peer(ctn, is_rs_client=True, v6=True)
            ctn.add_peer(g1, v6=True)

        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3, 'q4': q4}
        cls.ipv4s = {'q1': q1, 'q2': q2}
        cls.ipv6s = {'q3': q3, 'q4': q4}
Exemple #6
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1',
                            asn=65001,
                            router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65002, router_id='192.168.0.2')
        g2 = GoBGPContainer(name='g2',
                            asn=65001,
                            router_id='192.168.0.3',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        ctns = [g1, g2, q1]

        initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(initial_wait_time)

        g1.add_peer(q1)
        q1.add_peer(g1)

        q1.add_peer(g2)
        g2.add_peer(q1)

        g1.add_route('10.0.0.0/24')

        cls.g1 = g1
        cls.g2 = g2
        cls.q1 = q1
        cls.ctns = {n.name: n for n in ctns}
Exemple #7
0
    def test_07_add_ebgp_peer(self):
        q3 = QuaggaBGPContainer(name='q3', asn=65001, router_id='192.168.0.4')
        self.quaggas['q3'] = q3
        initial_wait_time = q3.run()
        time.sleep(initial_wait_time)

        self.gobgp.add_peer(q3)
        q3.add_peer(self.gobgp)

        q3.add_route('10.0.3.0/24')

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q3)
Exemple #8
0
    def test_05_add_quagga(self):
        q4 = QuaggaBGPContainer(name='q4', asn=65004, router_id='192.168.0.5')
        self.quaggas['q4'] = q4
        initial_wait_time = q4.run()
        time.sleep(initial_wait_time)

        self.gobgp.add_peer(q4)
        q4.add_peer(self.gobgp)

        q4.add_route('10.0.4.0/24')

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q4)
Exemple #9
0
    def test_09_add_distant_relative(self):
        q1 = self.quaggas['q1']
        q2 = self.quaggas['q2']
        q3 = self.quaggas['q3']
        q5 = QuaggaBGPContainer(name='q5', asn=65005, router_id='192.168.0.6')

        initial_wait_time = q5.run()
        time.sleep(initial_wait_time)

        for q in [q2, q3]:
            q5.add_peer(q)
            q.add_peer(q5)

        med200 = {
            'name': 'med200',
            'type': 'permit',
            'match': '0.0.0.0/0',
            'med': 200
        }
        q2.add_policy(med200, self.gobgp, 'out')
        med100 = {
            'name': 'med100',
            'type': 'permit',
            'match': '0.0.0.0/0',
            'med': 100
        }
        q3.add_policy(med100, self.gobgp, 'out')

        q5.add_route('10.0.6.0/24')

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q2)
        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q3)
        q2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)
        q3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)

        timeout = 120
        interval = 1
        count = 0
        while True:
            paths = self.gobgp.get_adj_rib_out(q1, '10.0.6.0/24')
            if len(paths) > 0:
                path = paths[0]
                print "{0}'s nexthop is {1}".format(path['nlri']['prefix'],
                                                    path['nexthop'])
                n_addrs = [i[1].split('/')[0] for i in self.gobgp.ip_addrs]
                if path['nexthop'] in n_addrs:
                    break

            time.sleep(interval)
            count += interval
            if count >= timeout:
                raise Exception('timeout')
Exemple #10
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        # preparing the container for ipv4
        g1_v4 = GoBGPContainer(name='g1_v4', asn=65000, router_id='192.168.0.1',
                               ctn_image_name=gobgp_ctn_image_name,
                               log_level=parser_option.gobgp_log_level,
                               zebra=True)
        q1_v4 = QuaggaBGPContainer(name='q1_v4', asn=65001, router_id='192.168.0.2', zebra=True)
        o1_v4 = QuaggaBGPContainer(name='o1_v4', asn=65002, router_id='192.168.0.3')
        o2_v4 = QuaggaBGPContainer(name='o2_v4', asn=65002, router_id='192.168.0.4')

        # preparing the container for ipv6
        g1_v6 = GoBGPContainer(name='g1_v6', asn=65000, router_id='192.168.0.1',
                               ctn_image_name=gobgp_ctn_image_name,
                               log_level=parser_option.gobgp_log_level,
                               zebra=True)
        q1_v6 = QuaggaBGPContainer(name='q1_v6', asn=65001, router_id='192.168.0.2', zebra=True)
        o1_v6 = QuaggaBGPContainer(name='o1_v6', asn=65002, router_id='192.168.0.3')
        o2_v6 = QuaggaBGPContainer(name='o2_v6', asn=65002, router_id='192.168.0.4')

        # preparing the bridge for ipv4
        br01_v4 = Bridge(name='br01_v4', subnet='192.168.10.0/24')
        br02_v4 = Bridge(name='br02_v4', subnet='192.168.20.0/24')
        br03_v4 = Bridge(name='br03_v4', subnet='192.168.30.0/24')

        # preparing the bridge for ipv6
        br01_v6 = Bridge(name='br01_v6', subnet='2001:10::/32')
        br02_v6 = Bridge(name='br02_v6', subnet='2001:20::/32')
        br03_v6 = Bridge(name='br03_v6', subnet='2001:30::/32')

        cls.ctns = {
            'ipv4': [g1_v4, q1_v4, o1_v4, o2_v4],
            'ipv6': [g1_v6, q1_v6, o1_v6, o2_v6],
        }
        cls.gobgps = {
            'ipv4': g1_v4,
            'ipv6': g1_v6,
        }
        cls.quaggas = {
            'ipv4': q1_v4,
            'ipv6': q1_v6,
        }
        cls.others = {
            'ipv4': [o1_v4, o2_v4],
            'ipv6': [o1_v6, o2_v6],
        }
        cls.bridges = {
            'br01_v4': br01_v4,
            'br02_v4': br02_v4,
            'br03_v4': br03_v4,
            'br01_v6': br01_v6,
            'br02_v6': br02_v6,
            'br03_v6': br03_v6,
        }
Exemple #11
0
    def test_05_add_quagga(self):
        q4 = QuaggaBGPContainer(name='q4', asn=65004, router_id='192.168.0.5')
        self.quaggas['q4'] = q4
        initial_wait_time = q4.run()
        time.sleep(initial_wait_time)

        self.gobgp.add_peer(q4)
        q4.add_peer(self.gobgp)

        q4.add_route('10.0.4.0/24')

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q4)
Exemple #12
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1',
                            asn=65000,
                            router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)

        rs_clients = [
            QuaggaBGPContainer(name='q{0}'.format(i + 1),
                               asn=(65001 + i),
                               router_id='192.168.0.{0}'.format(i + 2))
            for i in range(3)
        ]
        ctns = [g1] + rs_clients
        q1 = rs_clients[0]
        q2 = rs_clients[1]
        q3 = rs_clients[2]

        # advertise a route from route-server-clients
        routes = []
        for idx, rs_client in enumerate(rs_clients):
            route = '10.0.{0}.0/24'.format(idx + 1)
            rs_client.add_route(route)
            routes.append(route)

        initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(initial_wait_time)

        for rs_client in rs_clients:
            g1.add_peer(rs_client,
                        is_rs_client=True,
                        passwd='passwd',
                        passive=True,
                        prefix_limit=10)
            rs_client.add_peer(g1, passwd='passwd')

        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3}
Exemple #13
0
    def test_09_add_distant_relative(self):
        q1 = self.quaggas['q1']
        q2 = self.quaggas['q2']
        q3 = self.quaggas['q3']
        q5 = QuaggaBGPContainer(name='q5', asn=65005, router_id='192.168.0.6')

        initial_wait_time = q5.run()
        time.sleep(initial_wait_time)

        for q in [q2, q3]:
            q5.add_peer(q)
            q.add_peer(q5)

        med200 = {'name': 'med200',
                  'type': 'permit',
                  'match': '0.0.0.0/0',
                  'med': 200}
        q2.add_policy(med200, self.gobgp, 'out')
        med100 = {'name': 'med100',
                  'type': 'permit',
                  'match': '0.0.0.0/0',
                  'med': 100}
        q3.add_policy(med100, self.gobgp, 'out')

        q5.add_route('10.0.6.0/24')

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q2)
        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q3)
        q2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)
        q3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)

        timeout = 120
        interval = 1
        count = 0
        while True:
            paths = self.gobgp.get_adj_rib_out(q1, '10.0.6.0/24')
            if len(paths) > 0:
                path = paths[0]
                print "{0}'s nexthop is {1}".format(path['nlri']['prefix'],
                                                    path['nexthop'])
                n_addrs = [i[1].split('/')[0] for i in self.gobgp.ip_addrs]
                if path['nexthop'] in n_addrs:
                    break

            time.sleep(interval)
            count += interval
            if count >= timeout:
                raise Exception('timeout')
Exemple #14
0
    def test_15_add_ebgp_peer(self):
        q4 = QuaggaBGPContainer(name='q4', asn=65001, router_id='192.168.0.5')
        self.quaggas['q4'] = q4
        initial_wait_time = q4.run()
        time.sleep(initial_wait_time)

        self.gobgp.add_peer(q4)
        q4.add_peer(self.gobgp)

        prefix = '10.0.4.0/24'
        q4.add_route(prefix)

        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q4)

        q1 = self.quaggas['q1']
        q2 = self.quaggas['q2']
        for q in [q1, q2]:
            def _f():
                return prefix in [p['nlri']['prefix'] for p in self.gobgp.get_adj_rib_out(q)]
            wait_for_completion(_f)

        def f():
            return len(q2.get_global_rib(prefix)) == 1
        wait_for_completion(f)
Exemple #15
0
    def test_10_add_distant_relative(self):
        q1 = self.quaggas['q1']
        q2 = self.quaggas['q2']
        q3 = self.quaggas['q3']
        q5 = QuaggaBGPContainer(name='q5', asn=65005, router_id='192.168.0.6')

        initial_wait_time = q5.run()
        time.sleep(initial_wait_time)

        for q in [q2, q3]:
            q5.add_peer(q)
            q.add_peer(q5)

        med200 = {
            'name': 'med200',
            'type': 'permit',
            'match': '0.0.0.0/0',
            'med': 200,
            'priority': 10
        }
        q2.add_policy(med200, self.gobgp, 'out')
        med100 = {
            'name': 'med100',
            'type': 'permit',
            'match': '0.0.0.0/0',
            'med': 100,
            'priority': 10
        }
        q3.add_policy(med100, self.gobgp, 'out')

        q5.add_route('10.0.6.0/24')

        q2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)
        q3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)
        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q2)
        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q3)

        def check_nexthop(target_prefix, expected_nexthop):
            is_done = False
            for _ in range(self.retry_limit):
                if is_done:
                    break
                time.sleep(self.wait_per_retry)
                for path in q1.get_global_rib():
                    if path['prefix'] == target_prefix:
                        print("{0}'s nexthop is {1}".format(
                            path['prefix'], path['nexthop']))
                        n_addrs = [
                            i[1].split('/')[0]
                            for i in expected_nexthop.ip_addrs
                        ]
                        if path['nexthop'] in n_addrs:
                            is_done = True
                            break
            return is_done

        done = check_nexthop('10.0.6.0/24', q3)
        self.assertTrue(done)

        med300 = {
            'name': 'med300',
            'type': 'permit',
            'match': '0.0.0.0/0',
            'med': 300,
            'priority': 5
        }
        q3.add_policy(med300, self.gobgp, 'out')

        time.sleep(self.wait_per_retry)

        done = check_nexthop('10.0.6.0/24', q2)
        self.assertTrue(done)
Exemple #16
0
    def setUpClass(cls):
        #                  +-----Confederation(AS30)-----+
        #  AS21     AS20   | +-AS65002-+     +-AS65001-+ |   AS10
        # +----+   +----+  | | +-----+ |     | +-----+ | |  +----+
        # | q3 |---| q2 |--+-+-| g1  |-+-----+-| q11 |-+-+--| q1 |
        # +----+   +----+  | | +-----+ |     | +-----+ | |  +----+
        #                  | |    |    |     |    |    | |
        #                  | |    |    |     |    |    | |
        #                  | |    |    |     |    |    | |
        #                  | | +-----+ |     | +-----+ | |
        #                  | | | q22 | |     | | q12 | | |
        #                  | | +-----+ |     | +-----+ | |
        #                  | +---------+     +---------+ |
        #                  +-----------------------------+

        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        bgp_conf_1 = {
            'global': {
                'confederation': {
                    'config': {
                        'enabled': True,
                        'identifier': 30,
                        'member-as-list': [65002]
                    }
                }
            }
        }
        bgp_conf_2 = {
            'global': {
                'confederation': {
                    'config': {
                        'enabled': True,
                        'identifier': 30,
                        'member-as-list': [65001]
                    }
                }
            }
        }

        g1 = GoBGPContainer(name='g1',
                            asn=65002,
                            router_id='192.168.2.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level,
                            bgp_config=bgp_conf_2)

        q1 = QuaggaBGPContainer(name='q1', asn=10, router_id='1.1.1.1')
        q2 = QuaggaBGPContainer(name='q2', asn=20, router_id='2.2.2.2')
        q3 = QuaggaBGPContainer(name='q3', asn=21, router_id='3.3.3.3')
        q11 = QuaggaBGPContainer(name='q11',
                                 asn=65001,
                                 router_id='192.168.1.1',
                                 bgpd_config=bgp_conf_1)
        q12 = QuaggaBGPContainer(name='q12',
                                 asn=65001,
                                 router_id='192.168.1.2',
                                 bgpd_config=bgp_conf_1)
        q22 = QuaggaBGPContainer(name='q22',
                                 asn=65002,
                                 router_id='192.168.2.2',
                                 bgpd_config=bgp_conf_2)

        ctns = [g1, q1, q2, q3, q11, q12, q22]

        cls.initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(cls.initial_wait_time)

        q1.add_peer(q11, remote_as=30)
        q11.add_peer(q1)
        q11.add_peer(q12)
        q12.add_peer(q11)
        g1.add_peer(q11)
        q11.add_peer(g1)
        g1.add_peer(q22)
        q22.add_peer(g1)
        g1.add_peer(q2)
        q2.add_peer(g1, remote_as=30)
        q3.add_peer(q2)
        q2.add_peer(q3)
        cls.gobgp = g1
        cls.quaggas = {
            'q1': q1,
            'q2': q2,
            'q3': q3,
            'q11': q11,
            'q12': q12,
            'q22': q22
        }
Exemple #17
0
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1',
                            asn=65000,
                            router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65000, router_id='192.168.0.2')
        q2 = QuaggaBGPContainer(name='q2', asn=65000, router_id='192.168.0.3')
        q3 = QuaggaBGPContainer(name='q3', asn=65000, router_id='192.168.0.4')
        q4 = QuaggaBGPContainer(name='q4', asn=65000, router_id='192.168.0.5')

        qs = [q1, q2, q3, q4]
        ctns = [g1, q1, q2, q3, q4]

        # advertise a route from q1, q2
        for idx, c in enumerate(qs):
            route = '10.0.{0}.0/24'.format(idx + 1)
            c.add_route(route)

        initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(initial_wait_time)

        # g1 as a route reflector
        g1.add_peer(q1, is_rr_client=True)
        q1.add_peer(g1)
        g1.add_peer(q2, is_rr_client=True)
        q2.add_peer(g1)
        g1.add_peer(q3)
        q3.add_peer(g1)
        g1.add_peer(q4)
        q4.add_peer(g1)

        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3, 'q4': q4}
Exemple #18
0
    def setUpClass(cls):
        #                  +-----Confederation(AS30)-----+
        #  AS21     AS20   | +-AS65002-+     +-AS65001-+ |   AS10
        # +----+   +----+  | | +-----+ |     | +-----+ | |  +----+
        # | q3 |---| q2 |--+-+-| g1  |-+-----+-| q11 |-+-+--| q1 |
        # +----+   +----+  | | +-----+ |     | +-----+ | |  +----+
        #                  | |    |    |     |    |    | |
        #                  | |    |    |     |    |    | |
        #                  | |    |    |     |    |    | |
        #                  | | +-----+ |     | +-----+ | |
        #                  | | | q22 | |     | | q12 | | |
        #                  | | +-----+ |     | +-----+ | |
        #                  | +---------+     +---------+ |
        #                  +-----------------------------+

        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        bgp_conf_1 = {'global': {'confederation': {'config': {
            'enabled': True, 'identifier': 30, 'member-as-list': [65002]}}}}
        bgp_conf_2 = {'global': {'confederation': {'config': {
            'enabled': True, 'identifier': 30, 'member-as-list': [65001]}}}}

        g1 = GoBGPContainer(name='g1', asn=65002, router_id='192.168.2.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level,
                            bgp_config=bgp_conf_2)

        q1 = QuaggaBGPContainer(name='q1', asn=10, router_id='1.1.1.1')
        q2 = QuaggaBGPContainer(name='q2', asn=20, router_id='2.2.2.2')
        q3 = QuaggaBGPContainer(name='q3', asn=21, router_id='3.3.3.3')
        q11 = QuaggaBGPContainer(name='q11', asn=65001, router_id='192.168.1.1', bgpd_config=bgp_conf_1)
        q12 = QuaggaBGPContainer(name='q12', asn=65001, router_id='192.168.1.2', bgpd_config=bgp_conf_1)
        q22 = QuaggaBGPContainer(name='q22', asn=65002, router_id='192.168.2.2', bgpd_config=bgp_conf_2)

        ctns = [g1, q1, q2, q3, q11, q12, q22]

        cls.initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(cls.initial_wait_time)

        q1.add_peer(q11, remote_as=30)
        q11.add_peer(q1)
        q11.add_peer(q12)
        q12.add_peer(q11)
        g1.add_peer(q11)
        q11.add_peer(g1)
        g1.add_peer(q22)
        q22.add_peer(g1)
        g1.add_peer(q2)
        q2.add_peer(g1, remote_as=30)
        q3.add_peer(q2)
        q2.add_peer(q3)
        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3, 'q11': q11, 'q12': q12, 'q22': q22}
    def setUpClass(cls):
        gobgp_ctn_image_name = parser_option.gobgp_image
        base.TEST_PREFIX = parser_option.test_prefix

        g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
                            ctn_image_name=gobgp_ctn_image_name,
                            log_level=parser_option.gobgp_log_level)
        q1 = QuaggaBGPContainer(name='q1', asn=65000, router_id='192.168.0.2')
        q2 = QuaggaBGPContainer(name='q2', asn=65000, router_id='192.168.0.3')
        q3 = QuaggaBGPContainer(name='q3', asn=65000, router_id='192.168.0.4')
        q4 = QuaggaBGPContainer(name='q4', asn=65000, router_id='192.168.0.5')

        qs = [q1, q2, q3, q4]
        ctns = [g1, q1, q2, q3, q4]

        # advertise a route from q1, q2
        for idx, c in enumerate(qs):
            route = '10.0.{0}.0/24'.format(idx + 1)
            c.add_route(route)

        initial_wait_time = max(ctn.run() for ctn in ctns)

        time.sleep(initial_wait_time)

        # g1 as a route reflector
        g1.add_peer(q1, is_rr_client=True)
        q1.add_peer(g1)
        g1.add_peer(q2, is_rr_client=True)
        q2.add_peer(g1)
        g1.add_peer(q3)
        q3.add_peer(g1)
        g1.add_peer(q4)
        q4.add_peer(g1)

        cls.gobgp = g1
        cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3, 'q4': q4}
    def test_10_add_distant_relative(self):
        q1 = self.quaggas['q1']
        q2 = self.quaggas['q2']
        q3 = self.quaggas['q3']
        q5 = QuaggaBGPContainer(name='q5', asn=65005, router_id='192.168.0.6')

        initial_wait_time = q5.run()
        time.sleep(initial_wait_time)

        for q in [q2, q3]:
            q5.add_peer(q)
            q.add_peer(q5)

        med200 = {'name': 'med200',
                  'type': 'permit',
                  'match': '0.0.0.0/0',
                  'med': 200,
                  'priority': 10}
        q2.add_policy(med200, self.gobgp, 'out')
        med100 = {'name': 'med100',
                  'type': 'permit',
                  'match': '0.0.0.0/0',
                  'med': 100,
                  'priority': 10}
        q3.add_policy(med100, self.gobgp, 'out')

        q5.add_route('10.0.6.0/24')

        q2.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)
        q3.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q5)
        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q2)
        self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q3)

        def check_nexthop(target_prefix, expected_nexthop):
            is_done = False
            for _ in range(self.retry_limit):
                if is_done:
                    break
                time.sleep(self.wait_per_retry)
                for path in q1.get_global_rib():
                    if path['prefix'] == target_prefix:
                        print "{0}'s nexthop is {1}".format(path['prefix'],
                                                            path['nexthop'])
                        n_addrs = [i[1].split('/')[0] for i in
                                   expected_nexthop.ip_addrs]
                        if path['nexthop'] in n_addrs:
                            is_done = True
                            break
            return is_done

        done = check_nexthop('10.0.6.0/24', q3)
        self.assertTrue(done)

        med300 = {'name': 'med300',
                  'type': 'permit',
                  'match': '0.0.0.0/0',
                  'med': 300,
                  'priority': 5}
        q3.add_policy(med300, self.gobgp, 'out')

        time.sleep(self.wait_per_retry)

        done = check_nexthop('10.0.6.0/24', q2)
        self.assertTrue(done)