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

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