diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py
index b4f1f3acbd..35a6f56456 100644
--- a/src/sonic-config-engine/minigraph.py
+++ b/src/sonic-config-engine/minigraph.py
@@ -536,28 +536,36 @@ def parse_dpg(dpg, hname):
vlan_members = {}
vlan_member_list = {}
dhcp_relay_table = {}
- vlantype_name = ""
- intf_vlan_mbr = defaultdict(list)
+ # Dict: vlan member (port/PortChannel) -> set of VlanID, in which the member if an untagged vlan member
+ untagged_vlan_mbr = defaultdict(set)
for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))):
vlanid = vintf.find(str(QName(ns, "VlanID"))).text
+ vlantype = vintf.find(str(QName(ns, "Type")))
+ if vlantype is None:
+ vlantype_name = ""
+ else:
+ vlantype_name = vlantype.text
vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text
vmbr_list = vintfmbr.split(';')
- for i, member in enumerate(vmbr_list):
- intf_vlan_mbr[member].append(vlanid)
+ if vlantype_name != "Tagged":
+ for member in vmbr_list:
+ untagged_vlan_mbr[member].add(vlanid)
for vintf in vlanintfs.findall(str(QName(ns, "VlanInterface"))):
vintfname = vintf.find(str(QName(ns, "Name"))).text
vlanid = vintf.find(str(QName(ns, "VlanID"))).text
vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text
vlantype = vintf.find(str(QName(ns, "Type")))
- if vlantype != None:
- vlantype_name = vintf.find(str(QName(ns, "Type"))).text
+ if vlantype is None:
+ vlantype_name = ""
+ else:
+ vlantype_name = vlantype.text
vmbr_list = vintfmbr.split(';')
for i, member in enumerate(vmbr_list):
vmbr_list[i] = port_alias_map.get(member, member)
sonic_vlan_member_name = "Vlan%s" % (vlanid)
if vlantype_name == "Tagged":
vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'tagged'}
- elif len(intf_vlan_mbr[member]) > 1:
+ elif len(untagged_vlan_mbr[member]) > 1:
vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'tagged'}
else:
vlan_members[(sonic_vlan_member_name, vmbr_list[i])] = {'tagging_mode': 'untagged'}
diff --git a/src/sonic-config-engine/tests/sample-graph-resource-type.xml b/src/sonic-config-engine/tests/sample-graph-resource-type.xml
index 9ba4f1e702..62c2dfd64f 100644
--- a/src/sonic-config-engine/tests/sample-graph-resource-type.xml
+++ b/src/sonic-config-engine/tests/sample-graph-resource-type.xml
@@ -190,6 +190,14 @@
1000
192.168.0.0/27
+
+ ab4
+ fortyGigE0/8
+ 192.0.0.1;192.0.0.2
+ 1001
+ 1001
+ 192.168.0.32/27
+
kk1
fortyGigE0/12
@@ -205,6 +213,7 @@
192.0.0.1;192.0.0.2
2000
2000
+ Tagged
192.168.0.240/27
diff --git a/src/sonic-config-engine/tests/sample-graph-subintf.xml b/src/sonic-config-engine/tests/sample-graph-subintf.xml
index d5fd2d461c..a23b668c2c 100644
--- a/src/sonic-config-engine/tests/sample-graph-subintf.xml
+++ b/src/sonic-config-engine/tests/sample-graph-subintf.xml
@@ -208,6 +208,14 @@
1000
192.168.0.0/27
+
+ ab4
+ fortyGigE0/8
+ 192.0.0.1;192.0.0.2
+ 1001
+ 1001
+ 192.168.0.32/27
+
kk1
fortyGigE0/12
diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml
index a8bd8b0b46..8d7800686c 100644
--- a/src/sonic-config-engine/tests/simple-sample-graph.xml
+++ b/src/sonic-config-engine/tests/simple-sample-graph.xml
@@ -190,6 +190,14 @@
1000
192.168.0.0/27
+
+ ab4
+ fortyGigE0/8
+ 192.0.0.1;192.0.0.2
+ 1001
+ 1001
+ 192.168.0.32/27
+
kk1
fortyGigE0/12
@@ -205,6 +213,7 @@
192.0.0.1;192.0.0.2
2000
2000
+ Tagged
192.168.0.240/27
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py
index e1f6844dd5..29773dffc6 100644
--- a/src/sonic-config-engine/tests/test_cfggen.py
+++ b/src/sonic-config-engine/tests/test_cfggen.py
@@ -151,6 +151,7 @@ class TestCfgGen(TestCase):
utils.to_dict(output.strip()),
utils.to_dict(
'{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "tagged"\n },'
+ ' \n "Vlan1001|Ethernet8": {\n "tagging_mode": "tagged"\n },'
' \n "Vlan2000|Ethernet12": {\n "tagging_mode": "tagged"\n },'
' \n "Vlan2001|Ethernet12": {\n "tagging_mode": "tagged"\n },'
' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}'
@@ -160,9 +161,10 @@ class TestCfgGen(TestCase):
self.assertEqual(
utils.to_dict(output.strip()),
utils.to_dict(
- '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "untagged"\n },'
+ '{\n "Vlan1000|Ethernet8": {\n "tagging_mode": "tagged"\n },'
+ ' \n "Vlan1001|Ethernet8": {\n "tagging_mode": "tagged"\n },'
' \n "Vlan2000|Ethernet12": {\n "tagging_mode": "tagged"\n },'
- ' \n "Vlan2001|Ethernet12": {\n "tagging_mode": "tagged"\n },'
+ ' \n "Vlan2001|Ethernet12": {\n "tagging_mode": "untagged"\n },'
' \n "Vlan2020|Ethernet12": {\n "tagging_mode": "tagged"\n }\n}'
)
)
@@ -249,6 +251,7 @@ class TestCfgGen(TestCase):
utils.to_dict(output.strip()),
utils.to_dict(
"{'Vlan1000': {'alias': 'ab1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1000'}, "
+ "'Vlan1001': {'alias': 'ab4', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '1001'},"
"'Vlan2001': {'alias': 'ab3', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2001'},"
"'Vlan2000': {'alias': 'ab2', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2000'},"
"'Vlan2020': {'alias': 'kk1', 'dhcp_servers': ['192.0.0.1', '192.0.0.2'], 'vlanid': '2020'}}"
@@ -265,6 +268,7 @@ class TestCfgGen(TestCase):
utils.to_dict(output.strip()),
utils.to_dict(
"{('Vlan2000', 'Ethernet12'): {'tagging_mode': 'tagged'}, "
+ "('Vlan1001', 'Ethernet8'): {'tagging_mode': 'tagged'}, "
"('Vlan1000', 'Ethernet8'): {'tagging_mode': 'tagged'}, "
"('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}, "
"('Vlan2001', 'Ethernet12'): {'tagging_mode': 'tagged'}}"
@@ -275,9 +279,10 @@ class TestCfgGen(TestCase):
utils.to_dict(output.strip()),
utils.to_dict(
"{('Vlan2000', 'Ethernet12'): {'tagging_mode': 'tagged'}, "
- "('Vlan1000', 'Ethernet8'): {'tagging_mode': 'untagged'}, "
+ "('Vlan1000', 'Ethernet8'): {'tagging_mode': 'tagged'}, "
+ "('Vlan1001', 'Ethernet8'): {'tagging_mode': 'tagged'}, "
"('Vlan2020', 'Ethernet12'): {'tagging_mode': 'tagged'}, "
- "('Vlan2001', 'Ethernet12'): {'tagging_mode': 'tagged'}}"
+ "('Vlan2001', 'Ethernet12'): {'tagging_mode': 'untagged'}}"
)
)
@@ -704,6 +709,9 @@ class TestCfgGen(TestCase):
def test_minigraph_sub_port_interfaces(self, check_stderr=True):
self.verify_sub_intf(check_stderr=check_stderr)
+ def test_minigraph_sub_port_intf_resource_type_non_backend_tor(self, check_stderr=True):
+ self.verify_sub_intf_non_backend_tor(graph_file=self.sample_resource_graph, check_stderr=check_stderr)
+
def test_minigraph_sub_port_intf_resource_type(self, check_stderr=True):
self.verify_sub_intf(graph_file=self.sample_resource_graph, check_stderr=check_stderr)
@@ -737,6 +745,14 @@ class TestCfgGen(TestCase):
output = self.run_script(argument)
self.assertEqual(output.strip(), "{}")
+ def verify_sub_intf_non_backend_tor(self, **kwargs):
+ graph_file = kwargs.get('graph_file', self.sample_graph_simple)
+
+ # All the other tables stay unchanged
+ self.test_var_json_data(graph_file=graph_file)
+ self.test_minigraph_vlans(graph_file=graph_file)
+ self.test_minigraph_vlan_members(graph_file=graph_file)
+
def verify_sub_intf(self, **kwargs):
graph_file = kwargs.get('graph_file', self.sample_graph_simple)
check_stderr = kwargs.get('check_stderr', True)