github.com/osrg/gobgp/v3@v3.30.0/test/scenario_test/evpn_test.py (about) 1 # Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 # implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 17 from itertools import combinations 18 import sys 19 import time 20 import unittest 21 22 import collections 23 collections.Callable = collections.abc.Callable 24 25 import nose 26 27 from lib.noseplugin import OptionParser, parser_option 28 29 from lib import base 30 from lib.base import ( 31 BGP_FSM_ESTABLISHED, 32 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES, 33 local, 34 ) 35 from lib.gobgp import GoBGPContainer 36 37 38 def get_mac_mobility_sequence(pattr): 39 for ecs in [ 40 p['value'] for p in pattr 41 if 'type' in p and p['type'] == BGP_ATTR_TYPE_EXTENDED_COMMUNITIES]: 42 for ec in [e for e in ecs if 'type' in e and e['type'] == 6]: 43 if ec['subtype'] == 0: 44 if 'sequence' not in ec: 45 return 0 46 else: 47 return ec['sequence'] 48 return -1 49 50 51 class GoBGPTestBase(unittest.TestCase): 52 53 @classmethod 54 def setUpClass(cls): 55 gobgp_ctn_image_name = parser_option.gobgp_image 56 base.TEST_PREFIX = parser_option.test_prefix 57 58 g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1', 59 ctn_image_name=gobgp_ctn_image_name, 60 log_level=parser_option.gobgp_log_level) 61 g2 = GoBGPContainer(name='g2', asn=65000, router_id='192.168.0.2', 62 ctn_image_name=gobgp_ctn_image_name, 63 log_level=parser_option.gobgp_log_level) 64 ctns = [g1, g2] 65 66 initial_wait_time = max(ctn.run() for ctn in ctns) 67 68 time.sleep(initial_wait_time) 69 g1.local("gobgp vrf add vrf1 rd 10:10 rt both 10:10") 70 g1.local("gobgp vrf add vrf2 rd 10:20 rt both 10:20") 71 g2.local("gobgp vrf add vrf1 rd 20:10 rt both 10:10") 72 g2.local("gobgp vrf add vrf2 rd 20:20 rt both 10:20") 73 74 for a, b in combinations(ctns, 2): 75 a.add_peer(b, vpn=True, passwd='evpn') 76 b.add_peer(a, vpn=True, passwd='evpn') 77 78 cls.g1 = g1 79 cls.g2 = g2 80 81 # test each neighbor state is turned establish 82 def test_01_neighbor_established(self): 83 self.g1.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.g2) 84 85 def test_02_add_evpn_route(self): 86 self.g1.local('gobgp global rib add ' 87 '-a evpn macadv 11:22:33:44:55:66 10.0.0.1 esi AS 1 1 1 etag 1000 label 1000 ' 88 'rd 10:10 rt 10:10') 89 grib = self.g1.get_global_rib(rf='evpn') 90 self.assertEqual(len(grib), 1) 91 dst = grib[0] 92 self.assertEqual(len(dst['paths']), 1) 93 path = dst['paths'][0] 94 self.assertEqual(path['nexthop'], '0.0.0.0') 95 96 interval = 1 97 timeout = int(30 / interval) 98 done = False 99 for _ in range(timeout): 100 if done: 101 break 102 grib = self.g2.get_global_rib(rf='evpn') 103 104 if len(grib) < 1: 105 time.sleep(interval) 106 continue 107 108 self.assertEqual(len(grib), 1) 109 dst = grib[0] 110 self.assertEqual(len(dst['paths']), 1) 111 path = dst['paths'][0] 112 n_addrs = [i[1].split('/')[0] for i in self.g1.ip_addrs] 113 self.assertTrue(path['nexthop'] in n_addrs) 114 done = True 115 116 def test_03_check_mac_mobility(self): 117 self.g2.local('gobgp global rib add ' 118 '-a evpn macadv 11:22:33:44:55:66 10.0.0.1 esi AS 2 1 1 etag 1000 label 1000 ' 119 'rd 20:10 rt 10:10') 120 121 time.sleep(3) 122 123 grib = self.g1.get_global_rib(rf='evpn') 124 self.assertEqual(len(grib), 1) 125 dst = grib[0] 126 self.assertEqual(len(dst['paths']), 1) 127 path = dst['paths'][0] 128 n_addrs = [i[1].split('/')[0] for i in self.g2.ip_addrs] 129 self.assertTrue(path['nexthop'] in n_addrs) 130 self.assertEqual(get_mac_mobility_sequence(path['attrs']), 0) 131 132 def test_04_check_mac_mobility_again(self): 133 self.g1.local('gobgp global rib add ' 134 '-a evpn macadv 11:22:33:44:55:66 10.0.0.1 esi AS 3 1 1 etag 1000 label 1000 ' 135 'rd 10:10 rt 10:10') 136 137 time.sleep(3) 138 139 grib = self.g2.get_global_rib(rf='evpn') 140 self.assertEqual(len(grib), 1) 141 dst = grib[0] 142 self.assertEqual(len(dst['paths']), 1) 143 path = dst['paths'][0] 144 n_addrs = [i[1].split('/')[0] for i in self.g1.ip_addrs] 145 self.assertTrue(path['nexthop'] in n_addrs) 146 self.assertEqual(get_mac_mobility_sequence(path['attrs']), 1) 147 148 def test_05_check_mac_mobility_per_mac_vrf(self): 149 self.g2.local('gobgp global rib add ' 150 '-a evpn macadv 11:22:33:44:55:66 10.0.0.1 esi AS 4 1 1 etag 2000 label 2000 ' 151 'rd 20:20 rt 10:20') 152 153 time.sleep(3) 154 155 grib = self.g2.get_global_rib(rf='evpn') 156 self.assertEqual(len(grib), 2) 157 # first route is from previous tests 158 dst = grib[0] 159 self.assertEqual(len(dst['paths']), 1) 160 path = dst['paths'][0] 161 n_addrs = [i[1].split('/')[0] for i in self.g1.ip_addrs] 162 self.assertTrue(path['nexthop'] in n_addrs) 163 self.assertEqual(get_mac_mobility_sequence(path['attrs']), 1) 164 165 # dump global rib again on other gobgp instance to have our second route have the nexthop 166 # filled out. otherwise it'd be 0.0.0.0. 167 grib = self.g1.get_global_rib(rf='evpn') 168 self.assertEqual(len(grib), 2) 169 # second route from this test, in another mac-vrf 170 dst = grib[1] 171 self.assertEqual(len(dst['paths']), 1) 172 path = dst['paths'][0] 173 n_addrs = [i[1].split('/')[0] for i in self.g2.ip_addrs] 174 self.assertTrue(path['nexthop'] in n_addrs) 175 # no mac mobility for this route 176 self.assertEqual(get_mac_mobility_sequence(path['attrs']), -1) 177 178 179 if __name__ == '__main__': 180 output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True) 181 if int(output) != 0: 182 print("docker not found") 183 sys.exit(1) 184 185 nose.main(argv=sys.argv, addplugins=[OptionParser()], 186 defaultTest=sys.argv[0])