-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VoQ configuration using minigraph.xml file #5991
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -456,6 +456,17 @@ def parse_dpg(dpg, hname): | |
gwaddr = ipaddress.ip_address(next(mgmtipn.hosts())) | ||
mgmt_intf[(intfname, ipprefix)] = {'gwaddr': gwaddr} | ||
|
||
voqinbandintfs = child.find(str(QName(ns, "VoqInbandInterfaces"))) | ||
voq_inband_intfs = {} | ||
if voqinbandintfs: | ||
for voqintf in voqinbandintfs.findall(str(QName(ns1, "VoqInbandInterface"))): | ||
intfname = voqintf.find(str(QName(ns, "Name"))).text | ||
intftype = voqintf.find(str(QName(ns, "Type"))).text | ||
ipprefix = voqintf.find(str(QName(ns1, "PrefixStr"))).text | ||
if intfname not in voq_inband_intfs: | ||
voq_inband_intfs[intfname] = {'inband_type': intftype} | ||
voq_inband_intfs["%s|%s" % (intfname, ipprefix)] = {} | ||
|
||
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) | ||
pc_intfs = [] | ||
pcs = {} | ||
|
@@ -667,8 +678,8 @@ def parse_dpg(dpg, hname): | |
if mg_key in mg_tunnel.attrib: | ||
tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key] | ||
|
||
return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content | ||
return None, None, None, None, None, None, None, None, None, None | ||
return intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content | ||
return None, None, None, None, None, None, None, None, None, None, None, None, None | ||
|
||
def parse_host_loopback(dpg, hname): | ||
for child in dpg: | ||
|
@@ -794,6 +805,9 @@ def parse_meta(meta, hname): | |
cloudtype = None | ||
resource_type = None | ||
downstream_subrole = None | ||
switch_id = None | ||
switch_type = None | ||
max_cores = None | ||
kube_data = {} | ||
device_metas = meta.find(str(QName(ns, "Devices"))) | ||
for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): | ||
|
@@ -825,11 +839,17 @@ def parse_meta(meta, hname): | |
resource_type = value | ||
elif name == "DownStreamSubRole": | ||
downstream_subrole = value | ||
elif name == "SwitchId": | ||
switch_id = value | ||
elif name == "SwitchType": | ||
switch_type = value | ||
elif name == "MaxCores": | ||
max_cores = value | ||
elif name == "KubernetesEnabled": | ||
kube_data["enable"] = value | ||
elif name == "KubernetesServerIp": | ||
kube_data["ip"] = value | ||
return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data | ||
return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data | ||
|
||
|
||
def parse_linkmeta(meta, hname): | ||
|
@@ -886,6 +906,9 @@ def parse_linkmeta(meta, hname): | |
|
||
def parse_asic_meta(meta, hname): | ||
sub_role = None | ||
switch_id = None | ||
switch_type = None | ||
max_cores = None | ||
device_metas = meta.find(str(QName(ns, "Devices"))) | ||
for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): | ||
if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): | ||
|
@@ -895,7 +918,13 @@ def parse_asic_meta(meta, hname): | |
value = device_property.find(str(QName(ns1, "Value"))).text | ||
if name == "SubRole": | ||
sub_role = value | ||
return sub_role | ||
elif name == "SwitchId": | ||
switch_id = value | ||
elif name == "SwitchType": | ||
switch_type = value | ||
elif name == "MaxCores": | ||
max_cores = value | ||
return sub_role, switch_id, switch_type, max_cores | ||
|
||
def parse_deviceinfo(meta, hwsku): | ||
port_speeds = {} | ||
|
@@ -912,7 +941,28 @@ def parse_deviceinfo(meta, hwsku): | |
if desc != None: | ||
port_descriptions[port_alias_map.get(alias, alias)] = desc.text | ||
port_speeds[port_alias_map.get(alias, alias)] = speed | ||
return port_speeds, port_descriptions | ||
|
||
sysports = device_info.find(str(QName(ns, "SystemPorts"))) | ||
sys_ports = {} | ||
if sysports is not None: | ||
for sysport in sysports.findall(str(QName(ns, "SystemPort"))): | ||
portname = sysport.find(str(QName(ns, "Name"))).text | ||
hostname = sysport.find(str(QName(ns, "Hostname"))) | ||
asic_name = sysport.find(str(QName(ns, "AsicName"))) | ||
system_port_id = sysport.find(str(QName(ns, "SystemPortId"))).text | ||
switch_id = sysport.find(str(QName(ns, "SwitchId"))).text | ||
core_id = sysport.find(str(QName(ns, "CoreId"))).text | ||
core_port_id = sysport.find(str(QName(ns, "CorePortId"))).text | ||
speed = sysport.find(str(QName(ns, "Speed"))).text | ||
num_voq = sysport.find(str(QName(ns, "NumVoq"))).text | ||
key = portname | ||
if asic_name is not None: | ||
key = "%s|%s" % (asic_name.text, key) | ||
if hostname is not None: | ||
key = "%s|%s" % (hostname.text, key) | ||
sys_ports[key] = {"system_port_id": system_port_id, "switch_id": switch_id, "core_index": core_id, "core_port_index": core_port_id, "speed": speed, "num_voq": num_voq} | ||
|
||
return port_speeds, port_descriptions, sys_ports | ||
|
||
# Function to check if IP address is present in the key. | ||
# If it is present, then the key would be a tuple. | ||
|
@@ -1097,6 +1147,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw | |
vlan_members = None | ||
pcs = None | ||
mgmt_intf = None | ||
voq_inband_intfs = None | ||
lo_intfs = None | ||
neighbors = None | ||
devices = None | ||
|
@@ -1107,6 +1158,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw | |
port_speeds_default = {} | ||
port_speed_png = {} | ||
port_descriptions = {} | ||
sys_ports = {} | ||
console_ports = {} | ||
mux_cable_ports = {} | ||
syslog_servers = [] | ||
|
@@ -1119,6 +1171,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw | |
deployment_id = None | ||
region = None | ||
cloudtype = None | ||
switch_id = None | ||
switch_type = None | ||
max_cores = None | ||
hostname = None | ||
linkmetas = {} | ||
host_lo_intfs = None | ||
|
@@ -1153,33 +1208,33 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw | |
for child in root: | ||
if asic_name is None: | ||
if child.tag == str(QName(ns, "DpgDec")): | ||
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname) | ||
(intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname) | ||
elif child.tag == str(QName(ns, "CpgDec")): | ||
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname) | ||
elif child.tag == str(QName(ns, "PngDec")): | ||
(neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports, is_storage_device, png_ecmp_content) = parse_png(child, hostname, dpg_ecmp_content) | ||
elif child.tag == str(QName(ns, "UngDec")): | ||
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None) | ||
elif child.tag == str(QName(ns, "MetadataDeclaration")): | ||
(syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, kube_data) = parse_meta(child, hostname) | ||
(syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data) = parse_meta(child, hostname) | ||
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): | ||
linkmetas = parse_linkmeta(child, hostname) | ||
elif child.tag == str(QName(ns, "DeviceInfos")): | ||
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) | ||
(port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku) | ||
else: | ||
if child.tag == str(QName(ns, "DpgDec")): | ||
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name) | ||
(intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name) | ||
host_lo_intfs = parse_host_loopback(child, hostname) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the minigraph.xml this is defined under each asic.. We don't need this here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For single-asic linecards this is defined under the host's |
||
elif child.tag == str(QName(ns, "CpgDec")): | ||
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices) | ||
elif child.tag == str(QName(ns, "PngDec")): | ||
(neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname) | ||
elif child.tag == str(QName(ns, "MetadataDeclaration")): | ||
(sub_role) = parse_asic_meta(child, asic_name) | ||
(sub_role, switch_id, switch_type, max_cores ) = parse_asic_meta(child, asic_name) | ||
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): | ||
linkmetas = parse_linkmeta(child, hostname) | ||
elif child.tag == str(QName(ns, "DeviceInfos")): | ||
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku) | ||
(port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The sysports are also for each asic. I dont think we need it here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sysports a defined globally but needs to be programmed by each asic. |
||
|
||
# set the host device type in asic metadata also | ||
device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0] | ||
|
@@ -1232,6 +1287,26 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw | |
current_device['sub_role'] = sub_role | ||
results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role | ||
results['DEVICE_METADATA']['localhost']['asic_name'] = asic_name | ||
elif switch_type == "voq": | ||
# On Voq switches asic_name is mandatory even on single-asic devices | ||
results['DEVICE_METADATA']['localhost']['asic_name'] = 'Asic0' | ||
|
||
# on Voq system each asic has a switch_id | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VoQ system needs "asic_id" also. Setting of asic_id in ['DEVICE_METADATA']['localhost']['asic_id''] is done in sonic-cfggen. But this asic_id will be in simple number format like 0, 1, etc. Please make sure that this is over-written by asic_id (in either PCI device id format or simple number) from default_config.json before orchagent starts as discussed in sonic-net/sonic-utilities#1228. |
||
if switch_id is not None: | ||
results['DEVICE_METADATA']['localhost']['switch_id'] = switch_id | ||
# on Voq system each asic has a switch_type | ||
if switch_type is not None: | ||
results['DEVICE_METADATA']['localhost']['switch_type'] = switch_type | ||
# on Voq system each asic has a max_cores | ||
if max_cores is not None: | ||
results['DEVICE_METADATA']['localhost']['max_cores'] = max_cores | ||
|
||
# Voq systems have an inband interface | ||
if voq_inband_intfs is not None: | ||
results['VOQ_INBAND_INTERFACE'] = {} | ||
for key in voq_inband_intfs: | ||
results['VOQ_INBAND_INTERFACE'][key] = voq_inband_intfs[key] | ||
|
||
|
||
if resource_type is not None: | ||
results['DEVICE_METADATA']['localhost']['resource_type'] = resource_type | ||
|
@@ -1312,6 +1387,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw | |
results['INTERFACE'] = phyport_intfs | ||
results['VLAN_INTERFACE'] = vlan_intfs | ||
|
||
if sys_ports: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a unit tests for this ? |
||
results['SYSTEM_PORT'] = sys_ports | ||
|
||
for port_name in port_speeds_default: | ||
# ignore port not in port_config.ini | ||
if port_name not in ports: | ||
|
@@ -1597,7 +1675,7 @@ def parse_asic_sub_role(filename, asic_name): | |
root = ET.parse(filename).getroot() | ||
for child in root: | ||
if child.tag == str(QName(ns, "MetadataDeclaration")): | ||
sub_role = parse_asic_meta(child, asic_name) | ||
sub_role, _, _, _ = parse_asic_meta(child, asic_name) | ||
return sub_role | ||
|
||
def parse_asic_meta_get_devices(root): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is configuration is for the Line card host not asic, do we need these attributes ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are required in the case of single asic linecards. In this case the linecard is a single host device. For multi-asic linecards or multi-asic fixed systems these attributes needs to be parsed for each asic in
parse_asic_meta
.