From e99e2e405e71d40502f5f9b4bad68b733182e17e Mon Sep 17 00:00:00 2001 From: arista-nwolfe <94405414+arista-nwolfe@users.noreply.github.com> Date: Mon, 30 Jan 2023 14:08:28 -0800 Subject: [PATCH] [voq][chassis] Remove created ports from the default vlan. (#2607) Signed-off-by: Nathan Wolfe nwolfe@arista.com What I did -Remove newly created ports from the default vlan on VOQ systems. -Add a test to confirm we're executing removeDefaultVlanMembers when a new port is added on a VOQ system. Why I did it -When a port is created via create_port SAI call the port may be added to the default vlan, this is undesired. How I verified it -On a 7800R3AK-36DM2 linecard with multiple 400G ports I verified that the TX_TAG_ENABLE field in ETPPC_EDITING_PER_PORT_TABLE was not set for and ports. This confirms that no port is a member of any vlan --- orchagent/portsorch.cpp | 7 ++++ tests/test_virtual_chassis.py | 62 ++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 8c9e14608c53..2e404b22cfe7 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -2696,6 +2696,13 @@ bool PortsOrch::addPort(const set &lane_set, uint32_t speed, int an, string m_portListLaneMap[lane_set] = port_id; m_portCount++; + // newly created ports might be put in the default vlan so remove all ports from + // the default vlan. + if (gMySwitchType == "voq") { + removeDefaultVlanMembers(); + removeDefaultBridgePorts(); + } + SWSS_LOG_NOTICE("Create port %" PRIx64 " with the speed %u", port_id, speed); return true; diff --git a/tests/test_virtual_chassis.py b/tests/test_virtual_chassis.py index e70b495b6298..1dae2b68ffb0 100644 --- a/tests/test_virtual_chassis.py +++ b/tests/test_virtual_chassis.py @@ -3,6 +3,7 @@ import ast import time import pytest +import buffer_model class TestVirtualChassis(object): @@ -852,7 +853,66 @@ def test_chassis_system_lag_id_allocator_del_id(self, vct): assert len(lagmemberkeys) == 0, "Stale system lag member entries in asic db" break - + + def test_chassis_add_remove_ports(self, vct): + """Test removing and adding a port in a VOQ chassis. + + Test validates that when a port is created the port is removed from the default vlan. + """ + dvss = vct.dvss + for name in dvss.keys(): + dvs = dvss[name] + buffer_model.enable_dynamic_buffer(dvs.get_config_db(), dvs.runcmd) + + config_db = dvs.get_config_db() + app_db = dvs.get_app_db() + asic_db = dvs.get_asic_db() + metatbl = config_db.get_entry("DEVICE_METADATA", "localhost") + cfg_switch_type = metatbl.get("switch_type") + + if cfg_switch_type == "voq": + num_ports = len(asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT")) + # Get the port info we'll flap + port = config_db.get_keys('PORT')[0] + port_info = config_db.get_entry("PORT", port) + + # Remove port's other configs + pgs = config_db.get_keys('BUFFER_PG') + queues = config_db.get_keys('BUFFER_QUEUE') + for key in pgs: + if port in key: + config_db.delete_entry('BUFFER_PG', key) + app_db.wait_for_deleted_entry('BUFFER_PG_TABLE', key) + + for key in queues: + if port in key: + config_db.delete_entry('BUFFER_QUEUE', key) + app_db.wait_for_deleted_entry('BUFFER_QUEUE_TABLE', key) + + # Remove port + config_db.delete_entry('PORT', port) + app_db.wait_for_deleted_entry('PORT_TABLE', port) + num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT", + num_ports-1) + assert len(num) == num_ports-1 + + marker = dvs.add_log_marker() + + # Create port + config_db.update_entry("PORT", port, port_info) + app_db.wait_for_entry("PORT_TABLE", port) + num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT", + num_ports) + assert len(num) == num_ports + + # Check that we see the logs for removing default vlan + matching_log = "removeDefaultVlanMembers: Remove 0 VLAN members from default VLAN" + _, logSeen = dvs.runcmd( [ "sh", "-c", + "awk '/{}/,ENDFILE {{print;}}' /var/log/syslog | grep '{}' | wc -l".format( marker, matching_log ) ] ) + assert logSeen.strip() == "1" + + buffer_model.disable_dynamic_buffer(dvs.get_config_db(), dvs.runcmd) + # Add Dummy always-pass test at end as workaroud # for issue when Flaky fail on final test it invokes module tear-down before retrying def test_nonflaky_dummy():