github.com/osrg/gobgp/v3@v3.30.0/test/scenario_test/bgp_confederation_test.py (about)

     1  # Copyright (C) 2017 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  import sys
    18  import time
    19  import unittest
    20  
    21  import collections
    22  collections.Callable = collections.abc.Callable
    23  
    24  import nose
    25  
    26  from lib.noseplugin import OptionParser, parser_option
    27  
    28  from lib import base
    29  from lib.base import BGP_FSM_ESTABLISHED, local
    30  from lib.gobgp import GoBGPContainer
    31  from lib.quagga import QuaggaBGPContainer
    32  
    33  
    34  class GoBGPTestBase(unittest.TestCase):
    35  
    36      def _check_global_rib_first(self, q, prefix, aspath):
    37          route = q.get_global_rib(prefix)[0]
    38          self.assertListEqual(aspath, route['aspath'])
    39  
    40      @classmethod
    41      def setUpClass(cls):
    42          #                  +-----Confederation(AS30)-----+
    43          #  AS21     AS20   | +-AS65002-+     +-AS65001-+ |   AS10
    44          # +----+   +----+  | | +-----+ |     | +-----+ | |  +----+
    45          # | q3 |---| q2 |--+-+-| g1  |-+-----+-| q11 |-+-+--| q1 |
    46          # +----+   +----+  | | +-----+ |     | +-----+ | |  +----+
    47          #                  | |    |    |     |    |    | |
    48          #                  | |    |    |     |    |    | |
    49          #                  | |    |    |     |    |    | |
    50          #                  | | +-----+ |     | +-----+ | |
    51          #                  | | | q22 | |     | | q12 | | |
    52          #                  | | +-----+ |     | +-----+ | |
    53          #                  | +---------+     +---------+ |
    54          #                  +-----------------------------+
    55  
    56          gobgp_ctn_image_name = parser_option.gobgp_image
    57          base.TEST_PREFIX = parser_option.test_prefix
    58  
    59          bgp_conf_1 = {'global': {'confederation': {'config': {
    60              'enabled': True, 'identifier': 30, 'member-as-list': [65002]}}}}
    61          bgp_conf_2 = {'global': {'confederation': {'config': {
    62              'enabled': True, 'identifier': 30, 'member-as-list': [65001]}}}}
    63  
    64          g1 = GoBGPContainer(name='g1', asn=65002, router_id='192.168.2.1',
    65                              ctn_image_name=gobgp_ctn_image_name,
    66                              log_level=parser_option.gobgp_log_level,
    67                              bgp_config=bgp_conf_2)
    68  
    69          q1 = QuaggaBGPContainer(name='q1', asn=10, router_id='1.1.1.1')
    70          q2 = QuaggaBGPContainer(name='q2', asn=20, router_id='2.2.2.2')
    71          q3 = QuaggaBGPContainer(name='q3', asn=21, router_id='3.3.3.3')
    72          q11 = QuaggaBGPContainer(name='q11', asn=65001, router_id='192.168.1.1', bgpd_config=bgp_conf_1)
    73          q12 = QuaggaBGPContainer(name='q12', asn=65001, router_id='192.168.1.2', bgpd_config=bgp_conf_1)
    74          q22 = QuaggaBGPContainer(name='q22', asn=65002, router_id='192.168.2.2', bgpd_config=bgp_conf_2)
    75  
    76          ctns = [g1, q1, q2, q3, q11, q12, q22]
    77  
    78          cls.initial_wait_time = max(ctn.run() for ctn in ctns)
    79  
    80          time.sleep(cls.initial_wait_time)
    81  
    82          q1.add_peer(q11, remote_as=30)
    83          q11.add_peer(q1)
    84          q11.add_peer(q12)
    85          q12.add_peer(q11)
    86          g1.add_peer(q11)
    87          q11.add_peer(g1)
    88          g1.add_peer(q22)
    89          q22.add_peer(g1)
    90          g1.add_peer(q2)
    91          q2.add_peer(g1, remote_as=30)
    92          q3.add_peer(q2)
    93          q2.add_peer(q3)
    94          cls.gobgp = g1
    95          cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3, 'q11': q11, 'q12': q12, 'q22': q22}
    96  
    97      # test each neighbor state is turned establish
    98      def test_01_neighbor_established(self):
    99          self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.quaggas['q11'])
   100          self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.quaggas['q22'])
   101          self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.quaggas['q2'])
   102          self.quaggas['q11'].wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.quaggas['q1'])
   103          self.quaggas['q11'].wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.quaggas['q12'])
   104          self.quaggas['q2'].wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.quaggas['q3'])
   105  
   106      def test_02_route_advertise(self):
   107          self.quaggas['q3'].add_route('10.0.0.0/24')
   108          time.sleep(self.initial_wait_time)
   109  
   110          routes = []
   111          for _ in range(60):
   112              routes = self.quaggas['q1'].get_global_rib('10.0.0.0/24')
   113              if routes:
   114                  break
   115              time.sleep(1)
   116          self.assertFalse(len(routes) == 0)
   117  
   118          # Confirm AS_PATH in confederation is removed
   119          self._check_global_rib_first(self.quaggas['q1'], '10.0.0.0/24', [30, 20, 21])
   120  
   121          # Confirm AS_PATH in confederation is not removed
   122          self._check_global_rib_first(self.quaggas['q11'], '10.0.0.0/24', [65002, 20, 21])
   123  
   124          self._check_global_rib_first(self.quaggas['q22'], '10.0.0.0/24', [20, 21])
   125  
   126      def test_03_best_path(self):
   127          self.quaggas['q1'].add_route('10.0.0.0/24')
   128  
   129          routes = []
   130          for _ in range(60):
   131              routes = self.gobgp.get_global_rib('10.0.0.0/24')
   132              if len(routes) == 1:
   133                  if len(routes[0]['paths']) == 2:
   134                      break
   135              time.sleep(1)
   136          self.assertFalse(len(routes) != 1)
   137          self.assertFalse(len(routes[0]['paths']) != 2)
   138  
   139          # In g1, there are two routes to 10.0.0.0/24
   140          # confirm the route from q1 is selected as the best path
   141          # because it has shorter AS_PATH.
   142          # (AS_CONFED_* segments in AS_PATH is not counted)
   143          paths = routes[0]['paths']
   144          self.assertTrue(paths[0]['aspath'], [65001, 10])
   145  
   146          # confirm the new best path is advertised
   147          self._check_global_rib_first(self.quaggas['q22'], '10.0.0.0/24', [65001, 10])
   148  
   149  
   150  if __name__ == '__main__':
   151      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
   152      if int(output) != 0:
   153          print("docker not found")
   154          sys.exit(1)
   155  
   156      nose.main(argv=sys.argv, addplugins=[OptionParser()],
   157                defaultTest=sys.argv[0])