Skip to content
Open
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
5 changes: 5 additions & 0 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
80 changes: 78 additions & 2 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_wi
/* Initialize port and vlan table */
m_portTable = unique_ptr<Table>(new Table(db, APP_PORT_TABLE_NAME));
m_sendToIngressPortTable = unique_ptr<Table>(new Table(db, APP_SEND_TO_INGRESS_PORT_TABLE_NAME));
m_systemPortTable = unique_ptr<Table>(new Table(db, APP_SYSTEM_PORT_TABLE_NAME));

/* Initialize gearbox */
m_gearboxTable = unique_ptr<Table>(new Table(db, "_GEARBOX_TABLE"));
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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<FieldValueTuple> 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<int, int, int> 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())
Expand Down
11 changes: 10 additions & 1 deletion orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T>
struct PortCapability
{
Expand Down Expand Up @@ -264,6 +271,7 @@ class PortsOrch : public Orch, public Subject
unique_ptr<Table> m_counterLagTable;
unique_ptr<Table> m_portTable;
unique_ptr<Table> m_sendToIngressPortTable;
unique_ptr<Table> m_systemPortTable;
unique_ptr<Table> m_gearboxTable;
unique_ptr<CounterNameMapUpdater> m_queueCounterNameMapUpdater;
unique_ptr<Table> m_voqTable;
Expand Down Expand Up @@ -544,10 +552,11 @@ class PortsOrch : public Orch, public Subject
map<string, Port::Role> m_recircPortRole;

//map key is tuple of <attached_switch_id, core_index, core_port_index>
map<tuple<int, int, int>, sai_object_id_t> m_systemPortOidMap;
map<tuple<int, int, int>, systemPortMapInfo> m_systemPortOidMap;
sai_uint32_t m_systemPortCount;
bool getSystemPorts();
bool addSystemPorts();
void updateSystemPort(Port &port);
unique_ptr<Table> m_tableVoqSystemLagTable;
unique_ptr<Table> m_tableVoqSystemLagMemberTable;
void voqSyncAddLag(Port &lag);
Expand Down
128 changes: 72 additions & 56 deletions tests/test_virtual_chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Loading