Skip to content

Commit 280ab6f

Browse files
yaqiangzAharonMalkin
authored andcommitted
[bgp_scale] Fix announce_routes for t1-isolated topo (sonic-net#19117)
What is the motivation for this PR? Fix incorrect route announcing in isolated T1 topos How did you do it? For announce_routes.py, update to announce correct routes Announce more routes, details: [doc] Update announce_routes doc for isolated T1 sonic-net#19128 Add support to announce different sets from downstream For test_ipv6_bgp_scale, because T0 and T2 would both announce default routes, but T0s' has the shorter as path. Hence by default there are only default routes from T0s taking effect. In test, after shutdown all T0 neighbor ports, default routes wouldn't disappear, but default routes from T2 would appear. Hence update routes verification here. How did you verify/test it? Run tests Signed-off-by: Aharon Malkin <[email protected]>
1 parent db0f555 commit 280ab6f

File tree

9 files changed

+130
-27
lines changed

9 files changed

+130
-27
lines changed

ansible/library/announce_routes.py

Lines changed: 108 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@
7676
IPV6_ADDRESS_PATTERN_DEFAULT_VALUE = '20%02X:%02X%02X:0:%02X::/64'
7777
ENABLE_IPV4_ROUTES_GENERATION_DEFAULT_VALUE = True
7878
ENABLE_IPV6_ROUTES_GENERATION_DEFAULT_VALUE = True
79+
BGP_SCALE_T1S = [
80+
't1-isolated-d254u2', 't1-isolated-d254u2s1', 't1-isolated-d254u2s2',
81+
't1-isolated-d510u2', 't1-isolated-d510u2s2'
82+
]
7983

8084
# Describe default number of COLOs
8185
COLO_NUMBER = 30
@@ -105,6 +109,8 @@
105109
M0_SUBNET_PREFIX_LEN_V6 = 64
106110
# Describe default start asn of M1s
107111
M1_ASN_START = 65200
112+
# Describe default leaf number
113+
LEAF_NUMBER = 256
108114

109115

110116
def wait_for_http(host_ip, http_port, timeout=10):
@@ -481,6 +487,30 @@ def generate_routes(family, podset_number, tor_number, tor_subnet_number,
481487
return routes, suffix
482488

483489

490+
def generate_t1_to_t0_routes(family, offset, leaf_number, subnet_size, tor_asn, leaf_asn_start, nexthop, nexthop_v6,
491+
podset_num=1, ipv6_address_pattern=IPV6_ADDRESS_PATTERN_DEFAULT_VALUE):
492+
routes = []
493+
for podset in range(0, podset_num):
494+
for leaf in range(0, leaf_number):
495+
suffix = offset + leaf
496+
octet2 = (168 + int(suffix / (256 ** 2)))
497+
octet1 = (192 + int(octet2 / 256))
498+
octet2 = (octet2 % 256)
499+
octet3 = (int(suffix / 256) % 256)
500+
octet4 = (suffix % 256)
501+
prefixlen_v4 = (32 - int(math.log(subnet_size, 2)))
502+
prefix = "{}.{}.{}.{}/{}".format(octet1, octet2, octet3, octet4, prefixlen_v4)
503+
prefix_v6 = ipv6_address_pattern % (
504+
octet1, octet2, octet3, octet4)
505+
leaf_asn = leaf_asn_start + podset
506+
aspath = "{} {}".format(leaf_asn, tor_asn)
507+
if family in ["v4", "both"]:
508+
routes.append((prefix, nexthop, aspath))
509+
if family in ["v6", "both"]:
510+
routes.append((prefix_v6, nexthop_v6, aspath))
511+
return routes, suffix
512+
513+
484514
def fib_t0(topo, ptf_ip, no_default_route=False, action="announce", upstream_neighbor_groups=0):
485515
common_config = topo['configuration_properties'].get('common', {})
486516
podset_number = common_config.get("podset_number", PODSET_NUMBER)
@@ -547,7 +577,8 @@ def fib_t0(topo, ptf_ip, no_default_route=False, action="announce", upstream_nei
547577
current_routes_offset += last_suffix
548578

549579

550-
def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce", tor_default_route=False):
580+
def fib_t1_lag(topo, ptf_ip, topo_name, no_default_route=False, action="announce", tor_default_route=False,
581+
downstream_neighbor_groups=0):
551582
common_config = topo['configuration_properties'].get('common', {})
552583
podset_number = common_config.get("podset_number", PODSET_NUMBER)
553584
tor_number = common_config.get("tor_number", TOR_NUMBER)
@@ -573,13 +604,22 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce", tor_defa
573604
if 'DPUs' in topo['topology']:
574605
dpus = topo['topology']['DPUs']
575606

607+
last_suffix = 0
608+
if topo_name in BGP_SCALE_T1S:
609+
tor_default_route = True
610+
routes_to_change = {}
576611
for k, v in vms_config.items():
612+
curr_no_default_route = no_default_route
613+
if topo_name in BGP_SCALE_T1S and 'spine' in v['properties']:
614+
curr_no_default_route = True
577615
if dpus and k in dpus:
578616
continue
579617

580618
vm_offset = vms[k]['vm_offset']
581619
port = IPV4_BASE_PORT + vm_offset
582620
port6 = IPV6_BASE_PORT + vm_offset
621+
routes_to_change[port] = []
622+
routes_to_change[port6] = []
583623
aggregate_prefixes = v.get("aggregate_routes", AGGREGATE_ROUTES_DEFAULT_VALUE)
584624
aggregate_routes = [(prefix, nhipv4 if "." in prefix else nhipv6, "") for prefix in aggregate_prefixes]
585625
aggregate_routes_v4 = get_ipv4_routes(aggregate_routes)
@@ -594,33 +634,80 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce", tor_defa
594634
tor_index = tornum - 1 if tornum is not None else None
595635
if router_type:
596636
if enable_ipv4_routes_generation:
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)
637+
routes_v4, last_suffix = generate_routes("v4", podset_number, tor_number, tor_subnet_number,
638+
None, leaf_asn_start, tor_asn_start,
639+
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t1",
640+
router_type=router_type, tor_index=tor_index,
641+
no_default_route=curr_no_default_route,
642+
tor_default_route=tor_default_route)
602643
if aggregate_routes_v4:
603644
filterout_subnet_ipv4(aggregate_routes, routes_v4)
604645
routes_v4.extend(aggregate_routes_v4)
605-
change_routes(action, ptf_ip, port, routes_v4)
646+
routes_to_change[port] += routes_v4
606647
if enable_ipv6_routes_generation:
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)
648+
routes_v6, last_suffix = generate_routes("v6", podset_number, tor_number, tor_subnet_number,
649+
None, leaf_asn_start, tor_asn_start,
650+
nhipv4, nhipv6, tor_subnet_size, max_tor_subnet_number, "t1",
651+
router_type=router_type, tor_index=tor_index,
652+
no_default_route=curr_no_default_route,
653+
ipv6_address_pattern=ipv6_address_pattern,
654+
tor_default_route=tor_default_route)
614655
if aggregate_routes_v6:
615656
filterout_subnet_ipv6(aggregate_routes, routes_v6)
616657
routes_v6.extend(aggregate_routes_v6)
617-
change_routes(action, ptf_ip, port6, routes_v6)
658+
routes_to_change[port6] += routes_v6
618659

619660
if 'vips' in v:
620661
routes_vips = []
621662
for prefix in v["vips"]["ipv4"]["prefixes"]:
622663
routes_vips.append((prefix, nhipv4, v["vips"]["ipv4"]["asn"]))
623-
change_routes(action, ptf_ip, port, routes_vips)
664+
routes_to_change[port] += routes_vips
665+
if topo_name in BGP_SCALE_T1S:
666+
if downstream_neighbor_groups == 0:
667+
downstream_neighbor_groups = common_config.get("downstream_neighbor_groups", DEFAULT_NEIGHBOR_GROUPS)
668+
669+
# Announce T1 loopback received in T0
670+
leaf_number = common_config.get("leaf_number", LEAF_NUMBER)
671+
tor_number = len([k for k, v in vms_config.items() if 'tor' in v['properties']])
672+
lov6_address_pattern = ipv6_address_pattern.split("/")[0] + "/128"
673+
current_routes_offset = last_suffix
674+
for index, (k, v) in enumerate(vms_config.items()):
675+
if dpus and k in dpus:
676+
continue
677+
vm_offset = vms[k]['vm_offset']
678+
port = IPV4_BASE_PORT + vm_offset
679+
port6 = IPV6_BASE_PORT + vm_offset
680+
aggregate_prefixes = v.get("aggregate_routes", AGGREGATE_ROUTES_DEFAULT_VALUE)
681+
aggregate_routes = [(prefix, nhipv4 if "." in prefix else nhipv6, "") for prefix in aggregate_prefixes]
682+
aggregate_routes_v4 = get_ipv4_routes(aggregate_routes)
683+
aggregate_routes_v6 = get_ipv6_routes(aggregate_routes)
684+
if 'spine' in v['properties']:
685+
continue
686+
tor_asn = tor_asn_start + index
687+
if enable_ipv4_routes_generation:
688+
routes_v4, last_suffix = generate_t1_to_t0_routes("v4", current_routes_offset, leaf_number, 1, tor_asn,
689+
leaf_asn_start, nhipv4, nhipv6,
690+
ipv6_address_pattern=lov6_address_pattern)
691+
if aggregate_routes_v4:
692+
filterout_subnet_ipv4(aggregate_routes, routes_v4)
693+
routes_v4.extend(aggregate_routes_v4)
694+
routes_to_change[port] += routes_v4
695+
if enable_ipv6_routes_generation:
696+
routes_v6, last_suffix = generate_t1_to_t0_routes("v6", current_routes_offset, leaf_number, 1, tor_asn,
697+
leaf_asn_start, nhipv6, nhipv6,
698+
ipv6_address_pattern=lov6_address_pattern)
699+
if aggregate_routes_v6:
700+
filterout_subnet_ipv6(aggregate_routes, routes_v6)
701+
routes_v6.extend(aggregate_routes_v6)
702+
routes_to_change[port6] += routes_v6
703+
group_index = index * downstream_neighbor_groups // tor_number
704+
next_group_index = (index + 1) * downstream_neighbor_groups // tor_number
705+
if group_index != next_group_index:
706+
current_routes_offset += last_suffix
707+
for port, routes in routes_to_change.items():
708+
if len(routes) <= 0:
709+
continue
710+
change_routes(action, ptf_ip, port, routes)
624711

625712

626713
def get_new_ip(curr_ip, skip_count):
@@ -1474,7 +1561,8 @@ def main():
14741561
adhoc=dict(required=False, type='bool', default=False),
14751562
peers_routes_to_change=dict(required=False, type='dict', default={}),
14761563
log_path=dict(required=False, type='str', default=''),
1477-
upstream_neighbor_groups=dict(required=False, type='int', default=0)
1564+
upstream_neighbor_groups=dict(required=False, type='int', default=0),
1565+
downstream_neighbor_groups=dict(required=False, type='int', default=0)
14781566
),
14791567
supports_check_mode=False)
14801568

@@ -1489,6 +1577,7 @@ def main():
14891577
adhoc = module.params['adhoc']
14901578
peers_routes_to_change = module.params['peers_routes_to_change']
14911579
upstream_neighbor_groups = module.params['upstream_neighbor_groups']
1580+
downstream_neighbor_groups = module.params['downstream_neighbor_groups']
14921581

14931582
topo = read_topo(topo_name, path)
14941583
if not topo:
@@ -1514,7 +1603,8 @@ def main():
15141603
module.exit_json(changed=True)
15151604
elif topo_type == "t1" or topo_type == "smartswitch-t1":
15161605
fib_t1_lag(
1517-
topo, ptf_ip, no_default_route=is_storage_backend, action=action, tor_default_route=tor_default_route)
1606+
topo, ptf_ip, topo_name, no_default_route=is_storage_backend, action=action,
1607+
tor_default_route=tor_default_route, downstream_neighbor_groups=downstream_neighbor_groups)
15181608
module.exit_json(changed=True)
15191609
elif topo_type == "t2":
15201610
fib_t2_lag(topo, ptf_ip, action=action)

ansible/roles/vm_set/tasks/announce_routes.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
topo_name: "{{ topo }}"
127127
ptf_ip: "{{ ptf_host_ip }}"
128128
dut_interfaces: "{{ dut_interfaces | default('') }}"
129-
upstream_neighbor_groups: "{{ upstream_neighbor_groups | int }}"
129+
upstream_neighbor_groups: "{{ upstream_neighbor_groups | default(0) | int }}"
130+
downstream_neighbor_groups: "{{ downstream_neighbor_groups | default(0) | int }}"
130131
delegate_to: localhost
131132
when: exabgp_action == 'start'

ansible/testbed-cli.sh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ function read_yaml
142142

143143
tb_line=${tb_lines[0]}
144144
line_arr=($1)
145-
for attr in group-name topo ptf_image_name ptf ptf_ip ptf_ipv6 ptf_extra_mgmt_ip netns_mgmt_ip server vm_base dut inv_name auto_recover comment servers upstream_neighbor_groups;
145+
for attr in group-name topo ptf_image_name ptf ptf_ip ptf_ipv6 ptf_extra_mgmt_ip netns_mgmt_ip server vm_base dut inv_name auto_recover comment servers upstream_neighbor_groups downstream_neighbor_groups;
146146
do
147147
value=$(python -c "from __future__ import print_function; tb=eval(\"$tb_line\"); print(tb.get('$attr', None))")
148148
[ "$value" == "None" ] && value=
@@ -167,6 +167,7 @@ function read_yaml
167167
inv_name=${line_arr[12]}
168168
servers=${line_arr[15]}
169169
upstream_neighbor_groups=${line_arr[16]}
170+
downstream_neighbor_groups=${line_arr[17]}
170171
# Remove the dpu duts by the keyword 'dpu' in the dut name
171172
duts=$(echo $duts | sed "s/,[^,]*dpu[^,]*//g")
172173
}
@@ -320,7 +321,7 @@ function add_topo
320321
-e ptf_ip="$ptf_ip" -e topo="$topo" -e vm_set_name="$vm_set_name" \
321322
-e ptf_imagename="$ptf_imagename" -e vm_type="$vm_type" -e ptf_ipv6="$ptf_ipv6" \
322323
-e ptf_extra_mgmt_ip="$ptf_extra_mgmt_ip" -e netns_mgmt_ip="$netns_mgmt_ip" \
323-
-e upstream_neighbor_groups="$upstream_neighbor_groups" \
324+
-e upstream_neighbor_groups="$upstream_neighbor_groups" -e downstream_neighbor_groups="$downstream_neighbor_groups" \
324325
$ansible_options $@
325326

326327
if [ $i -eq 0 ]; then
@@ -442,7 +443,7 @@ function renumber_topo
442443
ANSIBLE_SCP_IF_SSH=y ansible-playbook -i $vmfile testbed_renumber_vm_topology.yml --vault-password-file="${passwd}" \
443444
-l "$server" -e testbed_name="$testbed_name" -e duts_name="$duts" -e VM_base="$vm_base" -e ptf_ip="$ptf_ip" \
444445
-e topo="$topo" -e vm_set_name="$vm_set_name" -e ptf_imagename="$ptf_imagename" -e ptf_ipv6="$ptf_ipv6" \
445-
-e upstream_neighbor_groups="$upstream_neighbor_groups" \
446+
-e upstream_neighbor_groups="$upstream_neighbor_groups" -e downstream_neighbor_groups="$downstream_neighbor_groups" \
446447
-e ptf_extra_mgmt_ip="$ptf_extra_mgmt_ip" $@
447448

448449
ansible-playbook fanout_connect.yml -i $vmfile --limit "$server" --vault-password-file="${passwd}" -e "dut=$duts" $@
@@ -492,7 +493,7 @@ function refresh_dut
492493
-e ptf_ip="$ptf_ip" -e topo="$topo" -e vm_set_name="$vm_set_name" \
493494
-e ptf_imagename="$ptf_imagename" -e vm_type="$vm_type" -e ptf_ipv6="$ptf_ipv6" \
494495
-e ptf_extra_mgmt_ip="$ptf_extra_mgmt_ip" -e force_stop_sonic_vm="yes" \
495-
-e upstream_neighbor_groups="$upstream_neighbor_groups" \
496+
-e upstream_neighbor_groups="$upstream_neighbor_groups" -e downstream_neighbor_groups="$downstream_neighbor_groups" \
496497
$ansible_options $@
497498

498499
echo Done

ansible/vars/topo_t1-isolated-d254u2.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,7 @@ configuration_properties:
10381038
ipv6_address_pattern: FC00:C:C::%02X%02X:%02X%02X:0/120
10391039
enable_ipv4_routes_generation: false
10401040
enable_ipv6_routes_generation: true
1041+
leaf_number: 256
10411042
spine:
10421043
swrole: spine
10431044
tor:

ansible/vars/topo_t1-isolated-d254u2s1.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ configuration_properties:
10421042
ipv6_address_pattern: FC00:C:C::%02X%02X:%02X%02X:0/120
10431043
enable_ipv4_routes_generation: false
10441044
enable_ipv6_routes_generation: true
1045+
leaf_number: 256
10451046
spine:
10461047
swrole: spine
10471048
tor:

ansible/vars/topo_t1-isolated-d254u2s2.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,7 @@ configuration_properties:
10461046
ipv6_address_pattern: FC00:C:C::%02X%02X:%02X%02X:0/120
10471047
enable_ipv4_routes_generation: false
10481048
enable_ipv6_routes_generation: true
1049+
leaf_number: 256
10491050
spine:
10501051
swrole: spine
10511052
tor:

ansible/vars/topo_t1-isolated-d510u2.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,8 @@ configuration_properties:
20622062
ipv6_address_pattern: FC00:C:C::%02X%02X:%02X%02X:0/120
20632063
enable_ipv4_routes_generation: false
20642064
enable_ipv6_routes_generation: true
2065+
leaf_number: 512
2066+
downstream_neighbor_groups: 2
20652067
spine:
20662068
swrole: spine
20672069
tor:

ansible/vars/topo_t1-isolated-d510u2s2.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,8 @@ configuration_properties:
20702070
ipv6_address_pattern: FC00:C:C::%02X%02X:%02X%02X:0/120
20712071
enable_ipv4_routes_generation: false
20722072
enable_ipv6_routes_generation: true
2073+
leaf_number: 256
2074+
downstream_neighbor_groups: 2
20732075
spine:
20742076
swrole: spine
20752077
tor:

tests/bgp/test_ipv6_bgp_scale.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
pytestmark = [
2020
pytest.mark.topology(
2121
't0-isolated-d2u254s1', 't0-isolated-d2u254s2', 't0-isolated-d2u510',
22-
't1-isolated-d254u2s1', 't1-isolated-d254u2s2', 't1-isolated-d510u2'
22+
't1-isolated-d254u2s1', 't1-isolated-d254u2s2', 't1-isolated-d510u2',
23+
't1-isolated-d254u2', 't1-isolated-d510u2s2'
2324
)
2425
]
2526

@@ -131,7 +132,8 @@ def announce_routes(localhost, tbinfo, ptf_ip, dut_interfaces):
131132
path="../ansible/",
132133
log_path="logs",
133134
dut_interfaces=dut_interfaces,
134-
upstream_neighbor_groups=tbinfo['upstream_neighbor_groups'] if 'upstream_neighbor_groups' in tbinfo else None
135+
upstream_neighbor_groups=tbinfo['upstream_neighbor_groups'] if 'upstream_neighbor_groups' in tbinfo else 0,
136+
downstream_neighbor_groups=tbinfo['downstream_neighbor_groups'] if 'downstream_neighbor_groups' in tbinfo else 0
135137
)
136138

137139

@@ -144,7 +146,8 @@ def get_all_bgp_ipv6_routes(duthost):
144146
def generate_packets(prefixes, dut_mac, src_mac):
145147
pkts = []
146148
for prefix in prefixes:
147-
addr = str(ipaddress.ip_network(prefix)[1])
149+
network = ipaddress.ip_network(prefix)
150+
addr = str(network[0] if network.num_addresses == 1 else network[1])
148151
pkt = simple_icmpv6_packet(
149152
eth_dst=dut_mac,
150153
eth_src=src_mac,
@@ -514,7 +517,8 @@ def test_device_unisolation(
514517
ptfadapter,
515518
bgp_peers_info,
516519
setup_packet_mask_counters,
517-
announce_bgp_routes_teardown
520+
announce_bgp_routes_teardown,
521+
tbinfo
518522
):
519523
'''
520524
This test is for the worst senario that all ports are flapped,

0 commit comments

Comments
 (0)