diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index a5fa104c9a..867bf044b4 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -1698,6 +1698,11 @@ void IntfsOrch::voqSyncAddIntf(string &alias) return; } + if(alias.empty()) + { + SWSS_LOG_ERROR("System Port/LAG alias is empty for %s!", port.m_alias.c_str()); + return; + } string oper_status = port.m_oper_status == SAI_PORT_OPER_STATUS_UP ? "up" : "down"; diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 7f3c29f3c9..b5d3c891dd 100644 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -702,6 +702,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector(new Table(db, APP_PORT_TABLE_NAME)); m_sendToIngressPortTable = unique_ptr(new Table(db, APP_SEND_TO_INGRESS_PORT_TABLE_NAME)); + m_systemPortTable = unique_ptr
(new Table(db, APP_SYSTEM_PORT_TABLE_NAME)); /* Initialize gearbox */ m_gearboxTable = unique_ptr
(new Table(db, "_GEARBOX_TABLE")); @@ -3973,6 +3974,7 @@ void PortsOrch::registerPort(Port &p) /* Create associated Gearbox lane mapping */ initGearboxPort(p); + updateSystemPort(p); /* Add port to port list */ m_portList[alias] = p; @@ -10017,7 +10019,9 @@ bool PortsOrch::getSystemPorts() attr.value.sysportconfig.attached_core_index, attr.value.sysportconfig.attached_core_port_index); - m_systemPortOidMap[sp_key] = system_port_list[i]; + systemPortMapInfo system_port_info; + system_port_info.system_port_id = system_port_list[i]; + m_systemPortOidMap[sp_key] = system_port_info; } } @@ -10103,7 +10107,8 @@ bool PortsOrch::addSystemPorts() sai_status_t status; //Retrive system port config info and enable - system_port_oid = m_systemPortOidMap[sp_key]; + system_port_oid = m_systemPortOidMap[sp_key].system_port_id; + attr.id = SAI_SYSTEM_PORT_ATTR_TYPE; attrs.push_back(attr); @@ -10166,6 +10171,10 @@ bool PortsOrch::addSystemPorts() port.m_system_port_info.speed = attrs[1].value.sysportconfig.speed; port.m_system_port_info.num_voq = attrs[1].value.sysportconfig.num_voq; + //Update the system Port Info to the m_systemPortOidMap to be used later when the Port Speed is changed dynamically + m_systemPortOidMap[sp_key].system_port_info = port.m_system_port_info; + m_systemPortOidMap[sp_key].info_valid = true; + initializeVoqs( port ); setPort(port.m_alias, port); /* Add system port name map to counter table */ @@ -10194,6 +10203,73 @@ bool PortsOrch::addSystemPorts() return true; } +void PortsOrch::updateSystemPort(Port &port) +{ + if (!m_initDone) + { + //addSystemPorts will update the system port + return; + } + + if ((gMySwitchType == "voq") && (port.m_type == Port::PHY)) + { + auto system_port_alias = gMyHostName + "|" + gMyAsicName + "|" + port.m_alias; + vector spFv; + + m_systemPortTable->get(system_port_alias, spFv); + + //Retrieve system port configurations from APP DB + int32_t switch_id = -1; + int32_t core_index = -1; + int32_t core_port_index = -1; + + for ( auto &fv : spFv ) + { + if(fv.first == "switch_id") + { + switch_id = stoi(fv.second); + continue; + } + if(fv.first == "core_index") + { + core_index = stoi(fv.second); + continue; + } + if(fv.first == "core_port_index") + { + core_port_index = stoi(fv.second); + continue; + } + if(switch_id < 0 || core_index < 0 || core_port_index < 0) + { + continue; + } + tuple sp_key(switch_id, core_index, core_port_index); + + if(m_systemPortOidMap.find(sp_key) != m_systemPortOidMap.end()) + { + auto system_port = m_systemPortOidMap[sp_key]; + // Check if the system_port_info is already populated in m_systemPortOidMap. + if(system_port.info_valid) + { + port.m_system_port_oid = system_port.system_port_id; + port.m_system_port_info = system_port.system_port_info; + port.m_system_port_info.local_port_oid = port.m_port_id; + //initializeVoqs(port); + SWSS_LOG_NOTICE("Updated system port for %s with system_port_alias:%s switch_id:%d, core_index:%d, core_port_index:%d", + port.m_alias.c_str(), system_port.system_port_info.alias.c_str(), system_port.system_port_info.switch_id, + system_port.system_port_info.core_index, system_port.system_port_info.core_port_index); + } + } + } + if(port.m_system_port_info.alias.empty()) + { + SWSS_LOG_ERROR("SYSTEM PORT Information is not updated for %s", port.m_alias.c_str()); + } + } +} + + bool PortsOrch::getInbandPort(Port &port) { if (m_portList.find(m_inbandPortName) == m_portList.end()) diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 3ed160cafd..d92fe860fa 100644 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -117,6 +117,13 @@ struct queueInfo sai_uint8_t index; }; +struct systemPortMapInfo +{ + sai_object_id_t system_port_id; + SystemPortInfo system_port_info; + bool info_valid = false; +}; + template struct PortCapability { @@ -264,6 +271,7 @@ class PortsOrch : public Orch, public Subject unique_ptr
m_counterLagTable; unique_ptr
m_portTable; unique_ptr
m_sendToIngressPortTable; + unique_ptr
m_systemPortTable; unique_ptr
m_gearboxTable; unique_ptr m_queueCounterNameMapUpdater; unique_ptr
m_voqTable; @@ -544,10 +552,11 @@ class PortsOrch : public Orch, public Subject map m_recircPortRole; //map key is tuple of - map, sai_object_id_t> m_systemPortOidMap; + map, systemPortMapInfo> m_systemPortOidMap; sai_uint32_t m_systemPortCount; bool getSystemPorts(); bool addSystemPorts(); + void updateSystemPort(Port &port); unique_ptr
m_tableVoqSystemLagTable; unique_ptr
m_tableVoqSystemLagMemberTable; void voqSyncAddLag(Port &lag); diff --git a/tests/test_virtual_chassis.py b/tests/test_virtual_chassis.py index 2101e92da7..a284b91e06 100644 --- a/tests/test_virtual_chassis.py +++ b/tests/test_virtual_chassis.py @@ -915,62 +915,6 @@ def test_chassis_system_lag_id_allocator_del_id(self, vct): 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) - assert len(num) == num_ports - - # 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 - _, logSeen = dvs.runcmd( [ "sh", "-c", - "awk STARTFILE/ENDFILE /var/log/syslog | grep 'removeDefaultVlanMembers: Remove 32 VLAN members from default VLAN' | wc -l"] ) - assert logSeen.strip() == "1" - - buffer_model.disable_dynamic_buffer(dvs) - def test_voq_egress_queue_counter(self, vct): if vct is None: return @@ -1038,6 +982,78 @@ def test_chassis_wred_profile_on_system_ports(self, vct): # Total number of logs = (No of system ports * No of lossless priorities) - No of lossless priorities for CPU ports assert logSeen.strip() == str(len(system_ports)*2 - 2) + 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") + cfg_hostname = metatbl.get("hostname") + cfg_asic_name = metatbl.get("asic_name") + + 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) + system_port = cfg_hostname+"|"+cfg_asic_name+"|"+port + + # Remove port's other configs + pgs = config_db.get_keys('BUFFER_PG') + buf_queues = config_db.get_keys('BUFFER_QUEUE') + queues = config_db.get_keys('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 buf_queues: + if port in key: + config_db.delete_entry('BUFFER_QUEUE', key) + app_db.wait_for_deleted_entry('BUFFER_QUEUE_TABLE', key) + + queue_info = {} + for key in queues: + if system_port in key: + queue_info[key] = config_db.get_entry("QUEUE", key) + config_db.delete_entry('QUEUE', key) + config_db.wait_for_deleted_entry('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) + assert len(num) == num_ports + + # 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 + + if len(queue_info): + for key, value in queue_info.items(): + config_db.update_entry("QUEUE", key, value) + config_db.wait_for_entry("QUEUE", key) + + # Check that we see the logs for removing default vlan + _, logSeen = dvs.runcmd( [ "sh", "-c", + "awk STARTFILE/ENDFILE /var/log/syslog | grep 'removeDefaultVlanMembers: Remove 32 VLAN members from default VLAN' | wc -l"] ) + assert logSeen.strip() == "1" + + buffer_model.disable_dynamic_buffer(dvs) + def test_chassis_system_intf_status(self, vct): dvs = self.get_sup_dvs(vct) chassis_app_db = DVSDatabase(swsscommon.CHASSIS_APP_DB, dvs.redis_chassis_sock)