Skip to content

Commit

Permalink
[testbed] announce routes with routes generation switch, aggregate ro…
Browse files Browse the repository at this point in the history
…utes and variable ipv6 address pattern (#15748)

* add routes generation switch, add aggregate routes key, paramterize ipv6 address prefix length
  • Loading branch information
w1nda authored Jan 18, 2025
1 parent cbd2bfe commit aca0f87
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 142 deletions.
204 changes: 153 additions & 51 deletions ansible/library/announce_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
TOR_ASN_START = 65500
IPV4_BASE_PORT = 5000
IPV6_BASE_PORT = 6000
AGGREGATE_ROUTES_DEFAULT_VALUE = []
IPV6_ADDRESS_PATTERN_DEFAULT_VALUE = '20%02X:%02X%02X:0:%02X::/64'
ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE = True
ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE = True

# Describe default number of COLOs
COLO_NUMBER = 30
Expand Down Expand Up @@ -332,7 +336,8 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start, nexthop,
nexthop_v6, tor_subnet_size, max_tor_subnet_number, topo,
router_type="leaf", tor_index=None, set_num=None,
no_default_route=False, core_ra_asn=CORE_RA_ASN):
no_default_route=False, core_ra_asn=CORE_RA_ASN,
ipv6_address_pattern=IPV6_ADDRESS_PATTERN_DEFAULT_VALUE):
routes = []
if not no_default_route and router_type != "tor":
default_route_as_path = get_uplink_router_as_path(
Expand Down Expand Up @@ -420,7 +425,7 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,

prefix = "{}.{}.{}.{}/{}".format(octet1,
octet2, octet3, octet4, prefixlen_v4)
prefix_v6 = "20%02X:%02X%02X:0:%02X::/64" % (
prefix_v6 = ipv6_address_pattern % (
octet1, octet2, octet3, octet4)

leaf_asn = leaf_asn_start + podset
Expand Down Expand Up @@ -465,24 +470,41 @@ def fib_t0(topo, ptf_ip, no_default_route=False, action="announce"):
spine_asn = common_config.get("spine_asn", SPINE_ASN)
leaf_asn_start = common_config.get("leaf_asn_start", LEAF_ASN_START)
tor_asn_start = common_config.get("tor_asn_start", TOR_ASN_START)
ipv6_address_pattern = common_config.get("ipv6_address_pattern", IPV6_ADDRESS_PATTERN_DEFAULT_VALUE)
enable_ipv6_routes_generation = common_config.get("enable_ipv6_routes_generation",
ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE)
enable_ipv4_routes_generation = common_config.get("enable_ipv4_routes_generation",
ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE)

vms = topo['topology']['VMs']
for vm in vms.values():
for vm_name, vm in vms.items():
vm_offset = vm['vm_offset']
port = IPV4_BASE_PORT + vm_offset
port6 = IPV6_BASE_PORT + vm_offset
aggregate_prefixes = topo['configuration'][vm_name].get("aggregate_routes", AGGREGATE_ROUTES_DEFAULT_VALUE)
aggregate_routes = [(prefix, nhipv4 if "." in prefix else nhipv6, "") for prefix in aggregate_prefixes]
aggregate_routes_v4 = get_ipv4_routes(aggregate_routes)
aggregate_routes_v6 = get_ipv6_routes(aggregate_routes)

routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv4, nhipv4, tor_subnet_size, max_tor_subnet_number, "t0",
no_default_route=no_default_route)
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv6, nhipv6, tor_subnet_size, max_tor_subnet_number, "t0",
no_default_route=no_default_route)

change_routes(action, ptf_ip, port, routes_v4)
change_routes(action, ptf_ip, port6, routes_v6)
if enable_ipv4_routes_generation:
routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv4, nhipv4, tor_subnet_size, max_tor_subnet_number, "t0",
no_default_route=no_default_route)
if aggregate_routes_v4:
filterout_subnet_ipv4(aggregate_routes, routes_v4)
routes_v4.extend(aggregate_routes_v4)
change_routes(action, ptf_ip, port, routes_v4)
if enable_ipv6_routes_generation:
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv6, nhipv6, tor_subnet_size, max_tor_subnet_number, "t0",
no_default_route=no_default_route,
ipv6_address_pattern=ipv6_address_pattern)
if aggregate_routes_v6:
filterout_subnet_ipv6(aggregate_routes, routes_v6)
routes_v6.extend(aggregate_routes_v6)
change_routes(action, ptf_ip, port6, routes_v6)


def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce"):
Expand All @@ -498,6 +520,11 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce"):
nhipv6 = common_config.get("nhipv6", NHIPV6)
leaf_asn_start = common_config.get("leaf_asn_start", LEAF_ASN_START)
tor_asn_start = common_config.get("tor_asn_start", TOR_ASN_START)
ipv6_address_pattern = common_config.get("ipv6_address_pattern", IPV6_ADDRESS_PATTERN_DEFAULT_VALUE)
enable_ipv6_routes_generation = common_config.get("enable_ipv6_routes_generation",
ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE)
enable_ipv4_routes_generation = common_config.get("enable_ipv4_routes_generation",
ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE)

vms = topo['topology']['VMs']
vms_config = topo['configuration']
Expand All @@ -513,6 +540,10 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce"):
vm_offset = vms[k]['vm_offset']
port = IPV4_BASE_PORT + vm_offset
port6 = IPV6_BASE_PORT + vm_offset
aggregate_prefixes = v.get("aggregate_routes", AGGREGATE_ROUTES_DEFAULT_VALUE)
aggregate_routes = [(prefix, nhipv4 if "." in prefix else nhipv6, "") for prefix in aggregate_prefixes]
aggregate_routes_v4 = get_ipv4_routes(aggregate_routes)
aggregate_routes_v6 = get_ipv6_routes(aggregate_routes)

router_type = None
if 'spine' in v['properties']:
Expand All @@ -522,18 +553,27 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce"):
tornum = v.get('tornum', None)
tor_index = tornum - 1 if tornum is not None else None
if router_type:
routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
None, leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t1",
router_type=router_type, tor_index=tor_index,
no_default_route=no_default_route)
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
None, leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t1",
router_type=router_type, tor_index=tor_index,
no_default_route=no_default_route)
change_routes(action, ptf_ip, port, routes_v4)
change_routes(action, ptf_ip, port6, routes_v6)
if enable_ipv4_routes_generation:
routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
None, leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t1",
router_type=router_type, tor_index=tor_index,
no_default_route=no_default_route)
if aggregate_routes_v4:
filterout_subnet_ipv4(aggregate_routes, routes_v4)
routes_v4.extend(aggregate_routes_v4)
change_routes(action, ptf_ip, port, routes_v4)
if enable_ipv6_routes_generation:
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
None, leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t1",
router_type=router_type, tor_index=tor_index,
no_default_route=no_default_route,
ipv6_address_pattern=ipv6_address_pattern)
if aggregate_routes_v6:
filterout_subnet_ipv6(aggregate_routes, routes_v6)
routes_v6.extend(aggregate_routes_v6)
change_routes(action, ptf_ip, port6, routes_v6)

if 'vips' in v:
routes_vips = []
Expand Down Expand Up @@ -925,6 +965,11 @@ def generate_t2_routes(dut_vm_dict, topo, ptf_ip, action="announce"):
leaf_asn_start = common_config.get("leaf_asn_start", LEAF_ASN_START)
tor_asn_start = common_config.get("tor_asn_start", TOR_ASN_START)
core_ra_asn = common_config.get("core_ra_asn", CORE_RA_ASN)
ipv6_address_pattern = common_config.get("ipv6_address_pattern", IPV6_ADDRESS_PATTERN_DEFAULT_VALUE)
enable_ipv6_routes_generation = common_config.get("enable_ipv6_routes_generation",
ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE)
enable_ipv4_routes_generation = common_config.get("enable_ipv4_routes_generation",
ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE)

# generate routes for t1 vms
for a_dut_index in dut_vm_dict:
Expand All @@ -944,6 +989,10 @@ def generate_t2_routes(dut_vm_dict, topo, ptf_ip, action="announce"):
vm_offset = vms[a_vm]['vm_offset']
port = IPV4_BASE_PORT + vm_offset
port6 = IPV6_BASE_PORT + vm_offset
aggregate_prefixes = vms_config[a_vm].get("aggregate_routes", AGGREGATE_ROUTES_DEFAULT_VALUE)
aggregate_routes = [(prefix, nhipv4 if "." in prefix else nhipv6, "") for prefix in aggregate_prefixes]
aggregate_routes_v4 = get_ipv4_routes(aggregate_routes)
aggregate_routes_v6 = get_ipv6_routes(aggregate_routes)

router_type = None
if 'leaf' in vms_config[a_vm]['properties']:
Expand All @@ -954,20 +1003,28 @@ def generate_t2_routes(dut_vm_dict, topo, ptf_ip, action="announce"):
tor_index = None

if router_type:
routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
common_config['dut_asn'], leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t2",
router_type=router_type, tor_index=tor_index, set_num=set_num,
core_ra_asn=core_ra_asn)
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
common_config['dut_asn'], leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t2",
router_type=router_type, tor_index=tor_index, set_num=set_num,
core_ra_asn=core_ra_asn)
random.shuffle(routes_v4)
random.shuffle(routes_v6)
r_set.append((routes_v4, port, action, ptf_ip))
r_set.append((routes_v6, port6, action, ptf_ip))
if enable_ipv4_routes_generation:
routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
common_config['dut_asn'], leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t2",
router_type=router_type, tor_index=tor_index, set_num=set_num,
core_ra_asn=core_ra_asn)
if aggregate_routes_v4:
filterout_subnet_ipv4(aggregate_routes, routes_v4)
routes_v4.extend(aggregate_routes_v4)
random.shuffle(routes_v4)
r_set.append((routes_v4, port, action, ptf_ip))
if enable_ipv6_routes_generation:
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
common_config['dut_asn'], leaf_asn_start, tor_asn_start,
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t2",
router_type=router_type, tor_index=tor_index, set_num=set_num,
core_ra_asn=core_ra_asn, ipv6_address_pattern=ipv6_address_pattern)
if aggregate_routes_v6:
filterout_subnet_ipv6(aggregate_routes, routes_v6)
routes_v6.extend(aggregate_routes_v6)
random.shuffle(routes_v6)
r_set.append((routes_v6, port6, action, ptf_ip))

if 'vips' in vms_config[a_vm]:
routes_vips = []
Expand All @@ -992,6 +1049,11 @@ def fib_t0_mclag(topo, ptf_ip, action="announce"):
spine_asn = common_config.get("spine_asn", SPINE_ASN)
leaf_asn_start = common_config.get("leaf_asn_start", LEAF_ASN_START)
tor_asn_start = common_config.get("tor_asn_start", TOR_ASN_START)
ipv6_address_pattern = common_config.get("ipv6_address_pattern", IPV6_ADDRESS_PATTERN_DEFAULT_VALUE)
enable_ipv6_routes_generation = common_config.get("enable_ipv6_routes_generation",
ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE)
enable_ipv4_routes_generation = common_config.get("enable_ipv4_routes_generation",
ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE)
vms = topo['topology']['VMs']
all_vms = sorted(vms.keys())

Expand All @@ -1005,18 +1067,30 @@ def fib_t0_mclag(topo, ptf_ip, action="announce"):
vm_offset = vms[vm]['vm_offset']
port = IPV4_BASE_PORT + vm_offset
port6 = IPV6_BASE_PORT + vm_offset
aggregate_prefixes = topo['configuration'][vm].get("aggregate_routes", AGGREGATE_ROUTES_DEFAULT_VALUE)
aggregate_routes = [(prefix, nhipv4 if "." in prefix else nhipv6, "") for prefix in aggregate_prefixes]
aggregate_routes_v4 = get_ipv4_routes(aggregate_routes)
aggregate_routes_v6 = get_ipv6_routes(aggregate_routes)

routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv4, nhipv4, tor_subnet_size, max_tor_subnet_number,
"t0-mclag", set_num=set_num)
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv6, nhipv6, tor_subnet_size, max_tor_subnet_number,
"t0-mclag", set_num=set_num)

change_routes(action, ptf_ip, port, routes_v4)
change_routes(action, ptf_ip, port6, routes_v6)
if enable_ipv4_routes_generation:
routes_v4 = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv4, nhipv4, tor_subnet_size, max_tor_subnet_number,
"t0-mclag", set_num=set_num)
if aggregate_routes_v4:
filterout_subnet_ipv4(aggregate_routes, routes_v4)
routes_v4.extend(aggregate_routes_v4)
change_routes(action, ptf_ip, port, routes_v4)
if enable_ipv6_routes_generation:
routes_v6 = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
spine_asn, leaf_asn_start, tor_asn_start,
nhipv6, nhipv6, tor_subnet_size, max_tor_subnet_number,
"t0-mclag", set_num=set_num,
ipv6_address_pattern=ipv6_address_pattern)
if aggregate_routes_v6:
filterout_subnet_ipv6(aggregate_routes, routes_v6)
routes_v6.extend(aggregate_routes_v6)
change_routes(action, ptf_ip, port6, routes_v6)


def fib_dpu(topo, ptf_ip, action="announce"):
Expand All @@ -1040,6 +1114,34 @@ def fib_dpu(topo, ptf_ip, action="announce"):
change_routes(action, ptf_ip, port6, routes_v6)


def get_ipv4_routes(routes):
return [r for r in routes if ipaddress.ip_network(UNICODE_TYPE(r[0])).version == 4]


def get_ipv6_routes(routes):
return [r for r in routes if ipaddress.ip_network(UNICODE_TYPE(r[0])).version == 6]


def filterout_subnet_ipv4(aggregate_routes, candidate_routes):
ars_ipv4 = get_ipv4_routes(aggregate_routes)
return filterout_subnet(ars_ipv4, candidate_routes)


def filterout_subnet_ipv6(aggregate_routes, candidate_routes):
ars_ipv6 = get_ipv6_routes(aggregate_routes)
return filterout_subnet(ars_ipv6, candidate_routes)


def filterout_subnet(aggregate_routes, candidate_routes):
subnets = []
for ar in aggregate_routes:
ar_net = ipaddress.ip_network(UNICODE_TYPE(ar[0]))
for cr in candidate_routes:
if ipaddress.ip_network(UNICODE_TYPE(cr[0])).subnet_of(ar_net):
subnets.append(cr)
return list(set(candidate_routes) - set(subnets))


def main():
module = AnsibleModule(
argument_spec=dict(
Expand Down
Loading

0 comments on commit aca0f87

Please sign in to comment.