Skip to content

Commit

Permalink
Add t1-smartswitch topo support (#14595)
Browse files Browse the repository at this point in the history
This PR is to add t1-smartswitch support.

add a t1-smartswich definition
add extra step start_dpu_vm to create sonic-vs neighbor to mimic DPUs
update vm_topology to bind DPUs interfaces to the bridges too
update annouce_route modules to create exabgp processes on PTF for DPU neighbors too. Refer testbed routing for details.
update topo_facts and config_sonic_basedon_testbed modules to update gen-mg logics

sign-off: Jing Zhang [email protected]
  • Loading branch information
zjswhhh authored Dec 3, 2024
1 parent 0d9f53c commit 7fb6741
Show file tree
Hide file tree
Showing 23 changed files with 1,520 additions and 75 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ ansible/*_tmp
.idea/

.python-version

sonic-dump/
7 changes: 7 additions & 0 deletions ansible/library/announce_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,14 @@ def fib_t1_lag(topo, ptf_ip, no_default_route=False, action="announce"):
vms = topo['topology']['VMs']
vms_config = topo['configuration']

dpus = None
if 'DPUs' in topo['topology']:
dpus = topo['topology']['DPUs']

for k, v in vms_config.items():
if dpus and k in dpus:
continue

vm_offset = vms[k]['vm_offset']
port = IPV4_BASE_PORT + vm_offset
port6 = IPV6_BASE_PORT + vm_offset
Expand Down
20 changes: 20 additions & 0 deletions ansible/library/testbed_vm_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ def get_neighbor_eos(self):
eos[eos_name] = vm_name
return eos

def get_neighbor_dpu(self):
dpu = {}
with open(self.topofile) as f:
vm_topology = yaml.safe_load(f)
self.topoall = vm_topology

if len(self.base_vm) > 2:
vm_start_index = int(self.base_vm[2:])
vm_name_fmt = 'VM%0{}d'.format(len(self.base_vm) - 2)

if 'DPUs' not in vm_topology['topology']:
return dpu

for dpu_name, dpu_value in vm_topology['topology']['DPUs'].items():
vm_name = vm_name_fmt % (vm_start_index + dpu_value['vm_offset'])
dpu[dpu_name] = vm_name

return dpu

def gather_veos_vms(self):
yaml_data = {}
with open(self.vm_file, 'r') as default_f:
Expand Down Expand Up @@ -111,6 +130,7 @@ def main():
vm_facts = TestbedVMFacts(
m_args['topo'], m_args['base_vm'], m_args['vm_file'])
neighbor_eos = vm_facts.get_neighbor_eos()
neighbor_eos.update(vm_facts.get_neighbor_dpu())
if has_dataloader:
hosts = vm_facts.inv_mgr.hosts
else:
Expand Down
70 changes: 43 additions & 27 deletions ansible/library/topo_facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs
dut_index = 0
for asic_intf in topo_definition['topology'][neigh_type][vm]['asic_intfs']:
vmconfig[vm]['asic_intfs'][dut_index].append(asic_intf)
if neigh_type == 'DPUs':
vmconfig[vm]['interface_indexes'] = [[]
for i in range(dut_num)]
for vlan in topo_definition['topology'][neigh_type][vm]['vlans']:
(dut_index, vlan_index, _) = parse_vm_vlan_port(vlan)
vmconfig[vm]['interface_indexes'][dut_index].append(
vlan_index)

# physical interface
if 'configuration' in topo_definition:
Expand All @@ -131,13 +138,13 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs
vmconfig[vm]['intfs'][dut_index].append(intf)

# ip interface
vmconfig[vm]['ip_intf'] = [None] * dut_num
vmconfig[vm]['peer_ipv4'] = [None] * dut_num
vmconfig[vm]['ipv4mask'] = [None] * dut_num
vmconfig[vm]['peer_ipv6'] = [None] * dut_num
vmconfig[vm]['ipv6mask'] = [None] * dut_num
vmconfig[vm]['bgp_ipv4'] = [None] * dut_num
vmconfig[vm]['bgp_ipv6'] = [None] * dut_num
vmconfig[vm]['ip_intf'] = [[] for _ in range(dut_num)]
vmconfig[vm]['peer_ipv4'] = [[] for _ in range(dut_num)]
vmconfig[vm]['ipv4mask'] = [[] for _ in range(dut_num)]
vmconfig[vm]['peer_ipv6'] = [[] for _ in range(dut_num)]
vmconfig[vm]['ipv6mask'] = [[] for _ in range(dut_num)]
vmconfig[vm]['bgp_ipv4'] = [[] for _ in range(dut_num)]
vmconfig[vm]['bgp_ipv6'] = [[] for _ in range(dut_num)]
vmconfig[vm]['bgp_asn'] = None

if 'configuration' in topo_definition:
Expand All @@ -159,18 +166,21 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs
(peer_ipv4, ipv4_mask) = \
topo_definition['configuration'][vm]['interfaces'][intf]['ipv4'].split(
'/')
vmconfig[vm]['peer_ipv4'][dut_index] = peer_ipv4
vmconfig[vm]['ipv4mask'][dut_index] = ipv4_mask
vmconfig[vm]['ip_intf'][dut_index] = intf
vmconfig[vm]['peer_ipv4'][dut_index].append(peer_ipv4)
vmconfig[vm]['ipv4mask'][dut_index].append(ipv4_mask)
if intf not in vmconfig[vm]['ip_intf'][dut_index]:
vmconfig[vm]['ip_intf'][dut_index].append(intf)

if (isinstance(topo_definition['configuration'][vm]['interfaces'], dict)
and 'ipv6' in topo_definition['configuration'][vm]['interfaces'][intf]
and ('loopback' not in intf.lower())):
(ipv6_addr, ipv6_mask) = \
topo_definition['configuration'][vm]['interfaces'][intf]['ipv6'].split(
'/')
vmconfig[vm]['peer_ipv6'][dut_index] = ipv6_addr.upper()
vmconfig[vm]['ipv6mask'][dut_index] = ipv6_mask
vmconfig[vm]['ip_intf'][dut_index] = intf
vmconfig[vm]['peer_ipv6'][dut_index].append(ipv6_addr.upper())
vmconfig[vm]['ipv6mask'][dut_index].append(ipv6_mask)
if intf not in vmconfig[vm]['ip_intf'][dut_index]:
vmconfig[vm]['ip_intf'][dut_index].append(intf)

# Configuration is provided via init_cfg_profile, no need to go through the topo file
if "init_cfg_profile" in topo_definition['configuration'][vm]:
Expand All @@ -191,39 +201,41 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs
if ip.version == 4:
# Each VM might not be connected to all the DUT's,
# so check if this VM is a peer to DUT at dut_index
if vmconfig[vm]['peer_ipv4'][dut_index]:
for peer_ipv4_idx in range(len(vmconfig[vm]['peer_ipv4'][dut_index])):
ipsubnet_str = \
vmconfig[vm]['peer_ipv4'][dut_index] + \
'/'+vmconfig[vm]['ipv4mask'][dut_index]
vmconfig[vm]['peer_ipv4'][dut_index][peer_ipv4_idx] + \
'/'+vmconfig[vm]['ipv4mask'][dut_index][peer_ipv4_idx]
if sys.version_info < (3, 0):
ipsubnet = ipaddress.ip_interface(
ipsubnet_str.decode('utf8'))
else:
ipsubnet = ipaddress.ip_interface(
ipsubnet_str)
if ip in ipsubnet.network:
vmconfig[vm]['bgp_ipv4'][dut_index] = ipstr.upper()
elif neigh_type == "NEIGH_ASIC":
vmconfig[vm]['bgp_ipv4'][dut_index] = ipstr.upper()
vmconfig[vm]['ipv4mask'][dut_index] = ip_mask if ip_mask else '32'
vmconfig[vm]['bgp_ipv4'][dut_index].append(ipstr.upper())
if (not vmconfig[vm]['peer_ipv4'][dut_index]) and neigh_type == "NEIGH_ASIC":
vmconfig[vm]['bgp_ipv4'][dut_index].append(ipstr.upper())
vmconfig[vm]['ipv4mask'][dut_index].append(ip_mask if ip_mask else '32')

elif ip.version == 6:
# Each VM might not be connected to all the DUT's,
# so check if this VM is a peer to DUT at dut_index
if vmconfig[vm]['peer_ipv6'][dut_index]:
for peer_ipv6_idx in range(len(vmconfig[vm]['peer_ipv6'][dut_index])):
ipsubnet_str = \
vmconfig[vm]['peer_ipv6'][dut_index] + \
'/'+vmconfig[vm]['ipv6mask'][dut_index]
vmconfig[vm]['peer_ipv6'][dut_index][peer_ipv6_idx] + \
'/'+vmconfig[vm]['ipv6mask'][dut_index][peer_ipv6_idx]
if sys.version_info < (3, 0):
ipsubnet = ipaddress.ip_interface(
ipsubnet_str.decode('utf8'))
else:
ipsubnet = ipaddress.ip_interface(
ipsubnet_str)
if ip in ipsubnet.network:
vmconfig[vm]['bgp_ipv6'][dut_index] = ipstr.upper()
elif neigh_type == "NEIGH_ASIC":
vmconfig[vm]['bgp_ipv6'][dut_index] = ipstr.upper()
vmconfig[vm]['ipv6mask'][dut_index] = ip_mask if ip_mask else '128'
vmconfig[vm]['bgp_ipv6'][dut_index].append(ipstr.upper())
if (not vmconfig[vm]['peer_ipv6'][dut_index]) and neigh_type == "NEIGH_ASIC":
vmconfig[vm]['bgp_ipv6'][dut_index].append(ipstr.upper())
vmconfig[vm]['ipv6mask'][dut_index].append(ip_mask if ip_mask else '128')

return vmconfig

def get_topo_config(self, topo_name, hwsku, testbed_name, asics_present, card_type):
Expand Down Expand Up @@ -285,6 +297,10 @@ def get_topo_config(self, topo_name, hwsku, testbed_name, asics_present, card_ty
vm_topo_config['vm'] = self.parse_topo_defintion(
topo_definition, po_map, dut_num, 'VMs')

if 'DPUs' in topo_definition['topology']:
vm_topo_config['vm'].update(self.parse_topo_defintion(
topo_definition, po_map, dut_num, 'DPUs'))

if 'cable' in topo_name:
dut_asn = topo_definition['configuration_properties']['common']['dut_asn']
vm_topo_config['dut_type'] = topo_definition['configuration_properties']['common']['dut_type']
Expand Down
Loading

0 comments on commit 7fb6741

Please sign in to comment.