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