diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py
index d53a56d7da..294fb7faaa 100644
--- a/src/sonic-config-engine/minigraph.py
+++ b/src/sonic-config-engine/minigraph.py
@@ -90,6 +90,7 @@ def parse_png(png, hname):
mgmt_port = ''
port_speeds = {}
console_ports = {}
+ mux_cable_ports = {}
for child in png:
if child.tag == str(QName(ns, "DeviceInterfaceLinks")):
for link in child.findall(str(QName(ns, "DeviceLinkBase"))):
@@ -162,7 +163,16 @@ def parse_png(png, hname):
elif node.tag == str(QName(ns, "EndDevice")):
mgmt_dev = node.text
- return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports)
+ if child.tag == str(QName(ns, "DeviceInterfaceLinks")):
+ for link in child.findall(str(QName(ns, 'DeviceLinkBase'))):
+ if link.find(str(QName(ns, "ElementType"))).text == "LogicalLink":
+ intf_name = link.find(str(QName(ns, "EndPort"))).text
+ if intf_name in port_alias_map:
+ intf_name = port_alias_map[intf_name]
+
+ mux_cable_ports[intf_name] = "true"
+
+ return (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speeds, console_ports, mux_cable_ports)
def parse_asic_external_link(link, asic_name, hostname):
neighbors = {}
@@ -831,6 +841,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
port_speed_png = {}
port_descriptions = {}
console_ports = {}
+ mux_cable_ports = {}
syslog_servers = []
dhcp_servers = []
ntp_servers = []
@@ -873,7 +884,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_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) = parse_png(child, hostname)
+ (neighbors, devices, console_dev, console_port, mgmt_dev, mgmt_port, port_speed_png, console_ports, mux_cable_ports) = parse_png(child, hostname)
elif child.tag == str(QName(ns, "UngDec")):
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname)
elif child.tag == str(QName(ns, "MetadataDeclaration")):
@@ -1009,6 +1020,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true':
port['fec'] = 'rs'
+ # If connected to a smart cable, get the connection position
+ for port_name, port in ports.items():
+ if port_name in mux_cable_ports:
+ port['mux_cable'] = mux_cable_ports[port_name]
+
# set port description if parsed from deviceinfo
for port_name in port_descriptions:
# ignore port not in port_config.ini
diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml
index acfcd4a6a7..3188409b1f 100644
--- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml
+++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml
@@ -209,6 +209,28 @@
switch-02t1
port1
+
+ LogicalLink
+ 10000
+ false
+ switch-t0
+ fortyGigE0/4
+ true
+ mux-cable
+ L
+ true
+
+
+ LogicalLink
+ 10000
+ false
+ switch-t0
+ fortyGigE0/8
+ true
+ mux-cable
+ U
+ true
+
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py
index 1fe1ad0384..0d2f94899e 100644
--- a/src/sonic-config-engine/tests/test_cfggen.py
+++ b/src/sonic-config-engine/tests/test_cfggen.py
@@ -346,9 +346,9 @@ class TestCfgGen(TestCase):
self.assertEqual(
utils.to_dict(output.strip()),
utils.to_dict(
- "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000'}, "
+ "{'Ethernet8': {'lanes': '37,38,39,40', 'description': 'Interface description', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/8', 'admin_status': 'up', 'speed': '40000', 'mux_cable': 'true'}, "
"'Ethernet0': {'lanes': '29,30,31,32', 'description': 'switch-01t1:port1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/0', 'admin_status': 'up', 'speed': '10000'}, "
- "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000'}, "
+ "'Ethernet4': {'lanes': '25,26,27,28', 'description': 'fortyGigE0/4', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '25000', 'mux_cable': 'true'}, "
"'Ethernet108': {'alias': 'fortyGigE0/108', 'pfc_asym': 'off', 'lanes': '81,82,83,84', 'description': 'fortyGigE0/108', 'mtu': '9100'}, "
"'Ethernet100': {'alias': 'fortyGigE0/100', 'pfc_asym': 'off', 'lanes': '125,126,127,128', 'description': 'fortyGigE0/100', 'mtu': '9100'}, "
"'Ethernet104': {'alias': 'fortyGigE0/104', 'pfc_asym': 'off', 'lanes': '85,86,87,88', 'description': 'fortyGigE0/104', 'mtu': '9100'}, "
diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py
index f9c390b653..42e5e63ac6 100644
--- a/src/sonic-config-engine/tests/test_minigraph_case.py
+++ b/src/sonic-config-engine/tests/test_minigraph_case.py
@@ -2,6 +2,7 @@ import os
import subprocess
import tests.common_utils as utils
+import minigraph
from unittest import TestCase
@@ -159,3 +160,13 @@ class TestCfgGenCaseInsensitive(TestCase):
output = self.run_script(argument)
self.assertEqual(output.strip(), "{}")
+ def test_mux_cable_parsing(self):
+ result = minigraph.parse_xml(self.sample_graph, port_config_file=self.port_config)
+
+ expected_mux_cable_ports = ["Ethernet4", "Ethernet8"]
+ port_table = result['PORT']
+ for port_name, port in port_table.items():
+ if port_name in expected_mux_cable_ports:
+ self.assertTrue(port["mux_cable"])
+ else:
+ self.assertTrue("mux_cable" not in port)