# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest from fabric.api import local from lib import base from lib.gobgp import * from lib.quagga import * from lib.exabgp import * import sys import os import time import nose import inspect from noseplugin import OptionParser, parser_option counter = 1 _SCENARIOS = {} def register_scenario(cls): global counter _SCENARIOS[counter] = cls counter += 1 def lookup_scenario(name): for value in _SCENARIOS.values(): if value.__name__ == name: return value return None def wait_for(f, timeout=120): interval = 1 count = 0 while True: if f(): return time.sleep(interval) count += interval if count >= timeout: raise Exception('timeout') @register_scenario class ImportPolicy(object): """ No.1 import-policy test -------------------------------- e1 ->(192.168.2.0/24)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): gobgp_ctn_image_name = env.parser_option.gobgp_image log_level = env.parser_option.gobgp_log_level g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1', ctn_image_name=gobgp_ctn_image_name, log_level=log_level) e1 = ExaBGPContainer(name='e1', asn=65001, router_id='192.168.0.2') q1 = QuaggaBGPContainer(name='q1', asn=65002, router_id='192.168.0.3') q2 = QuaggaBGPContainer(name='q2', asn=65003, router_id='192.168.0.4') ctns = [g1, e1, q1, q2] initial_wait_time = max(ctn.run() for ctn in ctns) time.sleep(initial_wait_time) for q in [e1, q1, q2]: g1.add_peer(q, is_rs_client=True) q.add_peer(g1) env.g1 = g1 env.e1 = e1 env.q1 = q1 env.q2 = q2 @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.0.0/16 16..24') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.2.0/24') # this will pass e1.add_route('192.168.2.0/15') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1)) == 2) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1)) == 2) wait_for(lambda: len(env.q1.get_global_rib()) == 2) wait_for(lambda: len(env.g1.get_local_rib(env.q2)) == 1) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2)) == 1) wait_for(lambda: len(env.q2.get_global_rib()) == 1) @register_scenario class ExportPolicy(object): """ No.2 export-policy test -------------------------------- e1 ->(192.168.2.0/24)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | -> q2-rib ->x q2-adj-rib-out | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.0.0/16 16..24') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.2.0/24') # this will pass e1.add_route('192.168.2.0/15') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) wait_for(lambda: len(q1.get_global_rib()) == 2) wait_for(lambda: len(g1.get_local_rib(q2)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @register_scenario class ImportPolicyUpdate(object): """ No.3 import-policy update test r1:192.168.2.0/24 r2:192.168.20.0/24 r3:192.168.200.0/24 ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 ------------------------------------------------- | update gobgp.conf | V ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.20.0/24') g1.local('gobgp policy prefix add ps0 192.168.200.0/24') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.2.0/24') e1.add_route('192.168.20.0/24') e1.add_route('192.168.200.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3) wait_for(lambda: len(q1.get_global_rib()) == 3) wait_for(lambda: len(g1.get_local_rib(q2)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @staticmethod def setup2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix del ps0 192.168.200.0/24') g1.softreset(e1) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3) wait_for(lambda: len(q1.get_global_rib()) == 3) wait_for(lambda: len(g1.get_local_rib(q2)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) wait_for(lambda: len(q2.get_global_rib()) == 2) @register_scenario class ExportPolicyUpdate(object): """ No.4 export-policy update test r1:192.168.2.0 r2:192.168.20.0 r3:192.168.200.0 ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r2,r3)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 ------------------------------------------------- | update gobgp.conf | V ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r2,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.20.0/24') g1.local('gobgp policy prefix add ps0 192.168.200.0/24') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.2.0/24') e1.add_route('192.168.20.0/24') e1.add_route('192.168.200.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3) wait_for(lambda: len(q1.get_global_rib()) == 3) wait_for(lambda: len(g1.get_local_rib(q2)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @staticmethod def setup2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix del ps0 192.168.200.0/24') # we need hard reset to flush q2's local rib g1.reset(e1) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3) wait_for(lambda: len(q1.get_global_rib()) == 3) wait_for(lambda: len(g1.get_local_rib(q2)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) wait_for(lambda: len(q2.get_global_rib()) == 2) @register_scenario class ExportPolicyUpdateRouteRefresh(object): """ export-policy update and route refresh handling test r1:192.168.2.0 r2:192.168.20.0 r3:192.168.200.0 ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r2,r3)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 ------------------------------------------------- | update gobgp.conf q2 sends route refresh | V ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r2,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): lookup_scenario("ExportPolicyUpdate").boot(env) @staticmethod def setup(env): lookup_scenario("ExportPolicyUpdate").setup(env) @staticmethod def check(env): lookup_scenario("ExportPolicyUpdate").check(env) @staticmethod def setup2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix del ps0 192.168.200.0/24') q2.send_route_refresh() for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check2(env): lookup_scenario("ExportPolicyUpdate").check2(env) @register_scenario class ImportPolicyIPV6(object): """ No.5 IPv6 import-policy test r1=2001::/64 r2=2001::/63 ------------------------------------------------- e1 ->(r1,r2)-> | ->(r1,r2)-> q1-rib ->(r1,r2)-> q1-adj-rib-out | ->(r1,r2)-> q1 | | | ->(r2) -> q2-rib ->(r2) -> q2-adj-rib-out | ->(r2)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): gobgp_ctn_image_name = env.parser_option.gobgp_image log_level = env.parser_option.gobgp_log_level g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1', ctn_image_name=gobgp_ctn_image_name, log_level=log_level) e1 = ExaBGPContainer(name='e1', asn=65001, router_id='192.168.0.2') q1 = QuaggaBGPContainer(name='q1', asn=65002, router_id='192.168.0.3') q2 = QuaggaBGPContainer(name='q2', asn=65003, router_id='192.168.0.4') ctns = [g1, e1, q1, q2] initial_wait_time = max(ctn.run() for ctn in ctns) time.sleep(initial_wait_time) br01 = Bridge(name='br01', subnet='2001::/96') [br01.addif(ctn) for ctn in ctns] for q in [e1, q1, q2]: g1.add_peer(q, is_rs_client=True, bridge=br01.name) q.add_peer(g1, bridge=br01.name) env.g1 = g1 env.e1 = e1 env.q1 = q1 env.q2 = q2 @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 2001::/32 64..128') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('2001::/64', rf='ipv6') # this will pass e1.add_route('2001::/63', rf='ipv6') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 2) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 2) wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 2) wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 1) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1) wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1) @register_scenario class ExportPolicyIPV6(object): """ No.6 IPv6 export-policy test r1=2001::/64 r2=2001::/63 ------------------------------------------------- e1 ->(r1,r2)-> | ->(r1,r2)-> q1-rib ->(r1,r2)-> q1-adj-rib-out | ->(r1,r2)-> q1 | | | ->(r1,r2)-> q2-rib ->(r2) -> q2-adj-rib-out | ->(r2)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicyIPV6').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 2001::/32 64..128') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('2001::/64', rf='ipv6') # this will pass e1.add_route('2001::/63', rf='ipv6') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 2) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 2) wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 2) wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 2) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1) wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1) @register_scenario class ImportPolicyIPV6Update(object): """ No.7 IPv6 import-policy update test r1=2001:0:10:2::/64 r2=2001:0:10:20::/64 r3=2001:0:10:200::/64 ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 ------------------------------------------------- | update gobgp.conf | V ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicyIPV6').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 2001:0:10:2::/64') g1.local('gobgp policy prefix add ps0 2001:0:10:20::/64') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('2001:0:10:2::/64', rf='ipv6') e1.add_route('2001:0:10:20::/64', rf='ipv6') e1.add_route('2001:0:10:200::/64', rf='ipv6') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 1) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1) wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1) @staticmethod def setup2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix del ps0 2001:0:10:20::/64') g1.softreset(e1, rf='ipv6') @staticmethod def check2(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 2) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 2) wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 2) @register_scenario class ExportPolicyIPv6Update(object): """ No.8 IPv6 export-policy update test r1=2001:0:10:2::/64 r2=2001:0:10:20::/64 r3=2001:0:10:200::/64 ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r2,r3)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 ------------------------------------------------- | update gobgp.conf | V ------------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2,r3)-> rib ->(r1,r2,r3)-> adj-rib-out | ->(r1,r2,r3)-> q1 | | | q2 | | ->(r1,r2,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 ------------------------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicyIPV6').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 2001:0:10:2::/64') g1.local('gobgp policy prefix add ps0 2001:0:10:20::/64') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('2001:0:10:2::/64', rf='ipv6') e1.add_route('2001:0:10:20::/64', rf='ipv6') e1.add_route('2001:0:10:200::/64', rf='ipv6') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 1) wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 1) @staticmethod def setup2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix del ps0 2001:0:10:20::/64') g1.reset(e1) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check2(env): wait_for(lambda: len(env.g1.get_local_rib(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q1, rf='ipv6')) == 3) wait_for(lambda: len(env.q1.get_global_rib(rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_local_rib(env.q2, rf='ipv6')) == 3) wait_for(lambda: len(env.g1.get_adj_rib_out(env.q2, rf='ipv6')) == 2) wait_for(lambda: len(env.q2.get_global_rib(rf='ipv6')) == 2) @register_scenario class ImportPolicyAsPathLengthCondition(object): """ No.9 aspath length condition import-policy test -------------------------------- e1 ->(aspath_length=10)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition as-path-length 10 ge') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', aspath=range(e1.asn, e1.asn-10, -1)) # this will pass e1.add_route('192.168.200.0/24', aspath=range(e1.asn, e1.asn-8, -1)) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) wait_for(lambda: len(q1.get_global_rib()) == 2) wait_for(lambda: len(g1.get_local_rib(q2)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @register_scenario class ImportPolicyAsPathCondition(object): """ No.10 aspath from condition import-policy test -------------------------------- e1 ->(aspath=[65100,...])-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy as-path add as0 ^{0}'.format(e1.asn)) g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition as-path as0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', aspath=range(e1.asn, e1.asn-10, -1)) # this will pass e1.add_route('192.168.200.0/24', aspath=range(e1.asn-1, e1.asn-10, -1)) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): # same check function as previous No.1 scenario lookup_scenario("ImportPolicy").check(env) @register_scenario class ImportPolicyAsPathAnyCondition(object): """ No.11 aspath any condition import-policy test -------------------------------- e1 ->(aspath=[...65098,...])-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy as-path add as0 65098') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition as-path as0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', aspath=[65000, 65098, 65010]) # this will pass e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010]) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): # same check function as previous No.1 scenario lookup_scenario("ImportPolicy").check(env) @register_scenario class ImportPolicyAsPathOriginCondition(object): """ No.12 aspath origin condition import-policy test -------------------------------- e1 ->(aspath=[...,65090])-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy as-path add as0 65090$') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition as-path as0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', aspath=[65000, 65098, 65090]) # this will pass e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010]) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): # same check function as previous No.1 scenario lookup_scenario("ImportPolicy").check(env) @register_scenario class ImportPolicyAsPathOnlyCondition(object): """ No.13 aspath only condition import-policy test -------------------------------- e1 -> (aspath=[65100]) -> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy as-path add as0 ^65100$') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition as-path as0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', aspath=[65100]) # this will pass e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010]) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): # same check function as previous No.1 scenario lookup_scenario("ImportPolicy").check(env) @register_scenario class ImportPolicyAsPathMismatchCondition(object): """ No.14 aspath condition mismatch import-policy test ------------------------------- exabgp ->(aspath=[...,65090])->| -> q1-rib -> q1-adj-rib-out | --> q1 | | | -> q2-rib -> q2-adj-rib-out | --> q2 ------------------------------- This case check if policy passes the path to e1 because of condition mismatch. """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', aspath=[65100, 65090]) # this will pass e1.add_route('192.168.200.0/24', aspath=[65000, 65100, 65010]) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) wait_for(lambda: len(q1.get_global_rib()) == 2) wait_for(lambda: len(g1.get_local_rib(q2)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) wait_for(lambda: len(q2.get_global_rib()) == 2) @register_scenario class ImportPolicyCommunityCondition(object): """ No.15 community condition import-policy test -------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', community=['65100:10']) # this will pass e1.add_route('192.168.200.0/24', community=['65100:20']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario("ImportPolicy").check(env) @register_scenario class ImportPolicyCommunityRegexp(object): """ No.16 community condition regexp import-policy test -------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 6[0-9]+:[0-9]+') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24', community=['65100:10']) # this will pass e1.add_route('192.168.200.0/24', community=['55100:20']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario("ImportPolicy").check(env) def community_exists(path, com): a, b = com.split(':') com = (int(a) << 16) + int(b) for a in path['attrs']: if a['type'] == BGP_ATTR_TYPE_COMMUNITIES and com in a['communities']: return True return False @register_scenario class ImportPolicyCommunityAction(object): """ No.17 community add action import-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=65100:10,65100:20)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community add 65100:20') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) wait_for(lambda: len(q1.get_global_rib()) == 1) wait_for(lambda: len(g1.get_local_rib(q2)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1)[0] env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) path = g1.get_adj_rib_out(q2)[0] env.assertTrue(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) @register_scenario class ImportPolicyCommunityReplace(object): """ No.18 community replace action import-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=65100:20)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community replace 65100:20') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1)[0] env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) path = g1.get_adj_rib_out(q2)[0] env.assertFalse(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) @register_scenario class ImportPolicyCommunityRemove(object): """ No.19 community remove action import-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=null)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community remove 65100:10 65100:20') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) e1.add_route('192.168.110.0/24', community=['65100:10', '65100:20']) e1.add_route('192.168.120.0/24', community=['65100:10', '65100:30']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_local_rib(q1)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 3) wait_for(lambda: len(q1.get_global_rib()) == 3) wait_for(lambda: len(g1.get_local_rib(q2)) == 3) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 3) wait_for(lambda: len(q2.get_global_rib()) == 3) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) if path['nlri']['prefix'] == '192.168.110.0/24': env.assertTrue(community_exists(path, '65100:20')) if path['nlri']['prefix'] == '192.168.120.0/24': env.assertTrue(community_exists(path, '65100:30')) adj_out = g1.get_adj_rib_out(q2) for path in adj_out: env.assertFalse(community_exists(path, '65100:10')) if path['nlri']['prefix'] == '192.168.110.0/24': env.assertFalse(community_exists(path, '65100:20')) if path['nlri']['prefix'] == '192.168.120.0/24': env.assertTrue(community_exists(path, '65100:30')) @register_scenario class ImportPolicyCommunityNull(object): """ No.20 community null action import-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=null)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community replace') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) e1.add_route('192.168.110.0/24', community=['65100:10', '65100:20']) e1.add_route('192.168.120.0/24', community=['65100:10', '65100:30']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityRemove').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) if path['nlri']['prefix'] == '192.168.110.0/24': env.assertTrue(community_exists(path, '65100:20')) if path['nlri']['prefix'] == '192.168.120.0/24': env.assertTrue(community_exists(path, '65100:30')) adj_out = g1.get_adj_rib_out(q2) for path in adj_out: env.assertFalse(community_exists(path, '65100:10')) if path['nlri']['prefix'] == '192.168.110.0/24': env.assertFalse(community_exists(path, '65100:20')) if path['nlri']['prefix'] == '192.168.120.0/24': env.assertFalse(community_exists(path, '65100:30')) @register_scenario class ExportPolicyCommunityAdd(object): """ No.21 community add action export-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=null)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community add 65100:20') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) local_rib = g1.get_local_rib(q2) for path in local_rib[0]['paths']: env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) adj_out = g1.get_adj_rib_out(q2) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) @register_scenario class ExportPolicyCommunityReplace(object): """ No.22 community replace action export-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=65100:20)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community replace 65100:20') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) local_rib = g1.get_local_rib(q2) for path in local_rib[0]['paths']: env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) adj_out = g1.get_adj_rib_out(q2) for path in adj_out: env.assertFalse(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) @register_scenario class ExportPolicyCommunityRemove(object): """ No.23 community replace action export-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=null)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community remove 65100:20 65100:30') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10', '65100:20', '65100:30']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) env.assertTrue(community_exists(path, '65100:30')) local_rib = g1.get_local_rib(q2) for path in local_rib[0]['paths']: env.assertTrue(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) env.assertTrue(community_exists(path, '65100:30')) adj_out = g1.get_adj_rib_out(q2) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) env.assertFalse(community_exists(path, '65100:30')) @register_scenario class ExportPolicyCommunityNull(object): """ No.24 community null action export-policy test ------------------------------- e1 ->(community=65100:10)-> | -> q1-rib -> q1-adj-rib-out | ->(community=65100:10)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(community=null)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action community replace') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10', '65100:20', '65100:30']) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) for path in adj_out: env.assertTrue(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) env.assertTrue(community_exists(path, '65100:30')) local_rib = g1.get_local_rib(q2) for path in local_rib[0]['paths']: env.assertTrue(community_exists(path, '65100:10')) env.assertTrue(community_exists(path, '65100:20')) env.assertTrue(community_exists(path, '65100:30')) adj_out = g1.get_adj_rib_out(q2) for path in adj_out: env.assertFalse(community_exists(path, '65100:10')) env.assertFalse(community_exists(path, '65100:20')) env.assertFalse(community_exists(path, '65100:30')) def metric(path): for a in path['attrs']: if 'metric' in a: return a['metric'] return -1 @register_scenario class ImportPolicyMedReplace(object): """ No.25 med replace action import-policy test ------------------------------- e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(med=100)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action med set 100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', med=300) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) env.assertTrue(metric(adj_out[0]) == 300) local_rib = g1.get_local_rib(q2) env.assertTrue(metric(local_rib[0]['paths'][0]) == 100) adj_out = g1.get_adj_rib_out(q2) env.assertTrue(metric(adj_out[0]) == 100) @register_scenario class ImportPolicyMedAdd(object): """ No.26 med add action import-policy test ------------------------------- e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(med=300+100)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action med add 100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', med=300) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) env.assertTrue(metric(adj_out[0]) == 300) local_rib = g1.get_local_rib(q2) env.assertTrue(metric(local_rib[0]['paths'][0]) == 400) adj_out = g1.get_adj_rib_out(q2) env.assertTrue(metric(adj_out[0]) == 400) @register_scenario class ImportPolicyMedSub(object): """ No.27 med subtract action import-policy test ------------------------------- e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(med=300-100)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action med sub 100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', med=300) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) env.assertTrue(metric(adj_out[0]) == 300) local_rib = g1.get_local_rib(q2) env.assertTrue(metric(local_rib[0]['paths'][0]) == 200) adj_out = g1.get_adj_rib_out(q2) env.assertTrue(metric(adj_out[0]) == 200) @register_scenario class ExportPolicyMedReplace(object): """ No.28 med replace action export-policy test ------------------------------- e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(med=100)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action med set 100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', med=300) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) env.assertTrue(metric(adj_out[0]) == 300) local_rib = g1.get_local_rib(q2) env.assertTrue(metric(local_rib[0]['paths'][0]) == 300) adj_out = g1.get_adj_rib_out(q2) env.assertTrue(metric(adj_out[0]) == 100) @register_scenario class ExportPolicyMedAdd(object): """ No.29 med add action export-policy test ------------------------------- e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(med=300+100)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action med add 100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', med=300) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) env.assertTrue(metric(adj_out[0]) == 300) local_rib = g1.get_local_rib(q2) env.assertTrue(metric(local_rib[0]['paths'][0]) == 300) adj_out = g1.get_adj_rib_out(q2) env.assertTrue(metric(adj_out[0]) == 400) @register_scenario class ExportPolicyMedSub(object): """ No.30 med subtract action export-policy test ------------------------------- e1 ->(med=300)-> | -> q1-rib -> q1-adj-rib-out | ->(med=300)-> q1 | | | -> q2-rib -> q2-adj-rib-out | ->(med=300-100)-> q2 | apply action | ------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy statement add st0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action med sub 100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', med=300) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 q1 = env.q1 q2 = env.q2 adj_out = g1.get_adj_rib_out(q1) env.assertTrue(metric(adj_out[0]) == 300) local_rib = g1.get_local_rib(q2) env.assertTrue(metric(local_rib[0]['paths'][0]) == 300) adj_out = g1.get_adj_rib_out(q2) env.assertTrue(metric(adj_out[0]) == 200) @register_scenario class InPolicyReject(object): """ No.31 in-policy reject test ---------------- e1 ->r1(community=65100:10) -> x | -> q1-rib -> | -> r2 --> q1 r2(192.168.10.0/24) -> o | | | -> q2-rib -> | -> r2 --> q2 ---------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy in add policy0'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) e1.add_route('192.168.10.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 2) wait_for(lambda: len(g1.get_local_rib(q1)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) wait_for(lambda: len(q1.get_global_rib()) == 1) wait_for(lambda: len(g1.get_local_rib(q2)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @register_scenario class InPolicyAccept(object): """ No.32 in-policy accept test ---------------- e1 ->r1(community=65100:10) -> x | -> q1-rib -> | -> r2 --> q1 r2(192.168.10.0/24) -> o | | | -> q2-rib -> | -> r2 --> q2 ---------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy community add cs0 65100:10') g1.local('gobgp policy statement st0 add condition community cs0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy in add policy0 default reject'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) e1.add_route('192.168.100.0/24', community=['65100:10']) e1.add_route('192.168.10.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('InPolicyReject').check(env) @register_scenario class InPolicyUpdate(object): """ No.35 in-policy update test r1:192.168.2.0 r2:192.168.20.0 r3:192.168.200.0 ------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q1 | | | q2 | | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 ------------------------------------- | update distribute policy | V ------------------------------------------- | q1 | e1 ->(r1,r2,r3)-> | ->(r1,r2)-> rib ->(r1,r2)-> adj-rib-out | ->(r1,r2)-> q1 | | | q2 | | ->(r1,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 ------------------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.20.0/24') g1.local('gobgp policy prefix add ps0 192.168.200.0/24') g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add condition neighbor ns0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy in add policy0'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) e1.add_route('192.168.2.0/24') e1.add_route('192.168.20.0/24') e1.add_route('192.168.200.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3) wait_for(lambda: len(g1.get_local_rib(q1)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) wait_for(lambda: len(q1.get_global_rib()) == 1) wait_for(lambda: len(g1.get_local_rib(q2)) == 1) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) wait_for(lambda: len(q2.get_global_rib()) == 1) @staticmethod def setup2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.clear_policy() g1.local('gobgp policy prefix del ps0 192.168.200.0/24') g1.softreset(e1) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3) wait_for(lambda: len(g1.get_local_rib(q1)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) wait_for(lambda: len(q1.get_global_rib()) == 2) wait_for(lambda: len(g1.get_local_rib(q2)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) wait_for(lambda: len(q2.get_global_rib()) == 2) @register_scenario class ExportPolicyAsPathPrepend(object): """ No.37 aspath prepend action export -------------------------------- e1 ->(aspath=[65001])-> | -> p1-rib -> p1-adj-rib-out | -> p1 | | | -> p2-rib -> p2-adj-rib-out | -> p2 | apply action | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.20.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action as-prepend 65005 5') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.20.0/24') e1.add_route('192.168.200.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 2) wait_for(lambda: len(g1.get_local_rib(q1)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) wait_for(lambda: len(q1.get_global_rib()) == 2) wait_for(lambda: len(g1.get_local_rib(q2)) == 2) wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) wait_for(lambda: len(q2.get_global_rib()) == 2) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1, prefix='192.168.20.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_adj_rib_out(q1, prefix='192.168.200.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_local_rib(q2, prefix='192.168.20.0/24')[0]['paths'][0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_adj_rib_out(q2, prefix='192.168.20.0/24')[0] env.assertTrue(path['aspath'] == [65005]*5 + [e1.asn]) path = g1.get_adj_rib_out(q2, prefix='192.168.200.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) @register_scenario class ImportPolicyAsPathPrependLastAS(object): """ No.38 aspath prepend action lastas import -------------------------------- e1 ->(aspath=[65001])-> | -> p1-rib -> p1-adj-rib-out | -> p1 | | | -> p2-rib -> p2-adj-rib-out | -> p2 | apply action | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.20.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action as-prepend last-as 5') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.20.0/24') e1.add_route('192.168.200.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ExportPolicyAsPathPrepend').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1, prefix='192.168.20.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_adj_rib_out(q1, prefix='192.168.200.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_local_rib(q2, prefix='192.168.20.0/24')[0]['paths'][0] env.assertTrue(path['aspath'] == [e1.asn]*5 + [e1.asn]) path = g1.get_adj_rib_out(q2, prefix='192.168.20.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]*5 + [e1.asn]) path = g1.get_adj_rib_out(q2, prefix='192.168.200.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) @register_scenario class ExportPolicyAsPathPrependLastAS(object): """ No.39 aspath prepend action lastas export -------------------------------- e1 ->(aspath=[65001])-> | -> p1-rib -> p1-adj-rib-out | -> p1 | | | -> p2-rib -> p2-adj-rib-out | -> p2 | apply action | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.20.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action as-prepend last-as 5') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.20.0/24') e1.add_route('192.168.200.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ExportPolicyAsPathPrepend').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1, prefix='192.168.20.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_adj_rib_out(q1, prefix='192.168.200.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_local_rib(q2, prefix='192.168.20.0/24')[0]['paths'][0] env.assertTrue(path['aspath'] == [e1.asn]) path = g1.get_adj_rib_out(q2, prefix='192.168.20.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]*5 + [e1.asn]) path = g1.get_adj_rib_out(q2, prefix='192.168.200.0/24')[0] env.assertTrue(path['aspath'] == [e1.asn]) @register_scenario class ImportPolicyExCommunityOriginCondition(object): """ No.40 extended community origin condition import -------------------------------- e1 ->(extcommunity=origin:65001.65100:200)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario("ImportPolicy").boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy ext-community add es0 soo:65001.65100:200') g1.local('gobgp policy statement st0 add condition ext-community es0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.20.0/24', extendedcommunity='origin:{0}:200'.format((65001 << 16) + 65100)) e1.add_route('192.168.200.0/24', extendedcommunity='origin:{0}:100'.format((65001 << 16) + 65200)) for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario("ImportPolicy").check(env) @register_scenario class ImportPolicyExCommunityTargetCondition(object): """ No.41 extended community origin condition import -------------------------------- e1 ->(extcommunity=target:65010:320)-> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | ->x q2-rib | -------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy ext-community add es0 rt:6[0-9]+:3[0-9]+') g1.local('gobgp policy statement st0 add condition ext-community es0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.20.0/24', extendedcommunity='target:65010:320') e1.add_route('192.168.200.0/24', extendedcommunity='target:55000:320') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario("ImportPolicy").check(env) @register_scenario class InPolicyPrefixCondition(object): """ No.42 prefix only condition accept in ----------------- e1 ->r1(192.168.100.0/24) -> o | -> q1-rib -> | -> r2 --> q1 r2(192.168.10.0/24) -> x | | | -> q2-rib -> | -> r2 --> q2 ----------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.10.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action reject') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy in add policy0'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) # this will be blocked e1.add_route('192.168.100.0/24') # this will pass e1.add_route('192.168.10.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('InPolicyReject').check(env) def ext_community_exists(path, extcomm): typ = extcomm.split(':')[0] value = ':'.join(extcomm.split(':')[1:]) for a in path['attrs']: if a['type'] == BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: for c in a['value']: if typ == 'RT' and c['type'] == 0 and c['subtype'] == 2 and c['value'] == value: return True return False @register_scenario class ImportPolicyExCommunityAdd(object): """ No.43 extended community add action import-policy test --------------------------------- e1 ->(extcommunity=none) ->| -> q1-rib -> q1-adj-rib-out | --> q1 | | | -> q2-rib -> q2-adj-rib-out | --> q2 | add ext-community | --------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.10.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action ext-community add rt:65000:1') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.10.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1)[0] env.assertFalse(ext_community_exists(path, 'RT:65000:1')) path = g1.get_adj_rib_out(q2)[0] env.assertTrue(ext_community_exists(path, 'RT:65000:1')) @register_scenario class ImportPolicyExCommunityAdd2(object): """ No.44 extended community add action import-policy test -------------------------------- e1 ->(extcommunity=RT:65000:1) -> | -> q1-rib -> q1-adj-rib-out | --> q1 | | | -> q2-rib -> q2-adj-rib-out | --> q2 | add ext-community | -------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.10.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action ext-community add rt:65100:100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.10.0/24', extendedcommunity='target:65000:1') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1)[0] env.assertTrue(ext_community_exists(path, 'RT:65000:1')) env.assertFalse(ext_community_exists(path, 'RT:65100:100')) path = g1.get_local_rib(q2)[0]['paths'][0] env.assertTrue(ext_community_exists(path, 'RT:65000:1')) env.assertTrue(ext_community_exists(path, 'RT:65100:100')) path = g1.get_adj_rib_out(q2)[0] env.assertTrue(ext_community_exists(path, 'RT:65000:1')) env.assertTrue(ext_community_exists(path, 'RT:65100:100')) @register_scenario class ImportPolicyExCommunityMultipleAdd(object): """ No.45 extended community add action multiple import-policy test --------------------------------------- exabgp ->(extcommunity=none) ->| -> peer1-rib -> peer1-adj-rib-out | --> peer1 | | | -> peer2-rib -> peer2-adj-rib-out | --> peer2 | add ext-community | --------------------------------------- """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.10.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action ext-community add rt:65100:100 rt:100:100') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy import add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.10.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1)[0] env.assertFalse(ext_community_exists(path, 'RT:65100:100')) env.assertFalse(ext_community_exists(path, 'RT:100:100')) path = g1.get_local_rib(q2)[0]['paths'][0] env.assertTrue(ext_community_exists(path, 'RT:65100:100')) env.assertTrue(ext_community_exists(path, 'RT:100:100')) path = g1.get_adj_rib_out(q2)[0] env.assertTrue(ext_community_exists(path, 'RT:65100:100')) env.assertTrue(ext_community_exists(path, 'RT:100:100')) @register_scenario class ExportPolicyExCommunityAdd(object): """ No.46 extended comunity add action export-policy test ------------------------------------ e1 ->(extcommunity=none) ->| -> q1-rib -> q1-adj-rib-out | --> q1 | | | -> q2-rib -> q2-adj-rib-out | --> q2 | add ext-community | ------------------------------------ """ @staticmethod def boot(env): lookup_scenario('ImportPolicy').boot(env) @staticmethod def setup(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 g1.local('gobgp policy prefix add ps0 192.168.10.0/24') g1.local('gobgp policy statement st0 add condition prefix ps0') g1.local('gobgp policy statement st0 add action accept') g1.local('gobgp policy statement st0 add action ext-community add rt:65000:1') g1.local('gobgp policy add policy0 st0') g1.local('gobgp neighbor {0} policy export add policy0'.format(g1.peers[q2]['neigh_addr'].split('/')[0])) e1.add_route('192.168.10.0/24') for c in [e1, q1, q2]: g1.wait_for(BGP_FSM_ESTABLISHED, c) @staticmethod def check(env): lookup_scenario('ImportPolicyCommunityAction').check(env) @staticmethod def check2(env): g1 = env.g1 e1 = env.e1 q1 = env.q1 q2 = env.q2 path = g1.get_adj_rib_out(q1)[0] env.assertFalse(ext_community_exists(path, 'RT:65000:1')) path = g1.get_local_rib(q2)[0]['paths'][0] env.assertFalse(ext_community_exists(path, 'RT:65000:1')) path = g1.get_adj_rib_out(q2)[0] env.assertTrue(ext_community_exists(path, 'RT:65000:1')) class GoBGPTestBase(unittest.TestCase): wait_per_retry = 5 retry_limit = 10 @classmethod def setUpClass(cls): idx = parser_option.test_index base.TEST_PREFIX = parser_option.test_prefix cls.parser_option = parser_option if idx not in _SCENARIOS: print 'invalid test-index. # of scenarios: {0}'.format(len(_SCENARIOS)) sys.exit(1) cls.setup2 = None cls.check2 = None for k, m in inspect.getmembers(_SCENARIOS[idx], inspect.isfunction): if k == 'boot': cls.boot = m elif k == 'setup': cls.setup = m elif k == 'check': cls.check = m elif k == 'setup2': cls.setup2 = m elif k == 'check2': cls.check2 = m def test(self): self.boot() self.setup() self.check() if self.setup2: self.setup2() if self.check2: self.check2() if __name__ == '__main__': if os.geteuid() is not 0: print "you are not root." sys.exit(1) output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True) if int(output) is not 0: print "docker not found" sys.exit(1) nose.main(argv=sys.argv, addplugins=[OptionParser()], defaultTest=sys.argv[0])