github.com/osrg/gobgp/v3@v3.30.0/test/scenario_test/route_server_policy_grpc_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  import inspect
    21  
    22  import collections
    23  collections.Callable = collections.abc.Callable
    24  
    25  import nose
    26  from nose.tools import (
    27      assert_true,
    28      assert_false,
    29  )
    30  
    31  from lib.noseplugin import OptionParser, parser_option
    32  
    33  from lib import base
    34  from lib.base import (
    35      Bridge,
    36      BGP_FSM_ESTABLISHED,
    37      BGP_ATTR_TYPE_COMMUNITIES,
    38      BGP_ATTR_TYPE_EXTENDED_COMMUNITIES,
    39      local,
    40  )
    41  from lib.gobgp import GoBGPContainer
    42  from lib.quagga import QuaggaBGPContainer
    43  from lib.exabgp import ExaBGPContainer
    44  
    45  
    46  counter = 1
    47  _SCENARIOS = {}
    48  
    49  
    50  def register_scenario(cls):
    51      global counter
    52      _SCENARIOS[counter] = cls
    53      counter += 1
    54  
    55  
    56  def lookup_scenario(name):
    57      for value in list(_SCENARIOS.values()):
    58          if value.__name__ == name:
    59              return value
    60      return None
    61  
    62  
    63  def wait_for(f, timeout=120):
    64      interval = 1
    65      count = 0
    66      while True:
    67          if f():
    68              return
    69  
    70          time.sleep(interval)
    71          count += interval
    72          if count >= timeout:
    73              raise Exception('timeout')
    74  
    75  
    76  @register_scenario
    77  class ImportPolicy(object):
    78      """
    79      No.1 import-policy test
    80                              --------------------------------
    81      e1 ->(192.168.2.0/24)-> | ->  q1-rib -> q1-adj-rib-out | --> q1
    82                              |                              |
    83                              | ->x q2-rib                   |
    84                              --------------------------------
    85      """
    86      @staticmethod
    87      def boot(env):
    88          gobgp_ctn_image_name = env.parser_option.gobgp_image
    89          log_level = env.parser_option.gobgp_log_level
    90          g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
    91                              ctn_image_name=gobgp_ctn_image_name,
    92                              log_level=log_level)
    93          e1 = ExaBGPContainer(name='e1', asn=65001, router_id='192.168.0.2')
    94          q1 = QuaggaBGPContainer(name='q1', asn=65002, router_id='192.168.0.3')
    95          q2 = QuaggaBGPContainer(name='q2', asn=65003, router_id='192.168.0.4')
    96  
    97          ctns = [g1, e1, q1, q2]
    98          initial_wait_time = max(ctn.run() for ctn in ctns)
    99          time.sleep(initial_wait_time)
   100  
   101          for q in [e1, q1, q2]:
   102              g1.add_peer(q, is_rs_client=True)
   103              q.add_peer(g1)
   104  
   105          env.g1 = g1
   106          env.e1 = e1
   107          env.q1 = q1
   108          env.q2 = q2
   109  
   110      @staticmethod
   111      def setup(env):
   112          g1 = env.g1
   113          e1 = env.e1
   114          q1 = env.q1
   115          q2 = env.q2
   116  
   117          g1.local('gobgp policy prefix add ps0 192.168.0.0/16 16..24')
   118          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0]))
   119          g1.local('gobgp policy statement add st0')
   120          g1.local('gobgp policy statement st0 add condition prefix ps0')
   121          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   122          g1.local('gobgp policy statement st0 add action reject')
   123          g1.local('gobgp policy add policy0 st0')
   124          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   125  
   126          # this will be blocked
   127          e1.add_route('192.168.2.0/24')
   128          # this will pass
   129          e1.add_route('192.168.2.0/15')
   130  
   131          for c in [e1, q1, q2]:
   132              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   133  
   134      @staticmethod
   135      def check(env):
   136          wait_for(lambda: len(env.g1.get_local_rib(env.q1)) == 2)
   137          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1)) == 2)
   138          wait_for(lambda: len(env.q1.get_global_rib()) == 2)
   139          wait_for(lambda: len(env.g1.get_local_rib(env.q2)) == 1)
   140          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2)) == 1)
   141          wait_for(lambda: len(env.q2.get_global_rib()) == 1)
   142  
   143      @staticmethod
   144      def executor(env):
   145          lookup_scenario("ImportPolicy").boot(env)
   146          lookup_scenario("ImportPolicy").setup(env)
   147          lookup_scenario("ImportPolicy").check(env)
   148  
   149  
   150  @register_scenario
   151  class ExportPolicy(object):
   152      """
   153      No.2 export-policy test
   154                              --------------------------------
   155      e1 ->(192.168.2.0/24)-> | -> q1-rib ->  q1-adj-rib-out | --> q1
   156                              |                              |
   157                              | -> q2-rib ->x q2-adj-rib-out |
   158                              --------------------------------
   159      """
   160      @staticmethod
   161      def boot(env):
   162          lookup_scenario("ImportPolicy").boot(env)
   163  
   164      @staticmethod
   165      def setup(env):
   166          g1 = env.g1
   167          e1 = env.e1
   168          q1 = env.q1
   169          q2 = env.q2
   170  
   171          g1.local('gobgp policy prefix add ps0 192.168.0.0/16 16..24')
   172          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   173          g1.local('gobgp policy statement add st0')
   174          g1.local('gobgp policy statement st0 add condition prefix ps0')
   175          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   176          g1.local('gobgp policy statement st0 add action reject')
   177          g1.local('gobgp policy add policy0 st0')
   178          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   179  
   180          # this will be blocked
   181          e1.add_route('192.168.2.0/24')
   182          # this will pass
   183          e1.add_route('192.168.2.0/15')
   184  
   185          for c in [e1, q1, q2]:
   186              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   187  
   188      @staticmethod
   189      def check(env):
   190          g1 = env.g1
   191          q1 = env.q1
   192          q2 = env.q2
   193          wait_for(lambda: len(g1.get_local_rib(q1)) == 2)
   194          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2)
   195          wait_for(lambda: len(q1.get_global_rib()) == 2)
   196          wait_for(lambda: len(g1.get_local_rib(q2)) == 2)
   197          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1)
   198          wait_for(lambda: len(q2.get_global_rib()) == 1)
   199  
   200      @staticmethod
   201      def executor(env):
   202          lookup_scenario("ExportPolicy").boot(env)
   203          lookup_scenario("ExportPolicy").setup(env)
   204          lookup_scenario("ExportPolicy").check(env)
   205  
   206  
   207  @register_scenario
   208  class ImportPolicyUpdate(object):
   209      """
   210      No.3 import-policy update test
   211  
   212      r1:192.168.2.0/24
   213      r2:192.168.20.0/24
   214      r3:192.168.200.0/24
   215                        -------------------------------------------------
   216                        | q1                                            |
   217      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   218                        |                                               |
   219                        | q2                                            |
   220                        | ->(r1)->       rib ->(r1)->       adj-rib-out | ->(r1)-> q2
   221                        -------------------------------------------------
   222                   |
   223           update gobgp.conf
   224                   |
   225                   V
   226                        -------------------------------------------------
   227                        | q1                                            |
   228      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   229                        |                                               |
   230                        | q2                                            |
   231                        | ->(r1,r3)->    rib ->(r1,r3)->    adj-rib-out | ->(r1,r3)-> q2
   232                        -------------------------------------------------
   233      """
   234      @staticmethod
   235      def boot(env):
   236          lookup_scenario("ImportPolicy").boot(env)
   237  
   238      @staticmethod
   239      def setup(env):
   240          g1 = env.g1
   241          e1 = env.e1
   242          q1 = env.q1
   243          q2 = env.q2
   244  
   245          g1.local('gobgp policy prefix add ps0 192.168.20.0/24')
   246          g1.local('gobgp policy prefix add ps0 192.168.200.0/24')
   247          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0]))
   248          g1.local('gobgp policy statement add st0')
   249          g1.local('gobgp policy statement st0 add condition prefix ps0')
   250          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   251          g1.local('gobgp policy statement st0 add action reject')
   252          g1.local('gobgp policy add policy0 st0')
   253          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   254  
   255          e1.add_route('192.168.2.0/24')
   256          e1.add_route('192.168.20.0/24')
   257          e1.add_route('192.168.200.0/24')
   258  
   259          for c in [e1, q1, q2]:
   260              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   261  
   262      @staticmethod
   263      def check(env):
   264          g1 = env.g1
   265          # e1 = env.e1
   266          q1 = env.q1
   267          q2 = env.q2
   268          wait_for(lambda: len(g1.get_local_rib(q1)) == 3)
   269          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3)
   270          wait_for(lambda: len(q1.get_global_rib()) == 3)
   271          wait_for(lambda: len(g1.get_local_rib(q2)) == 1)
   272          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1)
   273          wait_for(lambda: len(q2.get_global_rib()) == 1)
   274  
   275      @staticmethod
   276      def setup2(env):
   277          g1 = env.g1
   278          e1 = env.e1
   279          # q1 = env.q1
   280          # q2 = env.q2
   281  
   282          g1.local('gobgp policy prefix del ps0 192.168.200.0/24')
   283          g1.softreset(e1)
   284  
   285      @staticmethod
   286      def check2(env):
   287          g1 = env.g1
   288          # e1 = env.e1
   289          q1 = env.q1
   290          q2 = env.q2
   291          wait_for(lambda: len(g1.get_local_rib(q1)) == 3)
   292          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3)
   293          wait_for(lambda: len(q1.get_global_rib()) == 3)
   294          wait_for(lambda: len(g1.get_local_rib(q2)) == 2)
   295          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2)
   296          wait_for(lambda: len(q2.get_global_rib()) == 2)
   297  
   298      @staticmethod
   299      def executor(env):
   300          lookup_scenario("ImportPolicyUpdate").boot(env)
   301          lookup_scenario("ImportPolicyUpdate").setup(env)
   302          lookup_scenario("ImportPolicyUpdate").check(env)
   303          lookup_scenario("ImportPolicyUpdate").setup2(env)
   304          lookup_scenario("ImportPolicyUpdate").check2(env)
   305  
   306  
   307  @register_scenario
   308  class ExportPolicyUpdate(object):
   309      """
   310      No.4 export-policy update test
   311  
   312      r1:192.168.2.0
   313      r2:192.168.20.0
   314      r3:192.168.200.0
   315                        -------------------------------------------------
   316                        | q1                                            |
   317      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   318                        |                                               |
   319                        | q2                                            |
   320                        | ->(r1,r2,r3)-> rib ->(r1)->       adj-rib-out | ->(r1)-> q2
   321                        -------------------------------------------------
   322                   |
   323           update gobgp.conf
   324                   |
   325                   V
   326                        -------------------------------------------------
   327                        | q1                                            |
   328      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   329                        |                                               |
   330                        | q2                                            |
   331                        | ->(r1,r2,r3)-> rib ->(r1,r3)->    adj-rib-out | ->(r1,r3)-> q2
   332                        -------------------------------------------------
   333      """
   334      @staticmethod
   335      def boot(env):
   336          lookup_scenario("ImportPolicy").boot(env)
   337  
   338      @staticmethod
   339      def setup(env):
   340          g1 = env.g1
   341          e1 = env.e1
   342          q1 = env.q1
   343          q2 = env.q2
   344  
   345          g1.local('gobgp policy prefix add ps0 192.168.20.0/24')
   346          g1.local('gobgp policy prefix add ps0 192.168.200.0/24')
   347          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   348          g1.local('gobgp policy statement add st0')
   349          g1.local('gobgp policy statement st0 add condition prefix ps0')
   350          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   351          g1.local('gobgp policy statement st0 add action reject')
   352          g1.local('gobgp policy add policy0 st0')
   353          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   354  
   355          e1.add_route('192.168.2.0/24')
   356          e1.add_route('192.168.20.0/24')
   357          e1.add_route('192.168.200.0/24')
   358  
   359          for c in [e1, q1, q2]:
   360              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   361  
   362      @staticmethod
   363      def check(env):
   364          g1 = env.g1
   365          # e1 = env.e1
   366          q1 = env.q1
   367          q2 = env.q2
   368          wait_for(lambda: len(g1.get_local_rib(q1)) == 3)
   369          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3)
   370          wait_for(lambda: len(q1.get_global_rib()) == 3)
   371          wait_for(lambda: len(g1.get_local_rib(q2)) == 3)
   372          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1)
   373          wait_for(lambda: len(q2.get_global_rib()) == 1)
   374  
   375      @staticmethod
   376      def setup2(env):
   377          g1 = env.g1
   378          e1 = env.e1
   379          q1 = env.q1
   380          q2 = env.q2
   381  
   382          g1.local('gobgp policy prefix del ps0 192.168.200.0/24')
   383          # we need hard reset to flush q2's local rib
   384          g1.reset(e1)
   385  
   386          for c in [e1, q1, q2]:
   387              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   388  
   389      @staticmethod
   390      def check2(env):
   391          g1 = env.g1
   392          # e1 = env.e1
   393          q1 = env.q1
   394          q2 = env.q2
   395          wait_for(lambda: len(g1.get_local_rib(q1)) == 3)
   396          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3)
   397          wait_for(lambda: len(q1.get_global_rib()) == 3)
   398          wait_for(lambda: len(g1.get_local_rib(q2)) == 3)
   399          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2)
   400          wait_for(lambda: len(q2.get_global_rib()) == 2)
   401  
   402      @staticmethod
   403      def executor(env):
   404          lookup_scenario("ExportPolicyUpdate").boot(env)
   405          lookup_scenario("ExportPolicyUpdate").setup(env)
   406          lookup_scenario("ExportPolicyUpdate").check(env)
   407          lookup_scenario("ExportPolicyUpdate").setup2(env)
   408          lookup_scenario("ExportPolicyUpdate").check2(env)
   409  
   410  
   411  @register_scenario
   412  class ExportPolicyUpdateRouteRefresh(object):
   413      """
   414      export-policy update and route refresh handling test
   415  
   416      r1:192.168.2.0
   417      r2:192.168.20.0
   418      r3:192.168.200.0
   419                        -------------------------------------------------
   420                        | q1                                            |
   421      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   422                        |                                               |
   423                        | q2                                            |
   424                        | ->(r1,r2,r3)-> rib ->(r1)->       adj-rib-out | ->(r1)-> q2
   425                        -------------------------------------------------
   426                   |
   427           update gobgp.conf
   428           q2 sends route refresh
   429                   |
   430                   V
   431                        -------------------------------------------------
   432                        | q1                                            |
   433      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   434                        |                                               |
   435                        | q2                                            |
   436                        | ->(r1,r2,r3)-> rib ->(r1,r3)->    adj-rib-out | ->(r1,r3)-> q2
   437                        -------------------------------------------------
   438      """
   439      @staticmethod
   440      def boot(env):
   441          lookup_scenario("ExportPolicyUpdate").boot(env)
   442  
   443      @staticmethod
   444      def setup(env):
   445          lookup_scenario("ExportPolicyUpdate").setup(env)
   446  
   447      @staticmethod
   448      def check(env):
   449          lookup_scenario("ExportPolicyUpdate").check(env)
   450  
   451      @staticmethod
   452      def setup2(env):
   453          g1 = env.g1
   454          e1 = env.e1
   455          q1 = env.q1
   456          q2 = env.q2
   457  
   458          g1.local('gobgp policy prefix del ps0 192.168.200.0/24')
   459          q2.send_route_refresh()
   460  
   461          for c in [e1, q1, q2]:
   462              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   463  
   464      @staticmethod
   465      def check2(env):
   466          lookup_scenario("ExportPolicyUpdate").check2(env)
   467  
   468      @staticmethod
   469      def executor(env):
   470          lookup_scenario("ExportPolicyUpdateRouteRefresh").boot(env)
   471          lookup_scenario("ExportPolicyUpdateRouteRefresh").setup(env)
   472          lookup_scenario("ExportPolicyUpdateRouteRefresh").check(env)
   473          lookup_scenario("ExportPolicyUpdateRouteRefresh").setup2(env)
   474          lookup_scenario("ExportPolicyUpdateRouteRefresh").check2(env)
   475  
   476  
   477  @register_scenario
   478  class ImportPolicyIPV6(object):
   479      """
   480      No.5 IPv6 import-policy test
   481  
   482      r1=2001::/64
   483      r2=2001::/63
   484                     -------------------------------------------------
   485      e1 ->(r1,r2)-> | ->(r1,r2)-> q1-rib ->(r1,r2)-> q1-adj-rib-out | ->(r1,r2)-> q1
   486                     |                                               |
   487                     | ->(r2)   -> q2-rib ->(r2)   -> q2-adj-rib-out | ->(r2)-> q2
   488                     -------------------------------------------------
   489      """
   490      @staticmethod
   491      def boot(env):
   492          gobgp_ctn_image_name = env.parser_option.gobgp_image
   493          log_level = env.parser_option.gobgp_log_level
   494          g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
   495                              ctn_image_name=gobgp_ctn_image_name,
   496                              log_level=log_level)
   497          e1 = ExaBGPContainer(name='e1', asn=65001, router_id='192.168.0.2')
   498          q1 = QuaggaBGPContainer(name='q1', asn=65002, router_id='192.168.0.3')
   499          q2 = QuaggaBGPContainer(name='q2', asn=65003, router_id='192.168.0.4')
   500  
   501          ctns = [g1, e1, q1, q2]
   502          initial_wait_time = max(ctn.run() for ctn in ctns)
   503          time.sleep(initial_wait_time)
   504  
   505          br01 = Bridge(name='br01', subnet='2001::/96')
   506          [br01.addif(ctn) for ctn in ctns]
   507  
   508          for q in [e1, q1, q2]:
   509              g1.add_peer(q, is_rs_client=True, bridge=br01.name)
   510              q.add_peer(g1, bridge=br01.name)
   511  
   512              env.g1 = g1
   513              env.e1 = e1
   514              env.q1 = q1
   515              env.q2 = q2
   516  
   517      @staticmethod
   518      def setup(env):
   519          g1 = env.g1
   520          e1 = env.e1
   521          q1 = env.q1
   522          q2 = env.q2
   523  
   524          g1.local('gobgp policy prefix add ps0 2001::/32 64..128')
   525          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0]))
   526          g1.local('gobgp policy statement add st0')
   527          g1.local('gobgp policy statement st0 add condition prefix ps0')
   528          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   529          g1.local('gobgp policy statement st0 add action reject')
   530          g1.local('gobgp policy add policy0 st0')
   531          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   532  
   533          # this will be blocked
   534          e1.add_route('2001::/64', rf='ipv6')
   535          # this will pass
   536          e1.add_route('2001::/63', rf='ipv6')
   537  
   538          for c in [e1, q1, q2]:
   539              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   540  
   541      @staticmethod
   542      def check(env):
   543          wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 2)
   544          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 2)
   545          wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 2)
   546          wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 1)
   547          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1)
   548          wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1)
   549  
   550      @staticmethod
   551      def executor(env):
   552          lookup_scenario("ImportPolicyIPV6").boot(env)
   553          lookup_scenario("ImportPolicyIPV6").setup(env)
   554          lookup_scenario("ImportPolicyIPV6").check(env)
   555  
   556  
   557  @register_scenario
   558  class ExportPolicyIPV6(object):
   559      """
   560      No.6 IPv6 export-policy test
   561  
   562      r1=2001::/64
   563      r2=2001::/63
   564                     -------------------------------------------------
   565      e1 ->(r1,r2)-> | ->(r1,r2)-> q1-rib ->(r1,r2)-> q1-adj-rib-out | ->(r1,r2)-> q1
   566                     |                                               |
   567                     | ->(r1,r2)-> q2-rib ->(r2)   -> q2-adj-rib-out | ->(r2)-> q2
   568                     -------------------------------------------------
   569      """
   570      @staticmethod
   571      def boot(env):
   572          lookup_scenario('ImportPolicyIPV6').boot(env)
   573  
   574      @staticmethod
   575      def setup(env):
   576          g1 = env.g1
   577          e1 = env.e1
   578          q1 = env.q1
   579          q2 = env.q2
   580  
   581          g1.local('gobgp policy prefix add ps0 2001::/32 64..128')
   582          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   583          g1.local('gobgp policy statement add st0')
   584          g1.local('gobgp policy statement st0 add condition prefix ps0')
   585          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   586          g1.local('gobgp policy statement st0 add action reject')
   587          g1.local('gobgp policy add policy0 st0')
   588          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   589  
   590          # this will be blocked
   591          e1.add_route('2001::/64', rf='ipv6')
   592          # this will pass
   593          e1.add_route('2001::/63', rf='ipv6')
   594  
   595          for c in [e1, q1, q2]:
   596              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   597  
   598      @staticmethod
   599      def check(env):
   600          wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 2)
   601          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 2)
   602          wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 2)
   603          wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 2)
   604          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1)
   605          wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1)
   606  
   607      @staticmethod
   608      def executor(env):
   609          lookup_scenario("ExportPolicyIPV6").boot(env)
   610          lookup_scenario("ExportPolicyIPV6").setup(env)
   611          lookup_scenario("ExportPolicyIPV6").check(env)
   612  
   613  
   614  @register_scenario
   615  class ImportPolicyIPV6Update(object):
   616      """
   617      No.7 IPv6 import-policy update test
   618      r1=2001:0:10:2::/64
   619      r2=2001:0:10:20::/64
   620      r3=2001:0:10:200::/64
   621                        -------------------------------------------------
   622                        | q1                                            |
   623      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   624                        |                                               |
   625                        | q2                                            |
   626                        | ->(r1)->       rib ->(r1)->       adj-rib-out | ->(r1)-> q2
   627                        -------------------------------------------------
   628                   |
   629           update gobgp.conf
   630                   |
   631                   V
   632                        -------------------------------------------------
   633                        | q1                                            |
   634      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   635                        |                                               |
   636                        | q2                                            |
   637                        | ->(r1,r3)->    rib ->(r1,r3)->    adj-rib-out | ->(r1,r3)-> q2
   638                        -------------------------------------------------
   639      """
   640      @staticmethod
   641      def boot(env):
   642          lookup_scenario('ImportPolicyIPV6').boot(env)
   643  
   644      @staticmethod
   645      def setup(env):
   646          g1 = env.g1
   647          e1 = env.e1
   648          q1 = env.q1
   649          q2 = env.q2
   650  
   651          g1.local('gobgp policy prefix add ps0 2001:0:10:2::/64')
   652          g1.local('gobgp policy prefix add ps0 2001:0:10:20::/64')
   653          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0]))
   654          g1.local('gobgp policy statement add st0')
   655          g1.local('gobgp policy statement st0 add condition prefix ps0')
   656          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   657          g1.local('gobgp policy statement st0 add action reject')
   658          g1.local('gobgp policy add policy0 st0')
   659          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   660  
   661          e1.add_route('2001:0:10:2::/64', rf='ipv6')
   662          e1.add_route('2001:0:10:20::/64', rf='ipv6')
   663          e1.add_route('2001:0:10:200::/64', rf='ipv6')
   664  
   665          for c in [e1, q1, q2]:
   666              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   667  
   668      @staticmethod
   669      def check(env):
   670          wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3)
   671          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3)
   672          wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3)
   673          wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 1)
   674          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1)
   675          wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1)
   676  
   677      @staticmethod
   678      def setup2(env):
   679          g1 = env.g1
   680          e1 = env.e1
   681          # q1 = env.q1
   682          # q2 = env.q2
   683  
   684          g1.local('gobgp policy prefix del ps0 2001:0:10:20::/64')
   685          g1.softreset(e1, rf='ipv6')
   686  
   687      @staticmethod
   688      def check2(env):
   689          wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3)
   690          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3)
   691          wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3)
   692          wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 2)
   693          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 2)
   694          wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 2)
   695  
   696      @staticmethod
   697      def executor(env):
   698          lookup_scenario("ImportPolicyIPV6Update").boot(env)
   699          lookup_scenario("ImportPolicyIPV6Update").setup(env)
   700          lookup_scenario("ImportPolicyIPV6Update").check(env)
   701          lookup_scenario("ImportPolicyIPV6Update").setup2(env)
   702          lookup_scenario("ImportPolicyIPV6Update").check2(env)
   703  
   704  
   705  @register_scenario
   706  class ExportPolicyIPv6Update(object):
   707      """
   708      No.8 IPv6 export-policy update test
   709      r1=2001:0:10:2::/64
   710      r2=2001:0:10:20::/64
   711      r3=2001:0:10:200::/64
   712                        -------------------------------------------------
   713                        | q1                                            |
   714      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   715                        |                                               |
   716                        | q2                                            |
   717                        | ->(r1,r2,r3)-> rib ->(r1)->       adj-rib-out | ->(r1)-> q2
   718                        -------------------------------------------------
   719                   |
   720           update gobgp.conf
   721                   |
   722                   V
   723                        -------------------------------------------------
   724                        | q1                                            |
   725      e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1
   726                        |                                               |
   727                        | q2                                            |
   728                        | ->(r1,r2,r3)-> rib ->(r1,r3)->    adj-rib-out | ->(r1,r3)-> q2
   729                        -------------------------------------------------
   730      """
   731      @staticmethod
   732      def boot(env):
   733          lookup_scenario('ImportPolicyIPV6').boot(env)
   734  
   735      @staticmethod
   736      def setup(env):
   737          g1 = env.g1
   738          e1 = env.e1
   739          q1 = env.q1
   740          q2 = env.q2
   741  
   742          g1.local('gobgp policy prefix add ps0 2001:0:10:2::/64')
   743          g1.local('gobgp policy prefix add ps0 2001:0:10:20::/64')
   744          g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   745          g1.local('gobgp policy statement add st0')
   746          g1.local('gobgp policy statement st0 add condition prefix ps0')
   747          g1.local('gobgp policy statement st0 add condition neighbor ns0')
   748          g1.local('gobgp policy statement st0 add action reject')
   749          g1.local('gobgp policy add policy0 st0')
   750          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   751  
   752          e1.add_route('2001:0:10:2::/64', rf='ipv6')
   753          e1.add_route('2001:0:10:20::/64', rf='ipv6')
   754          e1.add_route('2001:0:10:200::/64', rf='ipv6')
   755  
   756          for c in [e1, q1, q2]:
   757              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   758  
   759      @staticmethod
   760      def check(env):
   761          wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3)
   762          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3)
   763          wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3)
   764          wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 3)
   765          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1)
   766          wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1)
   767  
   768      @staticmethod
   769      def setup2(env):
   770          g1 = env.g1
   771          e1 = env.e1
   772          q1 = env.q1
   773          q2 = env.q2
   774  
   775          g1.local('gobgp policy prefix del ps0 2001:0:10:20::/64')
   776          g1.reset(e1)
   777  
   778          for c in [e1, q1, q2]:
   779              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   780  
   781      @staticmethod
   782      def check2(env):
   783          wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3)
   784          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3)
   785          wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3)
   786          wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 3)
   787          wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 2)
   788          wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 2)
   789  
   790      @staticmethod
   791      def executor(env):
   792          lookup_scenario("ExportPolicyIPv6Update").boot(env)
   793          lookup_scenario("ExportPolicyIPv6Update").setup(env)
   794          lookup_scenario("ExportPolicyIPv6Update").check(env)
   795          lookup_scenario("ExportPolicyIPv6Update").setup2(env)
   796          lookup_scenario("ExportPolicyIPv6Update").check2(env)
   797  
   798  
   799  @register_scenario
   800  class ImportPolicyAsPathLengthCondition(object):
   801      """
   802      No.9 aspath length condition import-policy test
   803                                --------------------------------
   804      e1 ->(aspath_length=10)-> | ->  q1-rib -> q1-adj-rib-out | --> q1
   805                                |                              |
   806                                | ->x q2-rib                   |
   807                                --------------------------------
   808      """
   809      @staticmethod
   810      def boot(env):
   811          lookup_scenario("ImportPolicy").boot(env)
   812  
   813      @staticmethod
   814      def setup(env):
   815          g1 = env.g1
   816          e1 = env.e1
   817          q1 = env.q1
   818          q2 = env.q2
   819  
   820          g1.local('gobgp policy statement add st0')
   821          g1.local('gobgp policy statement st0 add condition as-path-length 10 ge')
   822          g1.local('gobgp policy statement st0 add action reject')
   823          g1.local('gobgp policy add policy0 st0')
   824          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   825  
   826          # this will be blocked
   827          e1.add_route('192.168.100.0/24', aspath=list(range(e1.asn, e1.asn - 10, -1)))
   828          # this will pass
   829          e1.add_route('192.168.200.0/24', aspath=list(range(e1.asn, e1.asn - 8, -1)))
   830  
   831          for c in [e1, q1, q2]:
   832              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   833  
   834      @staticmethod
   835      def check(env):
   836          g1 = env.g1
   837          # e1 = env.e1
   838          q1 = env.q1
   839          q2 = env.q2
   840          wait_for(lambda: len(g1.get_local_rib(q1)) == 2)
   841          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2)
   842          wait_for(lambda: len(q1.get_global_rib()) == 2)
   843          wait_for(lambda: len(g1.get_local_rib(q2)) == 1)
   844          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1)
   845          wait_for(lambda: len(q2.get_global_rib()) == 1)
   846  
   847      @staticmethod
   848      def executor(env):
   849          lookup_scenario("ImportPolicyAsPathLengthCondition").boot(env)
   850          lookup_scenario("ImportPolicyAsPathLengthCondition").setup(env)
   851          lookup_scenario("ImportPolicyAsPathLengthCondition").check(env)
   852  
   853  
   854  @register_scenario
   855  class ImportPolicyAsPathCondition(object):
   856      """
   857      No.10 aspath from condition import-policy test
   858                                  --------------------------------
   859      e1 ->(aspath=[65100,...])-> | ->  q1-rib -> q1-adj-rib-out | --> q1
   860                                  |                              |
   861                                  | ->x q2-rib                   |
   862                                  --------------------------------
   863      """
   864      @staticmethod
   865      def boot(env):
   866          lookup_scenario("ImportPolicy").boot(env)
   867  
   868      @staticmethod
   869      def setup(env):
   870          g1 = env.g1
   871          e1 = env.e1
   872          q1 = env.q1
   873          q2 = env.q2
   874  
   875          g1.local('gobgp policy as-path add as0 ^{0}'.format(e1.asn))
   876          g1.local('gobgp policy statement add st0')
   877          g1.local('gobgp policy statement st0 add condition as-path as0')
   878          g1.local('gobgp policy statement st0 add action reject')
   879          g1.local('gobgp policy add policy0 st0')
   880          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   881  
   882          # this will be blocked
   883          e1.add_route('192.168.100.0/24', aspath=list(range(e1.asn, e1.asn - 10, -1)))
   884          # this will pass
   885          e1.add_route('192.168.200.0/24', aspath=list(range(e1.asn - 1, e1.asn - 10, -1)))
   886  
   887          for c in [e1, q1, q2]:
   888              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   889  
   890      @staticmethod
   891      def check(env):
   892          # same check function as previous No.1 scenario
   893          lookup_scenario("ImportPolicy").check(env)
   894  
   895      @staticmethod
   896      def executor(env):
   897          lookup_scenario("ImportPolicyAsPathCondition").boot(env)
   898          lookup_scenario("ImportPolicyAsPathCondition").setup(env)
   899          lookup_scenario("ImportPolicyAsPathCondition").check(env)
   900  
   901  
   902  @register_scenario
   903  class ImportPolicyAsPathAnyCondition(object):
   904      """
   905      No.11 aspath any condition import-policy test
   906                                     --------------------------------
   907      e1 ->(aspath=[...65098,...])-> | ->  q1-rib -> q1-adj-rib-out | --> q1
   908                                     |                              |
   909                                     | ->x q2-rib                   |
   910                                     --------------------------------
   911      """
   912      @staticmethod
   913      def boot(env):
   914          lookup_scenario("ImportPolicy").boot(env)
   915  
   916      @staticmethod
   917      def setup(env):
   918          g1 = env.g1
   919          e1 = env.e1
   920          q1 = env.q1
   921          q2 = env.q2
   922  
   923          g1.local('gobgp policy as-path add as0 65098')
   924          g1.local('gobgp policy statement add st0')
   925          g1.local('gobgp policy statement st0 add condition as-path as0')
   926          g1.local('gobgp policy statement st0 add action reject')
   927          g1.local('gobgp policy add policy0 st0')
   928          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   929  
   930          # this will be blocked
   931          e1.add_route('192.168.100.0/24', aspath=[65000, 65098, 65010])
   932          # this will pass
   933          e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010])
   934  
   935          for c in [e1, q1, q2]:
   936              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   937  
   938      @staticmethod
   939      def check(env):
   940          # same check function as previous No.1 scenario
   941          lookup_scenario("ImportPolicy").check(env)
   942  
   943      @staticmethod
   944      def executor(env):
   945          lookup_scenario("ImportPolicyAsPathAnyCondition").boot(env)
   946          lookup_scenario("ImportPolicyAsPathAnyCondition").setup(env)
   947          lookup_scenario("ImportPolicyAsPathAnyCondition").check(env)
   948  
   949  
   950  @register_scenario
   951  class ImportPolicyAsPathOriginCondition(object):
   952      """
   953      No.12 aspath origin condition import-policy test
   954                                  --------------------------------
   955      e1 ->(aspath=[...,65090])-> | ->  q1-rib -> q1-adj-rib-out | --> q1
   956                                  |                              |
   957                                  | ->x q2-rib                   |
   958                                  --------------------------------
   959      """
   960      @staticmethod
   961      def boot(env):
   962          lookup_scenario("ImportPolicy").boot(env)
   963  
   964      @staticmethod
   965      def setup(env):
   966          g1 = env.g1
   967          e1 = env.e1
   968          q1 = env.q1
   969          q2 = env.q2
   970  
   971          g1.local('gobgp policy as-path add as0 65090$')
   972          g1.local('gobgp policy statement add st0')
   973          g1.local('gobgp policy statement st0 add condition as-path as0')
   974          g1.local('gobgp policy statement st0 add action reject')
   975          g1.local('gobgp policy add policy0 st0')
   976          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
   977  
   978          # this will be blocked
   979          e1.add_route('192.168.100.0/24', aspath=[65000, 65098, 65090])
   980          # this will pass
   981          e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010])
   982  
   983          for c in [e1, q1, q2]:
   984              g1.wait_for(BGP_FSM_ESTABLISHED, c)
   985  
   986      @staticmethod
   987      def check(env):
   988          # same check function as previous No.1 scenario
   989          lookup_scenario("ImportPolicy").check(env)
   990  
   991      @staticmethod
   992      def executor(env):
   993          lookup_scenario("ImportPolicyAsPathOriginCondition").boot(env)
   994          lookup_scenario("ImportPolicyAsPathOriginCondition").setup(env)
   995          lookup_scenario("ImportPolicyAsPathOriginCondition").check(env)
   996  
   997  
   998  @register_scenario
   999  class ImportPolicyAsPathOnlyCondition(object):
  1000      """
  1001      No.13 aspath only condition import-policy test
  1002                                --------------------------------
  1003      e1 -> (aspath=[65100]) -> | ->  q1-rib -> q1-adj-rib-out | --> q1
  1004                                |                              |
  1005                                | ->x q2-rib                   |
  1006                                --------------------------------
  1007      """
  1008      @staticmethod
  1009      def boot(env):
  1010          lookup_scenario("ImportPolicy").boot(env)
  1011  
  1012      @staticmethod
  1013      def setup(env):
  1014          g1 = env.g1
  1015          e1 = env.e1
  1016          q1 = env.q1
  1017          q2 = env.q2
  1018  
  1019          g1.local('gobgp policy as-path add as0 ^65100$')
  1020          g1.local('gobgp policy statement add st0')
  1021          g1.local('gobgp policy statement st0 add condition as-path as0')
  1022          g1.local('gobgp policy statement st0 add action reject')
  1023          g1.local('gobgp policy add policy0 st0')
  1024          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1025  
  1026          # this will be blocked
  1027          e1.add_route('192.168.100.0/24', aspath=[65100])
  1028          # this will pass
  1029          e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010])
  1030  
  1031          for c in [e1, q1, q2]:
  1032              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1033  
  1034      @staticmethod
  1035      def check(env):
  1036          # same check function as previous No.1 scenario
  1037          lookup_scenario("ImportPolicy").check(env)
  1038  
  1039      @staticmethod
  1040      def executor(env):
  1041          lookup_scenario("ImportPolicyAsPathOnlyCondition").boot(env)
  1042          lookup_scenario("ImportPolicyAsPathOnlyCondition").setup(env)
  1043          lookup_scenario("ImportPolicyAsPathOnlyCondition").check(env)
  1044  
  1045  
  1046  @register_scenario
  1047  class ImportPolicyAsPathMismatchCondition(object):
  1048      """
  1049      No.14 aspath condition mismatch import-policy test
  1050                                     -------------------------------
  1051      exabgp ->(aspath=[...,65090])->| -> q1-rib -> q1-adj-rib-out | --> q1
  1052                                     |                             |
  1053                                     | -> q2-rib -> q2-adj-rib-out | --> q2
  1054                                     -------------------------------
  1055      This case check if policy passes the path to e1 because of condition mismatch.
  1056      """
  1057      @staticmethod
  1058      def boot(env):
  1059          lookup_scenario("ImportPolicy").boot(env)
  1060  
  1061      @staticmethod
  1062      def setup(env):
  1063          g1 = env.g1
  1064          e1 = env.e1
  1065          q1 = env.q1
  1066          q2 = env.q2
  1067  
  1068          g1.local('gobgp policy community add cs0 65100:10')
  1069          g1.local('gobgp policy statement add st0')
  1070          g1.local('gobgp policy statement st0 add condition community cs0')
  1071          g1.local('gobgp policy statement st0 add action reject')
  1072          g1.local('gobgp policy add policy0 st0')
  1073          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1074  
  1075          # this will be blocked
  1076          e1.add_route('192.168.100.0/24', aspath=[65100, 65090])
  1077          # this will pass
  1078          e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010])
  1079  
  1080          for c in [e1, q1, q2]:
  1081              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1082  
  1083      @staticmethod
  1084      def check(env):
  1085          g1 = env.g1
  1086          # e1 = env.e1
  1087          q1 = env.q1
  1088          q2 = env.q2
  1089          wait_for(lambda: len(g1.get_local_rib(q1)) == 2)
  1090          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2)
  1091          wait_for(lambda: len(q1.get_global_rib()) == 2)
  1092          wait_for(lambda: len(g1.get_local_rib(q2)) == 2)
  1093          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2)
  1094          wait_for(lambda: len(q2.get_global_rib()) == 2)
  1095  
  1096      @staticmethod
  1097      def executor(env):
  1098          lookup_scenario("ImportPolicyAsPathMismatchCondition").boot(env)
  1099          lookup_scenario("ImportPolicyAsPathMismatchCondition").setup(env)
  1100          lookup_scenario("ImportPolicyAsPathMismatchCondition").check(env)
  1101  
  1102  
  1103  @register_scenario
  1104  class ImportPolicyCommunityCondition(object):
  1105      """
  1106      No.15 community condition import-policy test
  1107                                  --------------------------------
  1108      e1 ->(community=65100:10)-> | ->  q1-rib -> q1-adj-rib-out | --> q1
  1109                                  |                              |
  1110                                  | ->x q2-rib                   |
  1111                                  --------------------------------
  1112      """
  1113      @staticmethod
  1114      def boot(env):
  1115          lookup_scenario("ImportPolicy").boot(env)
  1116  
  1117      @staticmethod
  1118      def setup(env):
  1119          g1 = env.g1
  1120          e1 = env.e1
  1121          q1 = env.q1
  1122          q2 = env.q2
  1123  
  1124          g1.local('gobgp policy community add cs0 65100:10')
  1125          g1.local('gobgp policy statement add st0')
  1126          g1.local('gobgp policy statement st0 add condition community cs0')
  1127          g1.local('gobgp policy statement st0 add action reject')
  1128          g1.local('gobgp policy add policy0 st0')
  1129          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1130  
  1131          # this will be blocked
  1132          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1133          # this will pass
  1134          e1.add_route('192.168.200.0/24', community=['65100:20'])
  1135  
  1136          for c in [e1, q1, q2]:
  1137              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1138  
  1139      @staticmethod
  1140      def check(env):
  1141          lookup_scenario("ImportPolicy").check(env)
  1142  
  1143      @staticmethod
  1144      def executor(env):
  1145          lookup_scenario("ImportPolicyCommunityCondition").boot(env)
  1146          lookup_scenario("ImportPolicyCommunityCondition").setup(env)
  1147          lookup_scenario("ImportPolicyCommunityCondition").check(env)
  1148  
  1149  
  1150  @register_scenario
  1151  class ImportPolicyCommunityRegexp(object):
  1152      """
  1153      No.16 community condition regexp import-policy test
  1154                                  --------------------------------
  1155      e1 ->(community=65100:10)-> | ->  q1-rib -> q1-adj-rib-out | --> q1
  1156                                  |                              |
  1157                                  | ->x q2-rib                   |
  1158                                  --------------------------------
  1159      """
  1160      @staticmethod
  1161      def boot(env):
  1162          lookup_scenario("ImportPolicy").boot(env)
  1163  
  1164      @staticmethod
  1165      def setup(env):
  1166          g1 = env.g1
  1167          e1 = env.e1
  1168          q1 = env.q1
  1169          q2 = env.q2
  1170          g1.local('gobgp policy community add cs0 6[0-9]+:[0-9]+')
  1171          g1.local('gobgp policy statement add st0')
  1172          g1.local('gobgp policy statement st0 add condition community cs0')
  1173          g1.local('gobgp policy statement st0 add action reject')
  1174          g1.local('gobgp policy add policy0 st0')
  1175          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1176  
  1177          # this will be blocked
  1178          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1179          # this will pass
  1180          e1.add_route('192.168.200.0/24', community=['55100:20'])
  1181  
  1182          for c in [e1, q1, q2]:
  1183              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1184  
  1185      @staticmethod
  1186      def check(env):
  1187          lookup_scenario("ImportPolicy").check(env)
  1188  
  1189      @staticmethod
  1190      def executor(env):
  1191          lookup_scenario("ImportPolicyCommunityRegexp").boot(env)
  1192          lookup_scenario("ImportPolicyCommunityRegexp").setup(env)
  1193          lookup_scenario("ImportPolicyCommunityRegexp").check(env)
  1194  
  1195  
  1196  def community_exists(path, com):
  1197      a, b = com.split(':')
  1198      com = (int(a) << 16) + int(b)
  1199      for a in path['attrs']:
  1200          if a['type'] == BGP_ATTR_TYPE_COMMUNITIES and com in a['communities']:
  1201              return True
  1202      return False
  1203  
  1204  
  1205  @register_scenario
  1206  class ImportPolicyCommunityAction(object):
  1207      """
  1208      No.17 community add action import-policy test
  1209                                  -------------------------------
  1210      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)->          q1
  1211                                  |                             |
  1212                                  | -> q2-rib -> q2-adj-rib-out | ->(community=65100:10,65100:20)-> q2
  1213                                  |    apply action             |
  1214                                  -------------------------------
  1215      """
  1216      @staticmethod
  1217      def boot(env):
  1218          lookup_scenario("ImportPolicy").boot(env)
  1219  
  1220      @staticmethod
  1221      def setup(env):
  1222          g1 = env.g1
  1223          e1 = env.e1
  1224          q1 = env.q1
  1225          q2 = env.q2
  1226          g1.local('gobgp policy community add cs0 65100:10')
  1227          g1.local('gobgp policy statement add st0')
  1228          g1.local('gobgp policy statement st0 add condition community cs0')
  1229          g1.local('gobgp policy statement st0 add action accept')
  1230          g1.local('gobgp policy statement st0 add action community add 65100:20')
  1231          g1.local('gobgp policy add policy0 st0')
  1232          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1233  
  1234          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1235  
  1236          for c in [e1, q1, q2]:
  1237              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1238  
  1239      @staticmethod
  1240      def check(env):
  1241          g1 = env.g1
  1242          # e1 = env.e1
  1243          q1 = env.q1
  1244          q2 = env.q2
  1245          wait_for(lambda: len(g1.get_local_rib(q1)) == 1)
  1246          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1)
  1247          wait_for(lambda: len(q1.get_global_rib()) == 1)
  1248          wait_for(lambda: len(g1.get_local_rib(q2)) == 1)
  1249          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1)
  1250          wait_for(lambda: len(q2.get_global_rib()) == 1)
  1251  
  1252      @staticmethod
  1253      def check2(env):
  1254          g1 = env.g1
  1255          q1 = env.q1
  1256          q2 = env.q2
  1257          path = g1.get_adj_rib_out(q1)[0]
  1258          assert_true(community_exists(path, '65100:10'))
  1259          assert_false(community_exists(path, '65100:20'))
  1260          path = g1.get_adj_rib_out(q2)[0]
  1261          assert_true(community_exists(path, '65100:10'))
  1262          assert_true(community_exists(path, '65100:20'))
  1263  
  1264      @staticmethod
  1265      def executor(env):
  1266          lookup_scenario("ImportPolicyCommunityAction").boot(env)
  1267          lookup_scenario("ImportPolicyCommunityAction").setup(env)
  1268          lookup_scenario("ImportPolicyCommunityAction").check(env)
  1269          lookup_scenario("ImportPolicyCommunityAction").check2(env)
  1270  
  1271  
  1272  @register_scenario
  1273  class ImportPolicyCommunityReplace(object):
  1274      """
  1275      No.18 community replace action import-policy test
  1276                                  -------------------------------
  1277      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1278                                  |                             |
  1279                                  | -> q2-rib -> q2-adj-rib-out | ->(community=65100:20)-> q2
  1280                                  |    apply action             |
  1281                                  -------------------------------
  1282      """
  1283      @staticmethod
  1284      def boot(env):
  1285          lookup_scenario("ImportPolicy").boot(env)
  1286  
  1287      @staticmethod
  1288      def setup(env):
  1289          g1 = env.g1
  1290          e1 = env.e1
  1291          q1 = env.q1
  1292          q2 = env.q2
  1293  
  1294          g1.local('gobgp policy community add cs0 65100:10')
  1295          g1.local('gobgp policy statement add st0')
  1296          g1.local('gobgp policy statement st0 add condition community cs0')
  1297          g1.local('gobgp policy statement st0 add action accept')
  1298          g1.local('gobgp policy statement st0 add action community replace 65100:20')
  1299          g1.local('gobgp policy add policy0 st0')
  1300          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1301  
  1302          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1303  
  1304          for c in [e1, q1, q2]:
  1305              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1306  
  1307      @staticmethod
  1308      def check(env):
  1309          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1310  
  1311      @staticmethod
  1312      def check2(env):
  1313          g1 = env.g1
  1314          # e1 = env.e1
  1315          q1 = env.q1
  1316          q2 = env.q2
  1317          path = g1.get_adj_rib_out(q1)[0]
  1318          assert_true(community_exists(path, '65100:10'))
  1319          assert_false(community_exists(path, '65100:20'))
  1320          path = g1.get_adj_rib_out(q2)[0]
  1321          assert_false(community_exists(path, '65100:10'))
  1322          assert_true(community_exists(path, '65100:20'))
  1323  
  1324      @staticmethod
  1325      def executor(env):
  1326          lookup_scenario("ImportPolicyCommunityReplace").boot(env)
  1327          lookup_scenario("ImportPolicyCommunityReplace").setup(env)
  1328          lookup_scenario("ImportPolicyCommunityReplace").check(env)
  1329          lookup_scenario("ImportPolicyCommunityReplace").check2(env)
  1330  
  1331  
  1332  @register_scenario
  1333  class ImportPolicyCommunityRemove(object):
  1334      """
  1335      No.19 community remove action import-policy test
  1336                                  -------------------------------
  1337      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1338                                  |                             |
  1339                                  | -> q2-rib -> q2-adj-rib-out | ->(community=null)->     q2
  1340                                  |    apply action             |
  1341                                  -------------------------------
  1342      """
  1343      @staticmethod
  1344      def boot(env):
  1345          lookup_scenario("ImportPolicy").boot(env)
  1346  
  1347      @staticmethod
  1348      def setup(env):
  1349          g1 = env.g1
  1350          e1 = env.e1
  1351          q1 = env.q1
  1352          q2 = env.q2
  1353  
  1354          g1.local('gobgp policy community add cs0 65100:10')
  1355          g1.local('gobgp policy statement add st0')
  1356          g1.local('gobgp policy statement st0 add condition community cs0')
  1357          g1.local('gobgp policy statement st0 add action accept')
  1358          g1.local('gobgp policy statement st0 add action community remove 65100:10 65100:20')
  1359          g1.local('gobgp policy add policy0 st0')
  1360          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1361  
  1362          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1363          e1.add_route('192.168.110.0/24', community=['65100:10', '65100:20'])
  1364          e1.add_route('192.168.120.0/24', community=['65100:10', '65100:30'])
  1365  
  1366          for c in [e1, q1, q2]:
  1367              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1368  
  1369      @staticmethod
  1370      def check(env):
  1371          g1 = env.g1
  1372          # e1 = env.e1
  1373          q1 = env.q1
  1374          q2 = env.q2
  1375          wait_for(lambda: len(g1.get_local_rib(q1)) == 3)
  1376          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3)
  1377          wait_for(lambda: len(q1.get_global_rib()) == 3)
  1378          wait_for(lambda: len(g1.get_local_rib(q2)) == 3)
  1379          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 3)
  1380          wait_for(lambda: len(q2.get_global_rib()) == 3)
  1381  
  1382      @staticmethod
  1383      def check2(env):
  1384          g1 = env.g1
  1385          # e1 = env.e1
  1386          q1 = env.q1
  1387          q2 = env.q2
  1388          adj_out = g1.get_adj_rib_out(q1)
  1389          for path in adj_out:
  1390              assert_true(community_exists(path, '65100:10'))
  1391              if path['nlri']['prefix'] == '192.168.110.0/24':
  1392                  assert_true(community_exists(path, '65100:20'))
  1393              if path['nlri']['prefix'] == '192.168.120.0/24':
  1394                  assert_true(community_exists(path, '65100:30'))
  1395          adj_out = g1.get_adj_rib_out(q2)
  1396          for path in adj_out:
  1397              assert_false(community_exists(path, '65100:10'))
  1398              if path['nlri']['prefix'] == '192.168.110.0/24':
  1399                  assert_false(community_exists(path, '65100:20'))
  1400              if path['nlri']['prefix'] == '192.168.120.0/24':
  1401                  assert_true(community_exists(path, '65100:30'))
  1402  
  1403      @staticmethod
  1404      def executor(env):
  1405          lookup_scenario("ImportPolicyCommunityRemove").boot(env)
  1406          lookup_scenario("ImportPolicyCommunityRemove").setup(env)
  1407          lookup_scenario("ImportPolicyCommunityRemove").check(env)
  1408          lookup_scenario("ImportPolicyCommunityRemove").check2(env)
  1409  
  1410  
  1411  @register_scenario
  1412  class ImportPolicyCommunityNull(object):
  1413      """
  1414      No.20 community null action import-policy test
  1415                                  -------------------------------
  1416      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1417                                  |                             |
  1418                                  | -> q2-rib -> q2-adj-rib-out | ->(community=null)->     q2
  1419                                  |    apply action             |
  1420                                  -------------------------------
  1421      """
  1422      @staticmethod
  1423      def boot(env):
  1424          lookup_scenario("ImportPolicy").boot(env)
  1425  
  1426      @staticmethod
  1427      def setup(env):
  1428          g1 = env.g1
  1429          e1 = env.e1
  1430          q1 = env.q1
  1431          q2 = env.q2
  1432          g1.local('gobgp policy community add cs0 65100:10')
  1433          g1.local('gobgp policy statement add st0')
  1434          g1.local('gobgp policy statement st0 add condition community cs0')
  1435          g1.local('gobgp policy statement st0 add action accept')
  1436          g1.local('gobgp policy statement st0 add action community replace')
  1437          g1.local('gobgp policy add policy0 st0')
  1438          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1439  
  1440          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1441          e1.add_route('192.168.110.0/24', community=['65100:10', '65100:20'])
  1442          e1.add_route('192.168.120.0/24', community=['65100:10', '65100:30'])
  1443  
  1444          for c in [e1, q1, q2]:
  1445              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1446  
  1447      @staticmethod
  1448      def check(env):
  1449          lookup_scenario('ImportPolicyCommunityRemove').check(env)
  1450  
  1451      @staticmethod
  1452      def check2(env):
  1453          g1 = env.g1
  1454          q1 = env.q1
  1455          q2 = env.q2
  1456          adj_out = g1.get_adj_rib_out(q1)
  1457          for path in adj_out:
  1458              assert_true(community_exists(path, '65100:10'))
  1459              if path['nlri']['prefix'] == '192.168.110.0/24':
  1460                  assert_true(community_exists(path, '65100:20'))
  1461              if path['nlri']['prefix'] == '192.168.120.0/24':
  1462                  assert_true(community_exists(path, '65100:30'))
  1463          adj_out = g1.get_adj_rib_out(q2)
  1464          for path in adj_out:
  1465              assert_false(community_exists(path, '65100:10'))
  1466              if path['nlri']['prefix'] == '192.168.110.0/24':
  1467                  assert_false(community_exists(path, '65100:20'))
  1468              if path['nlri']['prefix'] == '192.168.120.0/24':
  1469                  assert_false(community_exists(path, '65100:30'))
  1470  
  1471      @staticmethod
  1472      def executor(env):
  1473          lookup_scenario("ImportPolicyCommunityNull").boot(env)
  1474          lookup_scenario("ImportPolicyCommunityNull").setup(env)
  1475          lookup_scenario("ImportPolicyCommunityNull").check(env)
  1476          lookup_scenario("ImportPolicyCommunityNull").check2(env)
  1477  
  1478  
  1479  @register_scenario
  1480  class ExportPolicyCommunityAdd(object):
  1481      """
  1482      No.21 community add action export-policy test
  1483                                  -------------------------------
  1484      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1485                                  |                             |
  1486                                  | -> q2-rib -> q2-adj-rib-out | ->(community=null)->     q2
  1487                                  |              apply action   |
  1488                                  -------------------------------
  1489      """
  1490      @staticmethod
  1491      def boot(env):
  1492          lookup_scenario('ImportPolicy').boot(env)
  1493  
  1494      @staticmethod
  1495      def setup(env):
  1496          g1 = env.g1
  1497          e1 = env.e1
  1498          q1 = env.q1
  1499          q2 = env.q2
  1500  
  1501          g1.local('gobgp policy community add cs0 65100:10')
  1502          g1.local('gobgp policy statement add st0')
  1503          g1.local('gobgp policy statement st0 add condition community cs0')
  1504          g1.local('gobgp policy statement st0 add action accept')
  1505          g1.local('gobgp policy statement st0 add action community add 65100:20')
  1506          g1.local('gobgp policy add policy0 st0')
  1507          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1508  
  1509          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1510  
  1511          for c in [e1, q1, q2]:
  1512              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1513  
  1514      @staticmethod
  1515      def check(env):
  1516          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1517  
  1518      @staticmethod
  1519      def check2(env):
  1520          g1 = env.g1
  1521          q1 = env.q1
  1522          q2 = env.q2
  1523  
  1524          adj_out = g1.get_adj_rib_out(q1)
  1525          for path in adj_out:
  1526              assert_true(community_exists(path, '65100:10'))
  1527              assert_false(community_exists(path, '65100:20'))
  1528  
  1529          local_rib = g1.get_local_rib(q2)
  1530          for path in local_rib[0]['paths']:
  1531              assert_true(community_exists(path, '65100:10'))
  1532              assert_false(community_exists(path, '65100:20'))
  1533  
  1534          adj_out = g1.get_adj_rib_out(q2)
  1535          for path in adj_out:
  1536              assert_true(community_exists(path, '65100:10'))
  1537              assert_true(community_exists(path, '65100:20'))
  1538  
  1539      @staticmethod
  1540      def executor(env):
  1541          lookup_scenario("ExportPolicyCommunityAdd").boot(env)
  1542          lookup_scenario("ExportPolicyCommunityAdd").setup(env)
  1543          lookup_scenario("ExportPolicyCommunityAdd").check(env)
  1544          lookup_scenario("ExportPolicyCommunityAdd").check2(env)
  1545  
  1546  
  1547  @register_scenario
  1548  class ExportPolicyCommunityReplace(object):
  1549      """
  1550      No.22 community replace action export-policy test
  1551                                  -------------------------------
  1552      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1553                                  |                             |
  1554                                  | -> q2-rib -> q2-adj-rib-out | ->(community=65100:20)-> q2
  1555                                  |              apply action   |
  1556                                  -------------------------------
  1557      """
  1558      @staticmethod
  1559      def boot(env):
  1560          lookup_scenario('ImportPolicy').boot(env)
  1561  
  1562      @staticmethod
  1563      def setup(env):
  1564          g1 = env.g1
  1565          e1 = env.e1
  1566          q1 = env.q1
  1567          q2 = env.q2
  1568  
  1569          g1.local('gobgp policy community add cs0 65100:10')
  1570          g1.local('gobgp policy statement add st0')
  1571          g1.local('gobgp policy statement st0 add condition community cs0')
  1572          g1.local('gobgp policy statement st0 add action accept')
  1573          g1.local('gobgp policy statement st0 add action community replace 65100:20')
  1574          g1.local('gobgp policy add policy0 st0')
  1575          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1576  
  1577          e1.add_route('192.168.100.0/24', community=['65100:10'])
  1578  
  1579          for c in [e1, q1, q2]:
  1580              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1581  
  1582      @staticmethod
  1583      def check(env):
  1584          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1585  
  1586      @staticmethod
  1587      def check2(env):
  1588          g1 = env.g1
  1589          q1 = env.q1
  1590          q2 = env.q2
  1591  
  1592          adj_out = g1.get_adj_rib_out(q1)
  1593          for path in adj_out:
  1594              assert_true(community_exists(path, '65100:10'))
  1595              assert_false(community_exists(path, '65100:20'))
  1596  
  1597          local_rib = g1.get_local_rib(q2)
  1598          for path in local_rib[0]['paths']:
  1599              assert_true(community_exists(path, '65100:10'))
  1600              assert_false(community_exists(path, '65100:20'))
  1601  
  1602          adj_out = g1.get_adj_rib_out(q2)
  1603          for path in adj_out:
  1604              assert_false(community_exists(path, '65100:10'))
  1605              assert_true(community_exists(path, '65100:20'))
  1606  
  1607      @staticmethod
  1608      def executor(env):
  1609          lookup_scenario("ExportPolicyCommunityReplace").boot(env)
  1610          lookup_scenario("ExportPolicyCommunityReplace").setup(env)
  1611          lookup_scenario("ExportPolicyCommunityReplace").check(env)
  1612          lookup_scenario("ExportPolicyCommunityReplace").check2(env)
  1613  
  1614  
  1615  @register_scenario
  1616  class ExportPolicyCommunityRemove(object):
  1617      """
  1618      No.23 community replace action export-policy test
  1619                                  -------------------------------
  1620      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1621                                  |                             |
  1622                                  | -> q2-rib -> q2-adj-rib-out | ->(community=null)->     q2
  1623                                  |              apply action   |
  1624                                  -------------------------------
  1625      """
  1626      @staticmethod
  1627      def boot(env):
  1628          lookup_scenario('ImportPolicy').boot(env)
  1629  
  1630      @staticmethod
  1631      def setup(env):
  1632          g1 = env.g1
  1633          e1 = env.e1
  1634          q1 = env.q1
  1635          q2 = env.q2
  1636  
  1637          g1.local('gobgp policy community add cs0 65100:10')
  1638          g1.local('gobgp policy statement add st0')
  1639          g1.local('gobgp policy statement st0 add condition community cs0')
  1640          g1.local('gobgp policy statement st0 add action accept')
  1641          g1.local('gobgp policy statement st0 add action community remove 65100:20 65100:30')
  1642          g1.local('gobgp policy add policy0 st0')
  1643          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1644  
  1645          e1.add_route('192.168.100.0/24', community=['65100:10', '65100:20', '65100:30'])
  1646  
  1647          for c in [e1, q1, q2]:
  1648              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1649  
  1650      @staticmethod
  1651      def check(env):
  1652          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1653  
  1654      @staticmethod
  1655      def check2(env):
  1656          g1 = env.g1
  1657          q1 = env.q1
  1658          q2 = env.q2
  1659  
  1660          adj_out = g1.get_adj_rib_out(q1)
  1661          for path in adj_out:
  1662              assert_true(community_exists(path, '65100:10'))
  1663              assert_true(community_exists(path, '65100:20'))
  1664              assert_true(community_exists(path, '65100:30'))
  1665  
  1666          local_rib = g1.get_local_rib(q2)
  1667          for path in local_rib[0]['paths']:
  1668              assert_true(community_exists(path, '65100:10'))
  1669              assert_true(community_exists(path, '65100:20'))
  1670              assert_true(community_exists(path, '65100:30'))
  1671  
  1672          adj_out = g1.get_adj_rib_out(q2)
  1673          for path in adj_out:
  1674              assert_true(community_exists(path, '65100:10'))
  1675              assert_false(community_exists(path, '65100:20'))
  1676              assert_false(community_exists(path, '65100:30'))
  1677  
  1678      @staticmethod
  1679      def executor(env):
  1680          lookup_scenario("ExportPolicyCommunityRemove").boot(env)
  1681          lookup_scenario("ExportPolicyCommunityRemove").setup(env)
  1682          lookup_scenario("ExportPolicyCommunityRemove").check(env)
  1683          lookup_scenario("ExportPolicyCommunityRemove").check2(env)
  1684  
  1685  
  1686  @register_scenario
  1687  class ExportPolicyCommunityNull(object):
  1688      """
  1689      No.24 community null action export-policy test
  1690                                  -------------------------------
  1691      e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1
  1692                                  |                             |
  1693                                  | -> q2-rib -> q2-adj-rib-out | ->(community=null)->     q2
  1694                                  |              apply action   |
  1695                                  -------------------------------
  1696      """
  1697      @staticmethod
  1698      def boot(env):
  1699          lookup_scenario('ImportPolicy').boot(env)
  1700  
  1701      @staticmethod
  1702      def setup(env):
  1703          g1 = env.g1
  1704          e1 = env.e1
  1705          q1 = env.q1
  1706          q2 = env.q2
  1707  
  1708          g1.local('gobgp policy community add cs0 65100:10')
  1709          g1.local('gobgp policy statement add st0')
  1710          g1.local('gobgp policy statement st0 add condition community cs0')
  1711          g1.local('gobgp policy statement st0 add action accept')
  1712          g1.local('gobgp policy statement st0 add action community replace')
  1713          g1.local('gobgp policy add policy0 st0')
  1714          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1715  
  1716          e1.add_route('192.168.100.0/24', community=['65100:10', '65100:20', '65100:30'])
  1717  
  1718          for c in [e1, q1, q2]:
  1719              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1720  
  1721      @staticmethod
  1722      def check(env):
  1723          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1724  
  1725      @staticmethod
  1726      def check2(env):
  1727          g1 = env.g1
  1728          q1 = env.q1
  1729          q2 = env.q2
  1730  
  1731          adj_out = g1.get_adj_rib_out(q1)
  1732          for path in adj_out:
  1733              assert_true(community_exists(path, '65100:10'))
  1734              assert_true(community_exists(path, '65100:20'))
  1735              assert_true(community_exists(path, '65100:30'))
  1736  
  1737          local_rib = g1.get_local_rib(q2)
  1738          for path in local_rib[0]['paths']:
  1739              assert_true(community_exists(path, '65100:10'))
  1740              assert_true(community_exists(path, '65100:20'))
  1741              assert_true(community_exists(path, '65100:30'))
  1742  
  1743          adj_out = g1.get_adj_rib_out(q2)
  1744          for path in adj_out:
  1745              assert_false(community_exists(path, '65100:10'))
  1746              assert_false(community_exists(path, '65100:20'))
  1747              assert_false(community_exists(path, '65100:30'))
  1748  
  1749      @staticmethod
  1750      def executor(env):
  1751          lookup_scenario("ExportPolicyCommunityNull").boot(env)
  1752          lookup_scenario("ExportPolicyCommunityNull").setup(env)
  1753          lookup_scenario("ExportPolicyCommunityNull").check(env)
  1754          lookup_scenario("ExportPolicyCommunityNull").check2(env)
  1755  
  1756  
  1757  def metric(path):
  1758      for a in path['attrs']:
  1759          if 'metric' in a:
  1760              return a['metric']
  1761      return -1
  1762  
  1763  
  1764  @register_scenario
  1765  class ImportPolicyMedReplace(object):
  1766      """
  1767      No.25 med replace action import-policy test
  1768                       -------------------------------
  1769      e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1
  1770                       |                             |
  1771                       | -> q2-rib -> q2-adj-rib-out | ->(med=100)-> q2
  1772                       |    apply action             |
  1773                       -------------------------------
  1774      """
  1775      @staticmethod
  1776      def boot(env):
  1777          lookup_scenario('ImportPolicy').boot(env)
  1778  
  1779      @staticmethod
  1780      def setup(env):
  1781          g1 = env.g1
  1782          e1 = env.e1
  1783          q1 = env.q1
  1784          q2 = env.q2
  1785  
  1786          g1.local('gobgp policy statement add st0')
  1787          g1.local('gobgp policy statement st0 add action accept')
  1788          g1.local('gobgp policy statement st0 add action med set 100')
  1789          g1.local('gobgp policy add policy0 st0')
  1790          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1791  
  1792          e1.add_route('192.168.100.0/24', med=300)
  1793  
  1794          for c in [e1, q1, q2]:
  1795              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1796  
  1797      @staticmethod
  1798      def check(env):
  1799          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1800  
  1801      @staticmethod
  1802      def check2(env):
  1803          g1 = env.g1
  1804          q1 = env.q1
  1805          q2 = env.q2
  1806  
  1807          adj_out = g1.get_adj_rib_out(q1)
  1808          assert_true(metric(adj_out[0]) == 300)
  1809  
  1810          local_rib = g1.get_local_rib(q2)
  1811          assert_true(metric(local_rib[0]['paths'][0]) == 100)
  1812  
  1813          adj_out = g1.get_adj_rib_out(q2)
  1814          assert_true(metric(adj_out[0]) == 100)
  1815  
  1816      @staticmethod
  1817      def executor(env):
  1818          lookup_scenario("ImportPolicyMedReplace").boot(env)
  1819          lookup_scenario("ImportPolicyMedReplace").setup(env)
  1820          lookup_scenario("ImportPolicyMedReplace").check(env)
  1821          lookup_scenario("ImportPolicyMedReplace").check2(env)
  1822  
  1823  
  1824  @register_scenario
  1825  class ImportPolicyMedAdd(object):
  1826      """
  1827      No.26 med add action import-policy test
  1828                       -------------------------------
  1829      e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)->     q1
  1830                       |                             |
  1831                       | -> q2-rib -> q2-adj-rib-out | ->(med=300+100)-> q2
  1832                       |    apply action             |
  1833                       -------------------------------
  1834      """
  1835      @staticmethod
  1836      def boot(env):
  1837          lookup_scenario('ImportPolicy').boot(env)
  1838  
  1839      @staticmethod
  1840      def setup(env):
  1841          g1 = env.g1
  1842          e1 = env.e1
  1843          q1 = env.q1
  1844          q2 = env.q2
  1845  
  1846          g1.local('gobgp policy statement add st0')
  1847          g1.local('gobgp policy statement st0 add action accept')
  1848          g1.local('gobgp policy statement st0 add action med add 100')
  1849          g1.local('gobgp policy add policy0 st0')
  1850          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1851  
  1852          e1.add_route('192.168.100.0/24', med=300)
  1853  
  1854          for c in [e1, q1, q2]:
  1855              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1856  
  1857      @staticmethod
  1858      def check(env):
  1859          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1860  
  1861      @staticmethod
  1862      def check2(env):
  1863          g1 = env.g1
  1864          q1 = env.q1
  1865          q2 = env.q2
  1866  
  1867          adj_out = g1.get_adj_rib_out(q1)
  1868          assert_true(metric(adj_out[0]) == 300)
  1869  
  1870          local_rib = g1.get_local_rib(q2)
  1871          assert_true(metric(local_rib[0]['paths'][0]) == 400)
  1872  
  1873          adj_out = g1.get_adj_rib_out(q2)
  1874          assert_true(metric(adj_out[0]) == 400)
  1875  
  1876      @staticmethod
  1877      def executor(env):
  1878          lookup_scenario("ImportPolicyMedAdd").boot(env)
  1879          lookup_scenario("ImportPolicyMedAdd").setup(env)
  1880          lookup_scenario("ImportPolicyMedAdd").check(env)
  1881          lookup_scenario("ImportPolicyMedAdd").check2(env)
  1882  
  1883  
  1884  @register_scenario
  1885  class ImportPolicyMedSub(object):
  1886      """
  1887      No.27 med subtract action import-policy test
  1888                       -------------------------------
  1889      e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)->     q1
  1890                       |                             |
  1891                       | -> q2-rib -> q2-adj-rib-out | ->(med=300-100)-> q2
  1892                       |    apply action             |
  1893                       -------------------------------
  1894      """
  1895      @staticmethod
  1896      def boot(env):
  1897          lookup_scenario('ImportPolicy').boot(env)
  1898  
  1899      @staticmethod
  1900      def setup(env):
  1901          g1 = env.g1
  1902          e1 = env.e1
  1903          q1 = env.q1
  1904          q2 = env.q2
  1905  
  1906          g1.local('gobgp policy statement add st0')
  1907          g1.local('gobgp policy statement st0 add action accept')
  1908          g1.local('gobgp policy statement st0 add action med sub 100')
  1909          g1.local('gobgp policy add policy0 st0')
  1910          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1911  
  1912          e1.add_route('192.168.100.0/24', med=300)
  1913  
  1914          for c in [e1, q1, q2]:
  1915              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1916  
  1917      @staticmethod
  1918      def check(env):
  1919          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1920  
  1921      @staticmethod
  1922      def check2(env):
  1923          g1 = env.g1
  1924          q1 = env.q1
  1925          q2 = env.q2
  1926  
  1927          adj_out = g1.get_adj_rib_out(q1)
  1928          assert_true(metric(adj_out[0]) == 300)
  1929  
  1930          local_rib = g1.get_local_rib(q2)
  1931          assert_true(metric(local_rib[0]['paths'][0]) == 200)
  1932  
  1933          adj_out = g1.get_adj_rib_out(q2)
  1934          assert_true(metric(adj_out[0]) == 200)
  1935  
  1936      @staticmethod
  1937      def executor(env):
  1938          lookup_scenario("ImportPolicyMedSub").boot(env)
  1939          lookup_scenario("ImportPolicyMedSub").setup(env)
  1940          lookup_scenario("ImportPolicyMedSub").check(env)
  1941          lookup_scenario("ImportPolicyMedSub").check2(env)
  1942  
  1943  
  1944  @register_scenario
  1945  class ExportPolicyMedReplace(object):
  1946      """
  1947      No.28 med replace action export-policy test
  1948                       -------------------------------
  1949      e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1
  1950                       |                             |
  1951                       | -> q2-rib -> q2-adj-rib-out | ->(med=100)-> q2
  1952                       |              apply action   |
  1953                       -------------------------------
  1954      """
  1955      @staticmethod
  1956      def boot(env):
  1957          lookup_scenario('ImportPolicy').boot(env)
  1958  
  1959      @staticmethod
  1960      def setup(env):
  1961          g1 = env.g1
  1962          e1 = env.e1
  1963          q1 = env.q1
  1964          q2 = env.q2
  1965  
  1966          g1.local('gobgp policy statement add st0')
  1967          g1.local('gobgp policy statement st0 add action accept')
  1968          g1.local('gobgp policy statement st0 add action med set 100')
  1969          g1.local('gobgp policy add policy0 st0')
  1970          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  1971  
  1972          e1.add_route('192.168.100.0/24', med=300)
  1973  
  1974          for c in [e1, q1, q2]:
  1975              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  1976  
  1977      @staticmethod
  1978      def check(env):
  1979          lookup_scenario('ImportPolicyCommunityAction').check(env)
  1980  
  1981      @staticmethod
  1982      def check2(env):
  1983          g1 = env.g1
  1984          q1 = env.q1
  1985          q2 = env.q2
  1986  
  1987          adj_out = g1.get_adj_rib_out(q1)
  1988          assert_true(metric(adj_out[0]) == 300)
  1989  
  1990          local_rib = g1.get_local_rib(q2)
  1991          assert_true(metric(local_rib[0]['paths'][0]) == 300)
  1992  
  1993          adj_out = g1.get_adj_rib_out(q2)
  1994          assert_true(metric(adj_out[0]) == 100)
  1995  
  1996      @staticmethod
  1997      def executor(env):
  1998          lookup_scenario("ExportPolicyMedReplace").boot(env)
  1999          lookup_scenario("ExportPolicyMedReplace").setup(env)
  2000          lookup_scenario("ExportPolicyMedReplace").check(env)
  2001          lookup_scenario("ExportPolicyMedReplace").check2(env)
  2002  
  2003  
  2004  @register_scenario
  2005  class ExportPolicyMedAdd(object):
  2006      """
  2007      No.29 med add action export-policy test
  2008                       -------------------------------
  2009      e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)->     q1
  2010                       |                             |
  2011                       | -> q2-rib -> q2-adj-rib-out | ->(med=300+100)-> q2
  2012                       |              apply action   |
  2013                       -------------------------------
  2014      """
  2015      @staticmethod
  2016      def boot(env):
  2017          lookup_scenario('ImportPolicy').boot(env)
  2018  
  2019      @staticmethod
  2020      def setup(env):
  2021          g1 = env.g1
  2022          e1 = env.e1
  2023          q1 = env.q1
  2024          q2 = env.q2
  2025  
  2026          g1.local('gobgp policy statement add st0')
  2027          g1.local('gobgp policy statement st0 add action accept')
  2028          g1.local('gobgp policy statement st0 add action med add 100')
  2029          g1.local('gobgp policy add policy0 st0')
  2030          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2031  
  2032          e1.add_route('192.168.100.0/24', med=300)
  2033  
  2034          for c in [e1, q1, q2]:
  2035              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2036  
  2037      @staticmethod
  2038      def check(env):
  2039          lookup_scenario('ImportPolicyCommunityAction').check(env)
  2040  
  2041      @staticmethod
  2042      def check2(env):
  2043          g1 = env.g1
  2044          q1 = env.q1
  2045          q2 = env.q2
  2046  
  2047          adj_out = g1.get_adj_rib_out(q1)
  2048          assert_true(metric(adj_out[0]) == 300)
  2049  
  2050          local_rib = g1.get_local_rib(q2)
  2051          assert_true(metric(local_rib[0]['paths'][0]) == 300)
  2052  
  2053          adj_out = g1.get_adj_rib_out(q2)
  2054          assert_true(metric(adj_out[0]) == 400)
  2055  
  2056      @staticmethod
  2057      def executor(env):
  2058          lookup_scenario("ExportPolicyMedAdd").boot(env)
  2059          lookup_scenario("ExportPolicyMedAdd").setup(env)
  2060          lookup_scenario("ExportPolicyMedAdd").check(env)
  2061          lookup_scenario("ExportPolicyMedAdd").check2(env)
  2062  
  2063  
  2064  @register_scenario
  2065  class ExportPolicyMedSub(object):
  2066      """
  2067      No.30 med subtract action export-policy test
  2068                       -------------------------------
  2069      e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)->     q1
  2070                       |                             |
  2071                       | -> q2-rib -> q2-adj-rib-out | ->(med=300-100)-> q2
  2072                       |              apply action   |
  2073                       -------------------------------
  2074      """
  2075      @staticmethod
  2076      def boot(env):
  2077          lookup_scenario('ImportPolicy').boot(env)
  2078  
  2079      @staticmethod
  2080      def setup(env):
  2081          g1 = env.g1
  2082          e1 = env.e1
  2083          q1 = env.q1
  2084          q2 = env.q2
  2085  
  2086          g1.local('gobgp policy statement add st0')
  2087          g1.local('gobgp policy statement st0 add action accept')
  2088          g1.local('gobgp policy statement st0 add action med sub 100')
  2089          g1.local('gobgp policy add policy0 st0')
  2090          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2091  
  2092          e1.add_route('192.168.100.0/24', med=300)
  2093  
  2094          for c in [e1, q1, q2]:
  2095              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2096  
  2097      @staticmethod
  2098      def check(env):
  2099          lookup_scenario('ImportPolicyCommunityAction').check(env)
  2100  
  2101      @staticmethod
  2102      def check2(env):
  2103          g1 = env.g1
  2104          q1 = env.q1
  2105          q2 = env.q2
  2106  
  2107          adj_out = g1.get_adj_rib_out(q1)
  2108          assert_true(metric(adj_out[0]) == 300)
  2109  
  2110          local_rib = g1.get_local_rib(q2)
  2111          assert_true(metric(local_rib[0]['paths'][0]) == 300)
  2112  
  2113          adj_out = g1.get_adj_rib_out(q2)
  2114          assert_true(metric(adj_out[0]) == 200)
  2115  
  2116      @staticmethod
  2117      def executor(env):
  2118          lookup_scenario("ExportPolicyMedSub").boot(env)
  2119          lookup_scenario("ExportPolicyMedSub").setup(env)
  2120          lookup_scenario("ExportPolicyMedSub").check(env)
  2121          lookup_scenario("ExportPolicyMedSub").check2(env)
  2122  
  2123  
  2124  @register_scenario
  2125  class ExportPolicyAsPathPrepend(object):
  2126      """
  2127      No.37 aspath prepend action export
  2128                              --------------------------------
  2129      e1 ->(aspath=[65001])-> | ->  p1-rib -> p1-adj-rib-out | -> p1
  2130                              |                              |
  2131                              | ->  p2-rib -> p2-adj-rib-out | -> p2
  2132                              |               apply action   |
  2133                              --------------------------------
  2134      """
  2135      @staticmethod
  2136      def boot(env):
  2137          lookup_scenario("ImportPolicy").boot(env)
  2138  
  2139      @staticmethod
  2140      def setup(env):
  2141          g1 = env.g1
  2142          e1 = env.e1
  2143          q1 = env.q1
  2144          q2 = env.q2
  2145  
  2146          g1.local('gobgp policy prefix add ps0 192.168.20.0/24')
  2147          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2148          g1.local('gobgp policy statement st0 add action accept')
  2149          g1.local('gobgp policy statement st0 add action as-prepend 65005 5')
  2150          g1.local('gobgp policy add policy0 st0')
  2151          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2152  
  2153          e1.add_route('192.168.20.0/24')
  2154          e1.add_route('192.168.200.0/24')
  2155  
  2156          for c in [e1, q1, q2]:
  2157              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2158  
  2159      @staticmethod
  2160      def check(env):
  2161          g1 = env.g1
  2162          e1 = env.e1
  2163          q1 = env.q1
  2164          q2 = env.q2
  2165          wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 2)
  2166          wait_for(lambda: len(g1.get_local_rib(q1)) == 2)
  2167          wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2)
  2168          wait_for(lambda: len(q1.get_global_rib()) == 2)
  2169          wait_for(lambda: len(g1.get_local_rib(q2)) == 2)
  2170          wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2)
  2171          wait_for(lambda: len(q2.get_global_rib()) == 2)
  2172  
  2173      @staticmethod
  2174      def check2(env):
  2175          g1 = env.g1
  2176          e1 = env.e1
  2177          q1 = env.q1
  2178          q2 = env.q2
  2179  
  2180          path = g1.get_adj_rib_out(q1, prefix='192.168.20.0/24')[0]
  2181          assert_true(path['aspath'] == [e1.asn])
  2182  
  2183          path = g1.get_adj_rib_out(q1, prefix='192.168.200.0/24')[0]
  2184          assert_true(path['aspath'] == [e1.asn])
  2185  
  2186          path = g1.get_local_rib(q2, prefix='192.168.20.0/24')[0]['paths'][0]
  2187          assert_true(path['aspath'] == [e1.asn])
  2188  
  2189          path = g1.get_adj_rib_out(q2, prefix='192.168.20.0/24')[0]
  2190          assert_true(path['aspath'] == ([65005] * 5) + [e1.asn])
  2191  
  2192          path = g1.get_adj_rib_out(q2, prefix='192.168.200.0/24')[0]
  2193          assert_true(path['aspath'] == [e1.asn])
  2194  
  2195      @staticmethod
  2196      def executor(env):
  2197          lookup_scenario("ExportPolicyAsPathPrepend").boot(env)
  2198          lookup_scenario("ExportPolicyAsPathPrepend").setup(env)
  2199          lookup_scenario("ExportPolicyAsPathPrepend").check(env)
  2200          lookup_scenario("ExportPolicyAsPathPrepend").check2(env)
  2201  
  2202  
  2203  @register_scenario
  2204  class ImportPolicyAsPathPrependLastAS(object):
  2205      """
  2206      No.38 aspath prepend action lastas import
  2207                              --------------------------------
  2208      e1 ->(aspath=[65001])-> | ->  p1-rib -> p1-adj-rib-out | -> p1
  2209                              |                              |
  2210                              | ->  p2-rib -> p2-adj-rib-out | -> p2
  2211                              |     apply action             |
  2212                              --------------------------------
  2213      """
  2214      @staticmethod
  2215      def boot(env):
  2216          lookup_scenario("ImportPolicy").boot(env)
  2217  
  2218      @staticmethod
  2219      def setup(env):
  2220          g1 = env.g1
  2221          e1 = env.e1
  2222          q1 = env.q1
  2223          q2 = env.q2
  2224  
  2225          g1.local('gobgp policy prefix add ps0 192.168.20.0/24')
  2226          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2227          g1.local('gobgp policy statement st0 add action accept')
  2228          g1.local('gobgp policy statement st0 add action as-prepend last-as 5')
  2229          g1.local('gobgp policy add policy0 st0')
  2230          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2231  
  2232          e1.add_route('192.168.20.0/24')
  2233          e1.add_route('192.168.200.0/24')
  2234  
  2235          for c in [e1, q1, q2]:
  2236              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2237  
  2238      @staticmethod
  2239      def check(env):
  2240          lookup_scenario('ExportPolicyAsPathPrepend').check(env)
  2241  
  2242      @staticmethod
  2243      def check2(env):
  2244          g1 = env.g1
  2245          e1 = env.e1
  2246          q1 = env.q1
  2247          q2 = env.q2
  2248  
  2249          path = g1.get_adj_rib_out(q1, prefix='192.168.20.0/24')[0]
  2250          assert_true(path['aspath'] == [e1.asn])
  2251  
  2252          path = g1.get_adj_rib_out(q1, prefix='192.168.200.0/24')[0]
  2253          assert_true(path['aspath'] == [e1.asn])
  2254  
  2255          path = g1.get_local_rib(q2, prefix='192.168.20.0/24')[0]['paths'][0]
  2256          assert_true(path['aspath'] == ([e1.asn] * 5) + [e1.asn])
  2257  
  2258          path = g1.get_adj_rib_out(q2, prefix='192.168.20.0/24')[0]
  2259          assert_true(path['aspath'] == ([e1.asn] * 5) + [e1.asn])
  2260  
  2261          path = g1.get_adj_rib_out(q2, prefix='192.168.200.0/24')[0]
  2262          assert_true(path['aspath'] == [e1.asn])
  2263  
  2264      @staticmethod
  2265      def executor(env):
  2266          lookup_scenario("ImportPolicyAsPathPrependLastAS").boot(env)
  2267          lookup_scenario("ImportPolicyAsPathPrependLastAS").setup(env)
  2268          lookup_scenario("ImportPolicyAsPathPrependLastAS").check(env)
  2269          lookup_scenario("ImportPolicyAsPathPrependLastAS").check2(env)
  2270  
  2271  
  2272  @register_scenario
  2273  class ExportPolicyAsPathPrependLastAS(object):
  2274      """
  2275      No.39 aspath prepend action lastas export
  2276                              --------------------------------
  2277      e1 ->(aspath=[65001])-> | ->  p1-rib -> p1-adj-rib-out | -> p1
  2278                              |                              |
  2279                              | ->  p2-rib -> p2-adj-rib-out | -> p2
  2280                              |     apply action             |
  2281                              --------------------------------
  2282      """
  2283      @staticmethod
  2284      def boot(env):
  2285          lookup_scenario("ImportPolicy").boot(env)
  2286  
  2287      @staticmethod
  2288      def setup(env):
  2289          g1 = env.g1
  2290          e1 = env.e1
  2291          q1 = env.q1
  2292          q2 = env.q2
  2293  
  2294          g1.local('gobgp policy prefix add ps0 192.168.20.0/24')
  2295          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2296          g1.local('gobgp policy statement st0 add action accept')
  2297          g1.local('gobgp policy statement st0 add action as-prepend last-as 5')
  2298          g1.local('gobgp policy add policy0 st0')
  2299          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2300  
  2301          e1.add_route('192.168.20.0/24')
  2302          e1.add_route('192.168.200.0/24')
  2303  
  2304          for c in [e1, q1, q2]:
  2305              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2306  
  2307      @staticmethod
  2308      def check(env):
  2309          lookup_scenario('ExportPolicyAsPathPrepend').check(env)
  2310  
  2311      @staticmethod
  2312      def check2(env):
  2313          g1 = env.g1
  2314          e1 = env.e1
  2315          q1 = env.q1
  2316          q2 = env.q2
  2317  
  2318          path = g1.get_adj_rib_out(q1, prefix='192.168.20.0/24')[0]
  2319          assert_true(path['aspath'] == [e1.asn])
  2320  
  2321          path = g1.get_adj_rib_out(q1, prefix='192.168.200.0/24')[0]
  2322          assert_true(path['aspath'] == [e1.asn])
  2323  
  2324          path = g1.get_local_rib(q2, prefix='192.168.20.0/24')[0]['paths'][0]
  2325          assert_true(path['aspath'] == [e1.asn])
  2326  
  2327          path = g1.get_adj_rib_out(q2, prefix='192.168.20.0/24')[0]
  2328          assert_true(path['aspath'] == ([e1.asn] * 5) + [e1.asn])
  2329  
  2330          path = g1.get_adj_rib_out(q2, prefix='192.168.200.0/24')[0]
  2331          assert_true(path['aspath'] == [e1.asn])
  2332  
  2333      @staticmethod
  2334      def executor(env):
  2335          lookup_scenario("ExportPolicyAsPathPrependLastAS").boot(env)
  2336          lookup_scenario("ExportPolicyAsPathPrependLastAS").setup(env)
  2337          lookup_scenario("ExportPolicyAsPathPrependLastAS").check(env)
  2338          lookup_scenario("ExportPolicyAsPathPrependLastAS").check2(env)
  2339  
  2340  
  2341  @register_scenario
  2342  class ImportPolicyExCommunityOriginCondition(object):
  2343      """
  2344      No.40 extended community origin condition import
  2345                                                   --------------------------------
  2346      e1 ->(extcommunity=origin:65001.65100:200)-> | ->  q1-rib -> q1-adj-rib-out | --> q1
  2347                                                   |                              |
  2348                                                   | ->x q2-rib                   |
  2349                                                   --------------------------------
  2350      """
  2351      @staticmethod
  2352      def boot(env):
  2353          lookup_scenario("ImportPolicy").boot(env)
  2354  
  2355      @staticmethod
  2356      def setup(env):
  2357          g1 = env.g1
  2358          e1 = env.e1
  2359          q1 = env.q1
  2360          q2 = env.q2
  2361  
  2362          g1.local('gobgp policy ext-community add es0 soo:65001.65100:200')
  2363          g1.local('gobgp policy statement st0 add condition ext-community es0')
  2364          g1.local('gobgp policy statement st0 add action reject')
  2365          g1.local('gobgp policy add policy0 st0')
  2366          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2367  
  2368          e1.add_route('192.168.20.0/24', extendedcommunity='origin:{0}:200'.format((65001 << 16) + 65100))
  2369          e1.add_route('192.168.200.0/24', extendedcommunity='origin:{0}:100'.format((65001 << 16) + 65200))
  2370  
  2371          for c in [e1, q1, q2]:
  2372              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2373  
  2374      @staticmethod
  2375      def check(env):
  2376          lookup_scenario("ImportPolicy").check(env)
  2377  
  2378      @staticmethod
  2379      def executor(env):
  2380          lookup_scenario("ImportPolicyExCommunityOriginCondition").boot(env)
  2381          lookup_scenario("ImportPolicyExCommunityOriginCondition").setup(env)
  2382          lookup_scenario("ImportPolicyExCommunityOriginCondition").check(env)
  2383  
  2384  
  2385  @register_scenario
  2386  class ImportPolicyExCommunityTargetCondition(object):
  2387      """
  2388      No.41 extended community origin condition import
  2389                                             --------------------------------
  2390      e1 ->(extcommunity=target:65010:320)-> | ->  q1-rib -> q1-adj-rib-out | --> q1
  2391                                             |                              |
  2392                                             | ->x q2-rib                   |
  2393                                             --------------------------------
  2394      """
  2395      @staticmethod
  2396      def boot(env):
  2397          lookup_scenario('ImportPolicy').boot(env)
  2398  
  2399      @staticmethod
  2400      def setup(env):
  2401          g1 = env.g1
  2402          e1 = env.e1
  2403          q1 = env.q1
  2404          q2 = env.q2
  2405  
  2406          g1.local('gobgp policy ext-community add es0 rt:6[0-9]+:3[0-9]+')
  2407          g1.local('gobgp policy statement st0 add condition ext-community es0')
  2408          g1.local('gobgp policy statement st0 add action reject')
  2409          g1.local('gobgp policy add policy0 st0')
  2410          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2411  
  2412          e1.add_route('192.168.20.0/24', extendedcommunity='target:65010:320')
  2413          e1.add_route('192.168.200.0/24', extendedcommunity='target:55000:320')
  2414  
  2415          for c in [e1, q1, q2]:
  2416              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2417  
  2418      @staticmethod
  2419      def check(env):
  2420          lookup_scenario("ImportPolicy").check(env)
  2421  
  2422      @staticmethod
  2423      def executor(env):
  2424          lookup_scenario("ImportPolicyExCommunityTargetCondition").boot(env)
  2425          lookup_scenario("ImportPolicyExCommunityTargetCondition").setup(env)
  2426          lookup_scenario("ImportPolicyExCommunityTargetCondition").check(env)
  2427  
  2428  
  2429  def ext_community_exists(path, extcomm):
  2430      typ = extcomm.split(':')[0]
  2431      value = ':'.join(extcomm.split(':')[1:])
  2432      for a in path['attrs']:
  2433          if a['type'] == BGP_ATTR_TYPE_EXTENDED_COMMUNITIES:
  2434              for c in a['value']:
  2435                  if typ == 'RT' and c['type'] == 0 and c['subtype'] == 2 and c['value'] == value:
  2436                      return True
  2437      return False
  2438  
  2439  
  2440  @register_scenario
  2441  class ImportPolicyExCommunityAdd(object):
  2442      """
  2443      No.43 extended community add action import-policy test
  2444                                 ---------------------------------
  2445      e1 ->(extcommunity=none) ->| ->  q1-rib ->  q1-adj-rib-out | --> q1
  2446                                 |                               |
  2447                                 | ->  q2-rib ->  q2-adj-rib-out | --> q2
  2448                                 |     add ext-community         |
  2449                                 ---------------------------------
  2450      """
  2451      @staticmethod
  2452      def boot(env):
  2453          lookup_scenario('ImportPolicy').boot(env)
  2454  
  2455      @staticmethod
  2456      def setup(env):
  2457          g1 = env.g1
  2458          e1 = env.e1
  2459          q1 = env.q1
  2460          q2 = env.q2
  2461  
  2462          g1.local('gobgp policy prefix add ps0 192.168.10.0/24')
  2463          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2464          g1.local('gobgp policy statement st0 add action accept')
  2465          g1.local('gobgp policy statement st0 add action ext-community add rt:65000:1')
  2466          g1.local('gobgp policy add policy0 st0')
  2467          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2468  
  2469          e1.add_route('192.168.10.0/24')
  2470  
  2471          for c in [e1, q1, q2]:
  2472              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2473  
  2474      @staticmethod
  2475      def check(env):
  2476          lookup_scenario('ImportPolicyCommunityAction').check(env)
  2477  
  2478      @staticmethod
  2479      def check2(env):
  2480          g1 = env.g1
  2481          # e1 = env.e1
  2482          q1 = env.q1
  2483          q2 = env.q2
  2484          path = g1.get_adj_rib_out(q1)[0]
  2485          assert_false(ext_community_exists(path, 'RT:65000:1'))
  2486          path = g1.get_adj_rib_out(q2)[0]
  2487          assert_true(ext_community_exists(path, 'RT:65000:1'))
  2488  
  2489      @staticmethod
  2490      def executor(env):
  2491          lookup_scenario("ImportPolicyExCommunityAdd").boot(env)
  2492          lookup_scenario("ImportPolicyExCommunityAdd").setup(env)
  2493          lookup_scenario("ImportPolicyExCommunityAdd").check(env)
  2494          lookup_scenario("ImportPolicyExCommunityAdd").check2(env)
  2495  
  2496  
  2497  @register_scenario
  2498  class ImportPolicyExCommunityAdd2(object):
  2499      """
  2500      No.44 extended community add action import-policy test
  2501                                        --------------------------------
  2502      e1 ->(extcommunity=RT:65000:1) -> | ->  q1-rib -> q1-adj-rib-out | --> q1
  2503                                        |                              |
  2504                                        | ->  q2-rib -> q2-adj-rib-out | --> q2
  2505                                        |     add ext-community        |
  2506                                        --------------------------------
  2507      """
  2508      @staticmethod
  2509      def boot(env):
  2510          lookup_scenario('ImportPolicy').boot(env)
  2511  
  2512      @staticmethod
  2513      def setup(env):
  2514          g1 = env.g1
  2515          e1 = env.e1
  2516          q1 = env.q1
  2517          q2 = env.q2
  2518  
  2519          g1.local('gobgp policy prefix add ps0 192.168.10.0/24')
  2520          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2521          g1.local('gobgp policy statement st0 add action accept')
  2522          g1.local('gobgp policy statement st0 add action ext-community add rt:65100:100')
  2523          g1.local('gobgp policy add policy0 st0')
  2524          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2525  
  2526          e1.add_route('192.168.10.0/24', extendedcommunity='target:65000:1')
  2527  
  2528          for c in [e1, q1, q2]:
  2529              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2530  
  2531      @staticmethod
  2532      def check(env):
  2533          lookup_scenario('ImportPolicyCommunityAction').check(env)
  2534  
  2535      @staticmethod
  2536      def check2(env):
  2537          g1 = env.g1
  2538          # e1 = env.e1
  2539          q1 = env.q1
  2540          q2 = env.q2
  2541          path = g1.get_adj_rib_out(q1)[0]
  2542          assert_true(ext_community_exists(path, 'RT:65000:1'))
  2543          assert_false(ext_community_exists(path, 'RT:65100:100'))
  2544          path = g1.get_local_rib(q2)[0]['paths'][0]
  2545          assert_true(ext_community_exists(path, 'RT:65000:1'))
  2546          assert_true(ext_community_exists(path, 'RT:65100:100'))
  2547          path = g1.get_adj_rib_out(q2)[0]
  2548          assert_true(ext_community_exists(path, 'RT:65000:1'))
  2549          assert_true(ext_community_exists(path, 'RT:65100:100'))
  2550  
  2551      @staticmethod
  2552      def executor(env):
  2553          lookup_scenario("ImportPolicyExCommunityAdd2").boot(env)
  2554          lookup_scenario("ImportPolicyExCommunityAdd2").setup(env)
  2555          lookup_scenario("ImportPolicyExCommunityAdd2").check(env)
  2556          lookup_scenario("ImportPolicyExCommunityAdd2").check2(env)
  2557  
  2558  
  2559  @register_scenario
  2560  class ImportPolicyExCommunityMultipleAdd(object):
  2561      """
  2562      No.45 extended community add action multiple import-policy test
  2563                                     ---------------------------------------
  2564      exabgp ->(extcommunity=none) ->| ->  peer1-rib ->  peer1-adj-rib-out | --> peer1
  2565                                     |                                     |
  2566                                     | ->  peer2-rib ->  peer2-adj-rib-out | --> peer2
  2567                                     |     add ext-community               |
  2568                                     ---------------------------------------
  2569      """
  2570      @staticmethod
  2571      def boot(env):
  2572          lookup_scenario('ImportPolicy').boot(env)
  2573  
  2574      @staticmethod
  2575      def setup(env):
  2576          g1 = env.g1
  2577          e1 = env.e1
  2578          q1 = env.q1
  2579          q2 = env.q2
  2580  
  2581          g1.local('gobgp policy prefix add ps0 192.168.10.0/24')
  2582          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2583          g1.local('gobgp policy statement st0 add action accept')
  2584          g1.local('gobgp policy statement st0 add action ext-community add rt:65100:100 rt:100:100')
  2585          g1.local('gobgp policy add policy0 st0')
  2586          g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2587  
  2588          e1.add_route('192.168.10.0/24')
  2589  
  2590          for c in [e1, q1, q2]:
  2591              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2592  
  2593      @staticmethod
  2594      def check(env):
  2595          lookup_scenario('ImportPolicyCommunityAction').check(env)
  2596  
  2597      @staticmethod
  2598      def check2(env):
  2599          g1 = env.g1
  2600          # e1 = env.e1
  2601          q1 = env.q1
  2602          q2 = env.q2
  2603          path = g1.get_adj_rib_out(q1)[0]
  2604          assert_false(ext_community_exists(path, 'RT:65100:100'))
  2605          assert_false(ext_community_exists(path, 'RT:100:100'))
  2606          path = g1.get_local_rib(q2)[0]['paths'][0]
  2607          assert_true(ext_community_exists(path, 'RT:65100:100'))
  2608          assert_true(ext_community_exists(path, 'RT:100:100'))
  2609          path = g1.get_adj_rib_out(q2)[0]
  2610          assert_true(ext_community_exists(path, 'RT:65100:100'))
  2611          assert_true(ext_community_exists(path, 'RT:100:100'))
  2612  
  2613      @staticmethod
  2614      def executor(env):
  2615          lookup_scenario("ImportPolicyExCommunityMultipleAdd").boot(env)
  2616          lookup_scenario("ImportPolicyExCommunityMultipleAdd").setup(env)
  2617          lookup_scenario("ImportPolicyExCommunityMultipleAdd").check(env)
  2618          lookup_scenario("ImportPolicyExCommunityMultipleAdd").check2(env)
  2619  
  2620  
  2621  @register_scenario
  2622  class ExportPolicyExCommunityAdd(object):
  2623      """
  2624      No.46 extended comunity add action export-policy test
  2625                                 ------------------------------------
  2626      e1 ->(extcommunity=none) ->| ->  q1-rib ->  q1-adj-rib-out    | --> q1
  2627                                 |                                  |
  2628                                 | ->  q2-rib ->  q2-adj-rib-out    | --> q2
  2629                                 |                add ext-community |
  2630                                 ------------------------------------
  2631      """
  2632      @staticmethod
  2633      def boot(env):
  2634          lookup_scenario('ImportPolicy').boot(env)
  2635  
  2636      @staticmethod
  2637      def setup(env):
  2638          g1 = env.g1
  2639          e1 = env.e1
  2640          q1 = env.q1
  2641          q2 = env.q2
  2642  
  2643          g1.local('gobgp policy prefix add ps0 192.168.10.0/24')
  2644          g1.local('gobgp policy statement st0 add condition prefix ps0')
  2645          g1.local('gobgp policy statement st0 add action accept')
  2646          g1.local('gobgp policy statement st0 add action ext-community add rt:65000:1')
  2647          g1.local('gobgp policy add policy0 st0')
  2648          g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0]))
  2649  
  2650          e1.add_route('192.168.10.0/24')
  2651  
  2652          for c in [e1, q1, q2]:
  2653              g1.wait_for(BGP_FSM_ESTABLISHED, c)
  2654  
  2655      @staticmethod
  2656      def check(env):
  2657          lookup_scenario('ImportPolicyCommunityAction').check(env)
  2658  
  2659      @staticmethod
  2660      def check2(env):
  2661          g1 = env.g1
  2662          # e1 = env.e1
  2663          q1 = env.q1
  2664          q2 = env.q2
  2665          path = g1.get_adj_rib_out(q1)[0]
  2666          assert_false(ext_community_exists(path, 'RT:65000:1'))
  2667          path = g1.get_local_rib(q2)[0]['paths'][0]
  2668          assert_false(ext_community_exists(path, 'RT:65000:1'))
  2669          path = g1.get_adj_rib_out(q2)[0]
  2670          assert_true(ext_community_exists(path, 'RT:65000:1'))
  2671  
  2672      @staticmethod
  2673      def executor(env):
  2674          lookup_scenario("ExportPolicyExCommunityAdd").boot(env)
  2675          lookup_scenario("ExportPolicyExCommunityAdd").setup(env)
  2676          lookup_scenario("ExportPolicyExCommunityAdd").check(env)
  2677          lookup_scenario("ExportPolicyExCommunityAdd").check2(env)
  2678  
  2679  
  2680  class TestGoBGPBase(unittest.TestCase):
  2681  
  2682      wait_per_retry = 5
  2683      retry_limit = 10
  2684  
  2685      @classmethod
  2686      def setUpClass(cls):
  2687          idx = parser_option.test_index
  2688          base.TEST_PREFIX = parser_option.test_prefix
  2689          cls.parser_option = parser_option
  2690          cls.executors = []
  2691          if idx == 0:
  2692              print('unset test-index. run all test sequential')
  2693              for _, v in list(_SCENARIOS.items()):
  2694                  for k, m in inspect.getmembers(v, inspect.isfunction):
  2695                      if k == 'executor':
  2696                          cls.executor = m
  2697                  cls.executors.append(cls.executor)
  2698          elif idx not in _SCENARIOS:
  2699              print('invalid test-index. # of scenarios: {0}'.format(len(_SCENARIOS)))
  2700              sys.exit(1)
  2701          else:
  2702              for k, m in inspect.getmembers(_SCENARIOS[idx], inspect.isfunction):
  2703                  if k == 'executor':
  2704                      cls.executor = m
  2705              cls.executors.append(cls.executor)
  2706  
  2707      def test(self):
  2708          for e in self.executors:
  2709              yield e
  2710  
  2711  
  2712  if __name__ == '__main__':
  2713      output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
  2714      if int(output) != 0:
  2715          print("docker not found")
  2716          sys.exit(1)
  2717  
  2718      nose.main(argv=sys.argv, addplugins=[OptionParser()],
  2719                defaultTest=sys.argv[0])