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])