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