7171TOR_ASN_START = 65500
7272IPV4_BASE_PORT = 5000
7373IPV6_BASE_PORT = 6000
74+ DEFAULT_NEIGHBOR_GROUPS = 1
7475AGGREGATE_ROUTES_DEFAULT_VALUE = []
7576IPV6_ADDRESS_PATTERN_DEFAULT_VALUE = '20%02X:%02X%02X:0:%02X::/64'
7677ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE = True
@@ -360,7 +361,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
360361 router_type = "leaf" , tor_index = None , set_num = None ,
361362 no_default_route = False , core_ra_asn = CORE_RA_ASN ,
362363 ipv6_address_pattern = IPV6_ADDRESS_PATTERN_DEFAULT_VALUE ,
363- tor_default_route = False ):
364+ tor_default_route = False , offset = 0 ):
364365 routes = []
365366 if not no_default_route and (router_type != "tor" or tor_default_route ):
366367 default_route_as_path = get_uplink_router_as_path (
@@ -375,6 +376,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
375376 # NOTE: Using large enough values (e.g., podset_number = 200,
376377 # us to overflow the 192.168.0.0/16 private address space here.
377378 # This should be fine for internal use, but may pose an issue if used otherwise
379+ suffix = 0
378380 for podset in range (0 , podset_number ):
379381 for tor in range (0 , tor_number ):
380382 for subnet in range (0 , tor_subnet_number ):
@@ -438,7 +440,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
438440
439441 suffix = ((podset * tor_number * max_tor_subnet_number * tor_subnet_size ) +
440442 (tor * max_tor_subnet_number * tor_subnet_size ) +
441- (subnet * tor_subnet_size ))
443+ (subnet * tor_subnet_size ) + offset )
442444 octet2 = (168 + int (suffix / (256 ** 2 )))
443445 octet1 = (192 + int (octet2 / 256 ))
444446 octet2 = (octet2 % 256 )
@@ -476,10 +478,10 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
476478 if family in ["v6" , "both" ]:
477479 routes .append ((prefix_v6 , nexthop_v6 , aspath ))
478480
479- return routes
481+ return routes , suffix
480482
481483
482- def fib_t0 (topo , ptf_ip , no_default_route = False , action = "announce" ):
484+ def fib_t0 (topo , ptf_ip , no_default_route = False , action = "announce" , upstream_neighbor_groups = 0 ):
483485 common_config = topo ['configuration_properties' ].get ('common' , {})
484486 podset_number = common_config .get ("podset_number" , PODSET_NUMBER )
485487 tor_number = common_config .get ("tor_number" , TOR_NUMBER )
@@ -498,9 +500,14 @@ def fib_t0(topo, ptf_ip, no_default_route=False, action="announce"):
498500 ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE )
499501 enable_ipv4_routes_generation = common_config .get ("enable_ipv4_routes_generation" ,
500502 ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE )
503+ if upstream_neighbor_groups == 0 :
504+ upstream_neighbor_groups = common_config .get ("upstream_neighbor_groups" , DEFAULT_NEIGHBOR_GROUPS )
501505
502506 vms = topo ['topology' ]['VMs' ]
503- for vm_name , vm in vms .items ():
507+ vms_len = len (vms )
508+ current_routes_offset = 0
509+ last_suffix = 0
510+ for index , (vm_name , vm ) in enumerate (vms .items ()):
504511 router_type = "leaf"
505512 if 'tor' in topo ['configuration' ][vm_name ]['properties' ]:
506513 router_type = 'tor'
@@ -513,26 +520,31 @@ def fib_t0(topo, ptf_ip, no_default_route=False, action="announce"):
513520 aggregate_routes_v6 = get_ipv6_routes (aggregate_routes )
514521
515522 if enable_ipv4_routes_generation :
516- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
517- spine_asn , leaf_asn_start , tor_asn_start ,
518- nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number , "t0" ,
519- router_type = router_type ,
520- no_default_route = no_default_route )
523+ routes_v4 , last_suffix = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
524+ spine_asn , leaf_asn_start , tor_asn_start ,
525+ nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number , "t0" ,
526+ router_type = router_type ,
527+ no_default_route = no_default_route , offset = current_routes_offset )
521528 if aggregate_routes_v4 :
522529 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
523530 routes_v4 .extend (aggregate_routes_v4 )
524531 change_routes (action , ptf_ip , port , routes_v4 )
525532 if enable_ipv6_routes_generation :
526- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
527- spine_asn , leaf_asn_start , tor_asn_start ,
528- nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t0" ,
529- router_type = router_type ,
530- no_default_route = no_default_route ,
531- ipv6_address_pattern = ipv6_address_pattern )
533+ routes_v6 , last_suffix = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
534+ spine_asn , leaf_asn_start , tor_asn_start ,
535+ nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t0" ,
536+ router_type = router_type ,
537+ no_default_route = no_default_route ,
538+ ipv6_address_pattern = ipv6_address_pattern ,
539+ offset = current_routes_offset )
532540 if aggregate_routes_v6 :
533541 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
534542 routes_v6 .extend (aggregate_routes_v6 )
535543 change_routes (action , ptf_ip , port6 , routes_v6 )
544+ group_index = index * upstream_neighbor_groups // vms_len
545+ next_group_index = (index + 1 ) * upstream_neighbor_groups // vms_len
546+ if group_index != next_group_index :
547+ current_routes_offset += last_suffix
536548
537549
538550def fib_t1_lag (topo , ptf_ip , no_default_route = False , action = "announce" , tor_default_route = False ):
@@ -582,23 +594,23 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce", tor_defa
582594 tor_index = tornum - 1 if tornum is not None else None
583595 if router_type :
584596 if enable_ipv4_routes_generation :
585- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
586- None , leaf_asn_start , tor_asn_start ,
587- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
588- router_type = router_type , tor_index = tor_index ,
589- no_default_route = no_default_route , tor_default_route = tor_default_route )
597+ routes_v4 , _ = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
598+ None , leaf_asn_start , tor_asn_start ,
599+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
600+ router_type = router_type , tor_index = tor_index ,
601+ no_default_route = no_default_route , tor_default_route = tor_default_route )
590602 if aggregate_routes_v4 :
591603 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
592604 routes_v4 .extend (aggregate_routes_v4 )
593605 change_routes (action , ptf_ip , port , routes_v4 )
594606 if enable_ipv6_routes_generation :
595- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
596- None , leaf_asn_start , tor_asn_start ,
597- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
598- router_type = router_type , tor_index = tor_index ,
599- no_default_route = no_default_route ,
600- ipv6_address_pattern = ipv6_address_pattern ,
601- tor_default_route = tor_default_route )
607+ routes_v6 , _ = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
608+ None , leaf_asn_start , tor_asn_start ,
609+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
610+ router_type = router_type , tor_index = tor_index ,
611+ no_default_route = no_default_route ,
612+ ipv6_address_pattern = ipv6_address_pattern ,
613+ tor_default_route = tor_default_route )
602614 if aggregate_routes_v6 :
603615 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
604616 routes_v6 .extend (aggregate_routes_v6 )
@@ -1216,22 +1228,22 @@ def generate_t2_routes(dut_vm_dict, topo, ptf_ip, action="announce"):
12161228
12171229 if router_type :
12181230 if enable_ipv4_routes_generation :
1219- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1220- common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1221- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1222- router_type = router_type , tor_index = tor_index , set_num = set_num ,
1223- core_ra_asn = core_ra_asn )
1231+ routes_v4 , _ = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1232+ common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1233+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1234+ router_type = router_type , tor_index = tor_index , set_num = set_num ,
1235+ core_ra_asn = core_ra_asn )
12241236 if aggregate_routes_v4 :
12251237 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
12261238 routes_v4 .extend (aggregate_routes_v4 )
12271239 random .shuffle (routes_v4 )
12281240 r_set .append ((routes_v4 , port , action , ptf_ip ))
12291241 if enable_ipv6_routes_generation :
1230- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1231- common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1232- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1233- router_type = router_type , tor_index = tor_index , set_num = set_num ,
1234- core_ra_asn = core_ra_asn , ipv6_address_pattern = ipv6_address_pattern )
1242+ routes_v6 , _ = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1243+ common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1244+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1245+ router_type = router_type , tor_index = tor_index , set_num = set_num ,
1246+ core_ra_asn = core_ra_asn , ipv6_address_pattern = ipv6_address_pattern )
12351247 if aggregate_routes_v6 :
12361248 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
12371249 routes_v6 .extend (aggregate_routes_v6 )
@@ -1285,20 +1297,20 @@ def fib_t0_mclag(topo, ptf_ip, action="announce"):
12851297 aggregate_routes_v6 = get_ipv6_routes (aggregate_routes )
12861298
12871299 if enable_ipv4_routes_generation :
1288- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1289- spine_asn , leaf_asn_start , tor_asn_start ,
1290- nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number ,
1291- "t0-mclag" , set_num = set_num )
1300+ routes_v4 , _ = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1301+ spine_asn , leaf_asn_start , tor_asn_start ,
1302+ nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number ,
1303+ "t0-mclag" , set_num = set_num )
12921304 if aggregate_routes_v4 :
12931305 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
12941306 routes_v4 .extend (aggregate_routes_v4 )
12951307 change_routes (action , ptf_ip , port , routes_v4 )
12961308 if enable_ipv6_routes_generation :
1297- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1298- spine_asn , leaf_asn_start , tor_asn_start ,
1299- nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number ,
1300- "t0-mclag" , set_num = set_num ,
1301- ipv6_address_pattern = ipv6_address_pattern )
1309+ routes_v6 , _ = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1310+ spine_asn , leaf_asn_start , tor_asn_start ,
1311+ nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number ,
1312+ "t0-mclag" , set_num = set_num ,
1313+ ipv6_address_pattern = ipv6_address_pattern )
13021314 if aggregate_routes_v6 :
13031315 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
13041316 routes_v6 .extend (aggregate_routes_v6 )
@@ -1461,7 +1473,8 @@ def main():
14611473 dut_interfaces = dict (required = False , type = 'str' , default = '' ),
14621474 adhoc = dict (required = False , type = 'bool' , default = False ),
14631475 peers_routes_to_change = dict (required = False , type = 'dict' , default = {}),
1464- log_path = dict (required = False , type = 'str' , default = '' )
1476+ log_path = dict (required = False , type = 'str' , default = '' ),
1477+ upstream_neighbor_groups = dict (required = False , type = 'int' , default = 0 )
14651478 ),
14661479 supports_check_mode = False )
14671480
@@ -1475,6 +1488,7 @@ def main():
14751488 path = module .params ['path' ]
14761489 adhoc = module .params ['adhoc' ]
14771490 peers_routes_to_change = module .params ['peers_routes_to_change' ]
1491+ upstream_neighbor_groups = module .params ['upstream_neighbor_groups' ]
14781492
14791493 topo = read_topo (topo_name , path )
14801494 if not topo :
@@ -1495,7 +1509,8 @@ def main():
14951509 adhoc_routes (topo , ptf_ip , peers_routes_to_change , action )
14961510 module .exit_json (change = True )
14971511 elif topo_type == "t0" :
1498- fib_t0 (topo , ptf_ip , no_default_route = is_storage_backend , action = action )
1512+ fib_t0 (topo , ptf_ip , no_default_route = is_storage_backend , action = action ,
1513+ upstream_neighbor_groups = upstream_neighbor_groups )
14991514 module .exit_json (changed = True )
15001515 elif topo_type == "t1" or topo_type == "smartswitch-t1" :
15011516 fib_t1_lag (
0 commit comments