github.com/osrg/gobgp/v3@v3.30.0/test/scenario_test/global_policy_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  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 (
    30      BGP_FSM_IDLE,
    31      BGP_FSM_ESTABLISHED,
    32      BGP_ATTR_TYPE_COMMUNITIES,
    33      local,
    34  )
    35  from lib.gobgp import GoBGPContainer
    36  from lib.exabgp import ExaBGPContainer
    37  
    38  
    39  def community_exists(path, com):
    40      a, b = com.split(':')
    41      com = (int(a) << 16) + int(b)
    42      for a in path['attrs']:
    43          if a['type'] == BGP_ATTR_TYPE_COMMUNITIES and com in a['communities']:
    44              return True
    45      return False
    46  
    47  
    48  class GoBGPTestBase(unittest.TestCase):
    49  
    50      @classmethod
    51      def setUpClass(cls):
    52          gobgp_ctn_image_name = parser_option.gobgp_image
    53          base.TEST_PREFIX = parser_option.test_prefix
    54  
    55          g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
    56                              ctn_image_name=gobgp_ctn_image_name,
    57                              log_level=parser_option.gobgp_log_level,
    58                              config_format=parser_option.config_format)
    59          q1 = ExaBGPContainer(name='q1', asn=65001, router_id='192.168.0.2')
    60          q2 = ExaBGPContainer(name='q2', asn=65002, router_id='192.168.0.3')
    61          q3 = ExaBGPContainer(name='q3', asn=65003, router_id='192.168.0.4')
    62  
    63          qs = [q1, q2, q3]
    64          ctns = [g1, q1, q2, q3]
    65  
    66          initial_wait_time = max(ctn.run() for ctn in ctns)
    67          time.sleep(initial_wait_time)
    68  
    69          g1.local('gobgp global policy export add default reject')
    70  
    71          for q in qs:
    72              g1.add_peer(q)
    73              q.add_peer(g1)
    74  
    75          # advertise a route from q1, q2, q3
    76          for idx, q in enumerate(qs):
    77              route = '10.0.{0}.0/24'.format(idx + 1)
    78              q.add_route(route)
    79  
    80          cls.gobgp = g1
    81          cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3}
    82  
    83      # test each neighbor state is turned establish
    84      def test_01_neighbor_established(self):
    85          for q in self.quaggas.values():
    86              self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q)
    87  
    88      def test_02_check_adj_rib_out(self):
    89          for q in self.quaggas.values():
    90              self.assertEqual(len(self.gobgp.get_adj_rib_out(q)), 0)
    91  
    92      def test_03_add_peer(self):
    93          q = ExaBGPContainer(name='q4', asn=65004, router_id='192.168.0.5')
    94          time.sleep(q.run())
    95          self.gobgp.add_peer(q)
    96          q.add_peer(self.gobgp)
    97          q.add_route('10.10.0.0/24')
    98          self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q)
    99          self.quaggas['q4'] = q
   100          for q in self.quaggas.values():
   101              self.assertEqual(len(self.gobgp.get_adj_rib_out(q)), 0)
   102  
   103      def test_04_disable_peer(self):
   104          q3 = self.quaggas['q3']
   105          self.gobgp.disable_peer(q3)
   106          self.gobgp.wait_for(expected_state=BGP_FSM_IDLE, peer=q3)
   107  
   108          for q in self.quaggas.values():
   109              if q.name == 'q3':
   110                  continue
   111              self.assertEqual(len(self.gobgp.get_adj_rib_out(q)), 0)
   112  
   113      def test_05_enable_peer(self):
   114          q3 = self.quaggas['q3']
   115          self.gobgp.enable_peer(q3)
   116          self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q3)
   117  
   118          for q in self.quaggas.values():
   119              self.assertEqual(len(self.gobgp.get_adj_rib_out(q)), 0)
   120  
   121      def test_06_disable_peer2(self):
   122          q3 = self.quaggas['q3']
   123          # advertise a route which was also advertised by q1
   124          # this route will be best for g1 because q3's router-id is larger
   125          # than q1
   126          q3.add_route('10.0.1.0/24')
   127          time.sleep(3)
   128          # then disable q3
   129          self.gobgp.disable_peer(q3)
   130          self.gobgp.wait_for(expected_state=BGP_FSM_IDLE, peer=q3)
   131  
   132          for q in self.quaggas.values():
   133              if q.name == 'q3':
   134                  continue
   135              self.assertEqual(len(self.gobgp.get_adj_rib_out(q)), 0)
   136  
   137      def test_07_adv_to_one_peer(self):
   138          self.gobgp.local('gobgp policy neighbor add ns0 {0}'.format(self.gobgp.peers[self.quaggas['q1']]['neigh_addr'].split('/')[0]))
   139          self.gobgp.local('gobgp policy statement add st0')
   140          self.gobgp.local('gobgp policy statement st0 add condition neighbor ns0')
   141          self.gobgp.local('gobgp policy statement st0 add action accept')
   142          self.gobgp.local('gobgp policy add p0 st0')
   143          self.gobgp.local('gobgp global policy export add p0 default reject')
   144          for q in self.quaggas.values():
   145              self.gobgp.softreset(q, type='out')
   146  
   147      def test_08_check_adj_rib_out(self):
   148          for q in self.quaggas.values():
   149              if q.name == 'q3':
   150                  continue
   151              paths = self.gobgp.get_adj_rib_out(q)
   152              if q == self.quaggas['q1']:
   153                  self.assertEqual(len(paths), 2)
   154              else:
   155                  self.assertEqual(len(paths), 0)
   156  
   157      def test_09_change_global_policy(self):
   158          self.gobgp.local('gobgp policy statement st0 add action community add 65100:10')
   159          self.gobgp.local('gobgp global policy export set p0 default accept')
   160          for q in self.quaggas.values():
   161              self.gobgp.softreset(q, type='out')
   162  
   163      def test_10_check_adj_rib_out(self):
   164          for q in self.quaggas.values():
   165              if q.name == 'q3':
   166                  continue
   167              paths = self.gobgp.get_adj_rib_out(q)
   168              if q != self.quaggas['q3']:
   169                  self.assertEqual(len(paths), 2)
   170              for path in paths:
   171                  if q == self.quaggas['q1']:
   172                      self.assertTrue(community_exists(path, '65100:10'))
   173                  else:
   174                      self.assertFalse(community_exists(path, '65100:10'))
   175  
   176      def test_11_add_ibgp_peer(self):
   177          q = ExaBGPContainer(name='q5', asn=65000, router_id='192.168.0.6')
   178          time.sleep(q.run())
   179          self.quaggas['q5'] = q
   180  
   181          self.gobgp.add_peer(q)
   182          q.add_peer(self.gobgp)
   183          self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=q)
   184  
   185      def test_12_add_local_pref_policy(self):
   186          self.gobgp.local('gobgp policy statement st1 add action accept')
   187          self.gobgp.local('gobgp policy statement st1 add action local-pref 300')
   188          self.gobgp.local('gobgp policy add p1 st1')
   189          self.gobgp.local('gobgp global policy export set p1 default reject')
   190          for q in self.quaggas.values():
   191              self.gobgp.softreset(q, type='out')
   192  
   193      def test_13_check_adj_rib_out(self):
   194          q1 = self.quaggas['q1']
   195          for path in self.gobgp.get_adj_rib_out(q1):
   196              self.assertTrue(path['local-pref'] is None)
   197          q5 = self.quaggas['q5']
   198          for path in self.gobgp.get_adj_rib_out(q5):
   199              self.assertEqual(path['local-pref'], 300)
   200  
   201      def test_14_route_type_condition_local(self):
   202          self.gobgp.local('gobgp policy statement st2 add action accept')
   203          self.gobgp.local('gobgp policy statement st2 add condition route-type local')
   204          self.gobgp.local('gobgp policy add p2 st2')
   205          self.gobgp.local('gobgp global policy export set p2 default reject')
   206          for q in self.quaggas.values():
   207              self.gobgp.softreset(q, type='out')
   208  
   209          q1 = self.quaggas['q1']
   210          self.assertEqual(len(self.gobgp.get_adj_rib_out(q1)), 0)
   211  
   212          self.gobgp.add_route('10.20.0.0/24')
   213  
   214          time.sleep(1)
   215  
   216          self.assertEqual(len(self.gobgp.get_adj_rib_out(q1)), 1)
   217          self.assertEqual(self.gobgp.get_adj_rib_out(q1)[0]['nlri']['prefix'], '10.20.0.0/24')
   218  
   219      def test_15_route_type_condition_internal(self):
   220          self.gobgp.local('gobgp policy statement st22 add action accept')
   221          self.gobgp.local('gobgp policy statement st22 add condition route-type internal')
   222          self.gobgp.local('gobgp policy add p2 st22')
   223          self.gobgp.local('gobgp policy del p2 st2')
   224          for q in self.quaggas.values():
   225              self.gobgp.softreset(q, type='out')
   226  
   227          q1 = self.quaggas['q1']
   228          self.assertEqual(len(self.gobgp.get_adj_rib_out(q1)), 0)
   229  
   230          q5 = self.quaggas['q5']
   231          q5.add_route('10.30.0.0/24')
   232  
   233          time.sleep(1)
   234  
   235          self.assertEqual(len(self.gobgp.get_adj_rib_out(q1)), 1)
   236          self.assertEqual(self.gobgp.get_adj_rib_out(q1)[0]['nlri']['prefix'], '10.30.0.0/24')
   237  
   238      def test_16_route_type_condition_external(self):
   239          self.gobgp.local('gobgp policy statement st222 add action accept')
   240          self.gobgp.local('gobgp policy statement st222 add condition route-type external')
   241          self.gobgp.local('gobgp policy add p2 st222')
   242          self.gobgp.local('gobgp policy del p2 st22')
   243          for q in self.quaggas.values():
   244              self.gobgp.softreset(q, type='out')
   245  
   246          q1 = self.quaggas['q1']
   247          num1 = len(self.gobgp.get_adj_rib_out(q1))
   248  
   249          self.gobgp.add_route('10.40.0.0/24')
   250          time.sleep(1)
   251          num2 = len(self.gobgp.get_adj_rib_out(q1))
   252          self.assertEqual(num1, num2)
   253  
   254          q5 = self.quaggas['q5']
   255          q5.add_route('10.50.0.0/24')
   256          time.sleep(1)
   257          num3 = len(self.gobgp.get_adj_rib_out(q1))
   258          self.assertEqual(num1, num3)
   259  
   260          q2 = self.quaggas['q2']
   261          q2.add_route('10.60.0.0/24')
   262          time.sleep(1)
   263          num4 = len(self.gobgp.get_adj_rib_out(q1))
   264          self.assertEqual(num1 + 1, num4)
   265  
   266      def test_17_multi_statement(self):
   267          self.gobgp.local('gobgp policy statement st3 add action med set 100')
   268          self.gobgp.local('gobgp policy statement st4 add action local-pref 100')
   269          self.gobgp.local('gobgp policy add p3 st3 st4')
   270          self.gobgp.local('gobgp global policy import set p3 default accept')
   271  
   272          self.gobgp.add_route('10.70.0.0/24')
   273          time.sleep(1)
   274          rib = self.gobgp.get_global_rib('10.70.0.0/24')
   275          self.assertEqual(len(rib), 1)
   276          self.assertEqual(len(rib[0]['paths']), 1)
   277          path = rib[0]['paths'][0]
   278          self.assertEqual(path['med'], 100)
   279          self.assertEqual(path['local-pref'], 100)
   280  
   281      def test_18_reject_policy(self):
   282          self.gobgp.local('gobgp global policy import set default reject')
   283          self.gobgp.local('gobgp neighbor all softresetin')
   284  
   285          time.sleep(1)
   286  
   287          # self-generated routes remain since softresetin doesn't re-evaluate
   288          # them
   289          for v in self.gobgp.get_global_rib():
   290              for p in v['paths']:
   291                  self.assertEqual(p['nexthop'], '0.0.0.0')
   292  
   293  
   294  if __name__ == '__main__':
   295      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
   296      if int(output) != 0:
   297          print("docker not found")
   298          sys.exit(1)
   299  
   300      nose.main(argv=sys.argv, addplugins=[OptionParser()],
   301                defaultTest=sys.argv[0])