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])