7070TOR_ASN_START = 65500
7171IPV4_BASE_PORT = 5000
7272IPV6_BASE_PORT = 6000
73+ DEFAULT_NEIGHBOR_GROUPS = 1
7374AGGREGATE_ROUTES_DEFAULT_VALUE = []
7475IPV6_ADDRESS_PATTERN_DEFAULT_VALUE = '20%02X:%02X%02X:0:%02X::/64'
7576ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE = True
@@ -340,7 +341,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
340341 router_type = "leaf" , tor_index = None , set_num = None ,
341342 no_default_route = False , core_ra_asn = CORE_RA_ASN ,
342343 ipv6_address_pattern = IPV6_ADDRESS_PATTERN_DEFAULT_VALUE ,
343- tor_default_route = False ):
344+ tor_default_route = False , offset = 0 ):
344345 routes = []
345346 if not no_default_route and (router_type != "tor" or tor_default_route ):
346347 default_route_as_path = get_uplink_router_as_path (
@@ -355,6 +356,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
355356 # NOTE: Using large enough values (e.g., podset_number = 200,
356357 # us to overflow the 192.168.0.0/16 private address space here.
357358 # This should be fine for internal use, but may pose an issue if used otherwise
359+ suffix = 0
358360 for podset in range (0 , podset_number ):
359361 for tor in range (0 , tor_number ):
360362 for subnet in range (0 , tor_subnet_number ):
@@ -418,7 +420,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
418420
419421 suffix = ((podset * tor_number * max_tor_subnet_number * tor_subnet_size ) +
420422 (tor * max_tor_subnet_number * tor_subnet_size ) +
421- (subnet * tor_subnet_size ))
423+ (subnet * tor_subnet_size ) + offset )
422424 octet2 = (168 + int (suffix / (256 ** 2 )))
423425 octet1 = (192 + int (octet2 / 256 ))
424426 octet2 = (octet2 % 256 )
@@ -456,10 +458,10 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
456458 if family in ["v6" , "both" ]:
457459 routes .append ((prefix_v6 , nexthop_v6 , aspath ))
458460
459- return routes
461+ return routes , suffix
460462
461463
462- def fib_t0 (topo , ptf_ip , no_default_route = False , action = "announce" ):
464+ def fib_t0 (topo , ptf_ip , no_default_route = False , action = "announce" , upstream_neighbor_groups = 0 ):
463465 common_config = topo ['configuration_properties' ].get ('common' , {})
464466 podset_number = common_config .get ("podset_number" , PODSET_NUMBER )
465467 tor_number = common_config .get ("tor_number" , TOR_NUMBER )
@@ -478,9 +480,14 @@ def fib_t0(topo, ptf_ip, no_default_route=False, action="announce"):
478480 ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE )
479481 enable_ipv4_routes_generation = common_config .get ("enable_ipv4_routes_generation" ,
480482 ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE )
483+ if upstream_neighbor_groups == 0 :
484+ upstream_neighbor_groups = common_config .get ("upstream_neighbor_groups" , DEFAULT_NEIGHBOR_GROUPS )
481485
482486 vms = topo ['topology' ]['VMs' ]
483- for vm_name , vm in vms .items ():
487+ vms_len = len (vms )
488+ current_routes_offset = 0
489+ last_suffix = 0
490+ for index , (vm_name , vm ) in enumerate (vms .items ()):
484491 router_type = "leaf"
485492 if 'tor' in topo ['configuration' ][vm_name ]['properties' ]:
486493 router_type = 'tor'
@@ -493,26 +500,31 @@ def fib_t0(topo, ptf_ip, no_default_route=False, action="announce"):
493500 aggregate_routes_v6 = get_ipv6_routes (aggregate_routes )
494501
495502 if enable_ipv4_routes_generation :
496- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
497- spine_asn , leaf_asn_start , tor_asn_start ,
498- nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number , "t0" ,
499- router_type = router_type ,
500- no_default_route = no_default_route )
503+ routes_v4 , last_suffix = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
504+ spine_asn , leaf_asn_start , tor_asn_start ,
505+ nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number , "t0" ,
506+ router_type = router_type ,
507+ no_default_route = no_default_route , offset = current_routes_offset )
501508 if aggregate_routes_v4 :
502509 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
503510 routes_v4 .extend (aggregate_routes_v4 )
504511 change_routes (action , ptf_ip , port , routes_v4 )
505512 if enable_ipv6_routes_generation :
506- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
507- spine_asn , leaf_asn_start , tor_asn_start ,
508- nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t0" ,
509- router_type = router_type ,
510- no_default_route = no_default_route ,
511- ipv6_address_pattern = ipv6_address_pattern )
513+ routes_v6 , last_suffix = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
514+ spine_asn , leaf_asn_start , tor_asn_start ,
515+ nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t0" ,
516+ router_type = router_type ,
517+ no_default_route = no_default_route ,
518+ ipv6_address_pattern = ipv6_address_pattern ,
519+ offset = current_routes_offset )
512520 if aggregate_routes_v6 :
513521 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
514522 routes_v6 .extend (aggregate_routes_v6 )
515523 change_routes (action , ptf_ip , port6 , routes_v6 )
524+ group_index = index * upstream_neighbor_groups // vms_len
525+ next_group_index = (index + 1 ) * upstream_neighbor_groups // vms_len
526+ if group_index != next_group_index :
527+ current_routes_offset += last_suffix
516528
517529
518530def fib_t1_lag (topo , ptf_ip , no_default_route = False , action = "announce" , tor_default_route = False ):
@@ -562,23 +574,23 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce", tor_defa
562574 tor_index = tornum - 1 if tornum is not None else None
563575 if router_type :
564576 if enable_ipv4_routes_generation :
565- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
566- None , leaf_asn_start , tor_asn_start ,
567- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
568- router_type = router_type , tor_index = tor_index ,
569- no_default_route = no_default_route , tor_default_route = tor_default_route )
577+ routes_v4 , _ = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
578+ None , leaf_asn_start , tor_asn_start ,
579+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
580+ router_type = router_type , tor_index = tor_index ,
581+ no_default_route = no_default_route , tor_default_route = tor_default_route )
570582 if aggregate_routes_v4 :
571583 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
572584 routes_v4 .extend (aggregate_routes_v4 )
573585 change_routes (action , ptf_ip , port , routes_v4 )
574586 if enable_ipv6_routes_generation :
575- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
576- None , leaf_asn_start , tor_asn_start ,
577- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
578- router_type = router_type , tor_index = tor_index ,
579- no_default_route = no_default_route ,
580- ipv6_address_pattern = ipv6_address_pattern ,
581- tor_default_route = tor_default_route )
587+ routes_v6 , _ = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
588+ None , leaf_asn_start , tor_asn_start ,
589+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t1" ,
590+ router_type = router_type , tor_index = tor_index ,
591+ no_default_route = no_default_route ,
592+ ipv6_address_pattern = ipv6_address_pattern ,
593+ tor_default_route = tor_default_route )
582594 if aggregate_routes_v6 :
583595 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
584596 routes_v6 .extend (aggregate_routes_v6 )
@@ -1013,22 +1025,22 @@ def generate_t2_routes(dut_vm_dict, topo, ptf_ip, action="announce"):
10131025
10141026 if router_type :
10151027 if enable_ipv4_routes_generation :
1016- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1017- common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1018- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1019- router_type = router_type , tor_index = tor_index , set_num = set_num ,
1020- core_ra_asn = core_ra_asn )
1028+ routes_v4 , _ = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1029+ common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1030+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1031+ router_type = router_type , tor_index = tor_index , set_num = set_num ,
1032+ core_ra_asn = core_ra_asn )
10211033 if aggregate_routes_v4 :
10221034 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
10231035 routes_v4 .extend (aggregate_routes_v4 )
10241036 random .shuffle (routes_v4 )
10251037 r_set .append ((routes_v4 , port , action , ptf_ip ))
10261038 if enable_ipv6_routes_generation :
1027- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1028- common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1029- nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1030- router_type = router_type , tor_index = tor_index , set_num = set_num ,
1031- core_ra_asn = core_ra_asn , ipv6_address_pattern = ipv6_address_pattern )
1039+ routes_v6 , _ = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1040+ common_config ['dut_asn' ], leaf_asn_start , tor_asn_start ,
1041+ nhipv4 , nhipv6 , tor_subnet_size , max_tor_subnet_number , "t2" ,
1042+ router_type = router_type , tor_index = tor_index , set_num = set_num ,
1043+ core_ra_asn = core_ra_asn , ipv6_address_pattern = ipv6_address_pattern )
10321044 if aggregate_routes_v6 :
10331045 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
10341046 routes_v6 .extend (aggregate_routes_v6 )
@@ -1082,20 +1094,20 @@ def fib_t0_mclag(topo, ptf_ip, action="announce"):
10821094 aggregate_routes_v6 = get_ipv6_routes (aggregate_routes )
10831095
10841096 if enable_ipv4_routes_generation :
1085- routes_v4 = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1086- spine_asn , leaf_asn_start , tor_asn_start ,
1087- nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number ,
1088- "t0-mclag" , set_num = set_num )
1097+ routes_v4 , _ = generate_routes ("v4" , podset_number , tor_number , tor_subnet_number ,
1098+ spine_asn , leaf_asn_start , tor_asn_start ,
1099+ nhipv4 , nhipv4 , tor_subnet_size , max_tor_subnet_number ,
1100+ "t0-mclag" , set_num = set_num )
10891101 if aggregate_routes_v4 :
10901102 filterout_subnet_ipv4 (aggregate_routes , routes_v4 )
10911103 routes_v4 .extend (aggregate_routes_v4 )
10921104 change_routes (action , ptf_ip , port , routes_v4 )
10931105 if enable_ipv6_routes_generation :
1094- routes_v6 = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1095- spine_asn , leaf_asn_start , tor_asn_start ,
1096- nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number ,
1097- "t0-mclag" , set_num = set_num ,
1098- ipv6_address_pattern = ipv6_address_pattern )
1106+ routes_v6 , _ = generate_routes ("v6" , podset_number , tor_number , tor_subnet_number ,
1107+ spine_asn , leaf_asn_start , tor_asn_start ,
1108+ nhipv6 , nhipv6 , tor_subnet_size , max_tor_subnet_number ,
1109+ "t0-mclag" , set_num = set_num ,
1110+ ipv6_address_pattern = ipv6_address_pattern )
10991111 if aggregate_routes_v6 :
11001112 filterout_subnet_ipv6 (aggregate_routes , routes_v6 )
11011113 routes_v6 .extend (aggregate_routes_v6 )
@@ -1181,7 +1193,8 @@ def main():
11811193 dut_interfaces = dict (required = False , type = 'str' , default = '' ),
11821194 adhoc = dict (required = False , type = 'bool' , default = False ),
11831195 peers_routes_to_change = dict (required = False , type = 'dict' , default = {}),
1184- log_path = dict (required = False , type = 'str' , default = '' )
1196+ log_path = dict (required = False , type = 'str' , default = '' ),
1197+ upstream_neighbor_groups = dict (required = False , type = 'int' , default = 0 )
11851198 ),
11861199 supports_check_mode = False )
11871200
@@ -1195,6 +1208,7 @@ def main():
11951208 path = module .params ['path' ]
11961209 adhoc = module .params ['adhoc' ]
11971210 peers_routes_to_change = module .params ['peers_routes_to_change' ]
1211+ upstream_neighbor_groups = module .params ['upstream_neighbor_groups' ]
11981212
11991213 topo = read_topo (topo_name , path )
12001214 if not topo :
@@ -1215,7 +1229,8 @@ def main():
12151229 adhoc_routes (topo , ptf_ip , peers_routes_to_change , action )
12161230 module .exit_json (change = True )
12171231 elif topo_type == "t0" :
1218- fib_t0 (topo , ptf_ip , no_default_route = is_storage_backend , action = action )
1232+ fib_t0 (topo , ptf_ip , no_default_route = is_storage_backend , action = action ,
1233+ upstream_neighbor_groups = upstream_neighbor_groups )
12191234 module .exit_json (changed = True )
12201235 elif topo_type == "t1" or topo_type == "smartswitch-t1" :
12211236 fib_t1_lag (
0 commit comments