Skip to content
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

[minigraph] Support FECDisabled in minigraph parser #4624

Merged
merged 1 commit into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 49 additions & 5 deletions src/sonic-config-engine/minigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
BACKEND_ASIC_SUB_ROLE = 'BackEnd'
BACKEND_ASIC_INTERFACE_NAME_PREFIX = 'Ethernet-BP'

# Default Virtual Network Index (VNI)
# Default Virtual Network Index (VNI)
vni_default = 8000

###############################################################################
Expand Down Expand Up @@ -554,6 +554,39 @@ def parse_meta(meta, hname):
region = value
return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region


def parse_linkmeta(meta, hname):
link = meta.find(str(QName(ns, "Link")))
linkmetas = {}
for linkmeta in link.findall(str(QName(ns1, "LinkMetadata"))):
port = None
fec_disabled = None

# Sample: ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4
key = linkmeta.find(str(QName(ns1, "Key"))).text
endpoints = key.split(';')
for endpoint in endpoints:
t = endpoint.split(':')
if len(t) == 2 and t[0].lower() == hname.lower():
port = t[1]
break
else:
# Cannot find a matching hname, something went wrong
continue

properties = linkmeta.find(str(QName(ns1, "Properties")))
for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))):
name = device_property.find(str(QName(ns1, "Name"))).text
value = device_property.find(str(QName(ns1, "Value"))).text
if name == "FECDisabled":
fec_disabled = value

linkmetas[port] = {}
if fec_disabled:
linkmetas[port]["FECDisabled"] = fec_disabled
return linkmetas


def parse_asic_meta(meta, hname):
sub_role = None
device_metas = meta.find(str(QName(ns, "Devices")))
Expand Down Expand Up @@ -732,7 +765,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
generate asic specific configuration.
"""
root = ET.parse(filename).getroot()
mini_graph_path = filename

u_neighbors = None
u_devices = None
Expand Down Expand Up @@ -766,8 +798,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
deployment_id = None
region = None
hostname = None
linkmetas = {}

#hostname is the asic_name, get the asic_id from the asic_name
# hostname is the asic_name, get the asic_id from the asic_name
if asic_name is not None:
asic_id = get_npu_id_from_name(asic_name)
else:
Expand Down Expand Up @@ -800,6 +833,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname)
elif child.tag == str(QName(ns, "MetadataDeclaration")):
(syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = 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)
else:
Expand All @@ -811,6 +846,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
(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)
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)

Expand Down Expand Up @@ -896,7 +933,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):

for port_name in port_speed_png:
# not consider port not in port_config.ini
#If no port_config_file is found ports is empty so ignore this error
# If no port_config_file is found ports is empty so ignore this error
if port_config_file is not None:
if port_name not in ports:
print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name
Expand All @@ -905,7 +942,14 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name]

for port_name, port in ports.items():
if port.get('speed') == '100000':
# get port alias from port_config.ini
if port_config_file:
alias = port.get('alias')
else:
alias = port_name
# generate default 100G FEC
# Note: FECDisabled only be effective on 100G port right now
if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true':
port['fec'] = 'rs'

# set port description if parsed from deviceinfo
Expand Down
31 changes: 29 additions & 2 deletions src/sonic-config-engine/tests/t0-sample-graph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -381,13 +381,14 @@
<EndPort>Ethernet1/1</EndPort>
<StartDevice>switch-t0</StartDevice>
<StartPort>fortyGigE0/124</StartPort>
<Bandwidth>100000</Bandwidth>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<AutoNegotiation>true</AutoNegotiation>
<Bandwidth>10000</Bandwidth>
<Bandwidth>100000</Bandwidth>
<EndDevice>switch-t0</EndDevice>
<EndPort>fortyGigE0/2</EndPort>
<EndPort>fortyGigE0/4</EndPort>
<FlowControl>true</FlowControl>
<StartDevice>ARISTA05T1</StartDevice>
<StartPort>Ethernet1/33</StartPort>
Expand Down Expand Up @@ -439,6 +440,32 @@
</Devices>
<Properties xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
</MetadataDeclaration>
<LinkMetadataDeclaration>
<Link xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:LinkMetadata>
<a:Name i:nil="true"/>
<a:Properties>
<a:DeviceProperty>
<a:Name>FECDisabled</a:Name>
<a:Reference i:nil="true"/>
<a:Value>True</a:Value>
</a:DeviceProperty>
</a:Properties>
<a:Key>ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4</a:Key>
</a:LinkMetadata>
<a:LinkMetadata>
<a:Name i:nil="true"/>
<a:Properties>
<a:DeviceProperty>
<a:Name>FECDisabled</a:Name>
<a:Reference i:nil="true"/>
<a:Value>True</a:Value>
</a:DeviceProperty>
</a:Properties>
<a:Key>ARISTA06T1:Ethernet1/34;switch-t0:fortyGigE0/8</a:Key>
</a:LinkMetadata>
</Link>
</LinkMetadataDeclaration>
<Hostname>switch-t0</Hostname>
<HwSku>Force10-S6000</HwSku>
</DeviceMiniGraph>
15 changes: 12 additions & 3 deletions src/sonic-config-engine/tests/test_cfggen.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ def test_minigraph_acl(self):
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE'
output = self.run_script(argument, True)
self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n"
"Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n"
"Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n"
"{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, "
"'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, "
"'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW_EGRESS'}, "
Expand Down Expand Up @@ -191,7 +189,18 @@ def test_minigraph_extra_neighbors(self):
def test_minigraph_port_description(self):
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'description': 'ARISTA04T1:Ethernet1/1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up'}")
self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}")

def test_minigraph_port_fec_disabled(self):
# Test for FECDisabled
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet4\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}")

def test_minigraph_port_rs(self):
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"'
output = self.run_script(argument)
self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}")

def test_minigraph_bgp(self):
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"'
Expand Down