Skip to content

Commit 750b3f6

Browse files
authored
Merge branch 'sonic-net:master' into vrrp_orch
2 parents e0ac765 + 7db69c1 commit 750b3f6

File tree

6 files changed

+358
-5
lines changed

6 files changed

+358
-5
lines changed

orchagent/p4orch/tests/fake_portorch.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ extern "C"
1414

1515
PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_with_pri_t> &tableNames,
1616
DBConnector *chassisAppDb)
17-
: Orch(db, tableNames), m_portStateTable(stateDb, STATE_PORT_TABLE_NAME),
17+
: Orch(db, tableNames),
18+
m_portStateTable(stateDb, STATE_PORT_TABLE_NAME),
19+
m_portOpErrTable(stateDb, STATE_PORT_OPER_ERR_TABLE_NAME),
1820
port_stat_manager(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ,
1921
PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, true),
2022
port_buffer_drop_stat_manager(PORT_BUFFER_DROP_STAT_FLEX_COUNTER_GROUP, StatsMode::READ,

orchagent/port.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ extern "C" {
1010
#include <vector>
1111
#include <map>
1212
#include <bitset>
13+
#include <chrono>
1314
#include <unordered_set>
14-
15+
#include <iomanip>
16+
#include <sstream>
1517
#include <macaddress.h>
1618
#include <sairedis.h>
1719

@@ -74,6 +76,42 @@ struct SystemLagInfo
7476
int32_t spa_id = 0;
7577
};
7678

79+
class PortOperErrorEvent
80+
{
81+
public:
82+
PortOperErrorEvent() = default;
83+
PortOperErrorEvent(const sai_port_error_status_t error, std::string key) : m_errorFlag(error), m_dbKeyError(key){}
84+
~PortOperErrorEvent() = default;
85+
86+
inline void incrementErrorCount(void) { m_errorCount++; }
87+
88+
inline size_t getErrorCount(void) const { return m_errorCount; }
89+
90+
void recordEventTime(void) {
91+
auto now = std::chrono::system_clock::now();
92+
m_eventTime = std::chrono::system_clock::to_time_t(now);
93+
}
94+
95+
std::string getEventTime(void) {
96+
std::ostringstream oss;
97+
oss << std::put_time(std::gmtime(&m_eventTime), "%Y-%m-%d %H:%M:%S");
98+
return oss.str();
99+
}
100+
101+
inline std::string getDbKey(void) const { return m_dbKeyError; }
102+
103+
// Returns true if port oper error flag in sai_port_error_status_t is set
104+
bool isErrorSet(sai_port_error_status_t errstatus) const { return (m_errorFlag & errstatus);}
105+
106+
static const std::unordered_map<sai_port_error_status_t, std::string> db_key_errors;
107+
108+
private:
109+
sai_port_error_status_t m_errorFlag = SAI_PORT_ERROR_STATUS_CLEAR;
110+
size_t m_errorCount = 0;
111+
std::string m_dbKeyError; // DB key for this port error
112+
std::time_t m_eventTime = 0;
113+
};
114+
77115
class Port
78116
{
79117
public:
@@ -155,6 +193,7 @@ class Port
155193
sai_object_id_t m_parent_port_id = 0;
156194
uint32_t m_dependency_bitmap = 0;
157195
sai_port_oper_status_t m_oper_status = SAI_PORT_OPER_STATUS_UNKNOWN;
196+
sai_port_error_status_t m_oper_error_status = SAI_PORT_ERROR_STATUS_CLEAR; //Bitmap of last port oper error status
158197
std::set<std::string> m_members;
159198
std::set<std::string> m_child_ports;
160199
std::vector<sai_object_id_t> m_queue_ids;
@@ -193,6 +232,9 @@ class Port
193232
sai_object_id_t m_system_side_id = 0;
194233
sai_object_id_t m_line_side_id = 0;
195234

235+
/* Port oper error status to event map*/
236+
std::unordered_map<sai_port_error_status_t, PortOperErrorEvent> m_portOperErrorToEvent;
237+
196238
/* pre-emphasis */
197239
std::map<sai_port_serdes_attr_t, std::vector<uint32_t>> m_preemphasis;
198240

orchagent/portsorch.cpp

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,25 @@ static char* hostif_vlan_tag[] = {
308308
[SAI_HOSTIF_VLAN_TAG_ORIGINAL] = "SAI_HOSTIF_VLAN_TAG_ORIGINAL"
309309
};
310310

311+
const std::unordered_map<sai_port_error_status_t, std::string> PortOperErrorEvent::db_key_errors =
312+
{
313+
// SAI port oper error status to error name mapping
314+
{ SAI_PORT_ERROR_STATUS_MAC_LOCAL_FAULT, "mac_local_fault"},
315+
{ SAI_PORT_ERROR_STATUS_MAC_REMOTE_FAULT, "mac_remote_fault"},
316+
{ SAI_PORT_ERROR_STATUS_FEC_SYNC_LOSS, "fec_sync_loss"},
317+
{ SAI_PORT_ERROR_STATUS_FEC_LOSS_ALIGNMENT_MARKER, "fec_alignment_loss"},
318+
{ SAI_PORT_ERROR_STATUS_HIGH_SER, "high_ser_error"},
319+
{ SAI_PORT_ERROR_STATUS_HIGH_BER, "high ber_error"},
320+
{ SAI_PORT_ERROR_STATUS_CRC_RATE, "crc_rate"},
321+
{ SAI_PORT_ERROR_STATUS_DATA_UNIT_CRC_ERROR, "data_unit_crc_error"},
322+
{ SAI_PORT_ERROR_STATUS_DATA_UNIT_SIZE, "data_unit_size"},
323+
{ SAI_PORT_ERROR_STATUS_DATA_UNIT_MISALIGNMENT_ERROR, "data_unit_misalignment_error"},
324+
{ SAI_PORT_ERROR_STATUS_CODE_GROUP_ERROR, "code_group_error"},
325+
{ SAI_PORT_ERROR_STATUS_SIGNAL_LOCAL_ERROR, "signal_local_error"},
326+
{ SAI_PORT_ERROR_STATUS_NO_RX_REACHABILITY, "no_rx_reachability"}
327+
};
328+
329+
311330
// functions ----------------------------------------------------------------------------------------------------------
312331

313332
static bool isValidPortTypeForLagMember(const Port& port)
@@ -509,6 +528,7 @@ bool PortsOrch::checkPathTracingCapability()
509528
PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vector<table_name_with_pri_t> &tableNames, DBConnector *chassisAppDb) :
510529
Orch(db, tableNames),
511530
m_portStateTable(stateDb, STATE_PORT_TABLE_NAME),
531+
m_portOpErrTable(stateDb, STATE_PORT_OPER_ERR_TABLE_NAME),
512532
port_stat_manager(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false),
513533
gb_port_stat_manager(true,
514534
PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ,
@@ -808,6 +828,26 @@ void PortsOrch::initializeCpuPort()
808828
SWSS_LOG_NOTICE("Get CPU port pid:%" PRIx64, this->m_cpuPort.m_port_id);
809829
}
810830

831+
// Creating mapping of various port oper errors for error handling
832+
void PortsOrch::initializePortOperErrors(Port &port)
833+
{
834+
SWSS_LOG_ENTER();
835+
836+
SWSS_LOG_NOTICE("Initialize port oper errors for port %s", port.m_alias.c_str());
837+
838+
for (auto& error : PortOperErrorEvent::db_key_errors)
839+
{
840+
const sai_port_error_status_t error_status = error.first;
841+
std::string error_name = error.second;
842+
843+
port.m_portOperErrorToEvent[error_status] = PortOperErrorEvent(error_status, error_name);
844+
SWSS_LOG_NOTICE("Initialize port %s error %s flag=0x%" PRIx32,
845+
port.m_alias.c_str(),
846+
error_name.c_str(),
847+
error_status);
848+
}
849+
}
850+
811851
void PortsOrch::initializePorts()
812852
{
813853
SWSS_LOG_ENTER();
@@ -3351,6 +3391,26 @@ void PortsOrch::updateDbPortFlapCount(Port& port, sai_port_oper_status_t pstatus
33513391
m_portTable->set(port.m_alias, tuples);
33523392
}
33533393

3394+
void PortsOrch::updateDbPortOperError(Port& port, PortOperErrorEvent *pevent)
3395+
{
3396+
SWSS_LOG_ENTER();
3397+
3398+
auto key = pevent->getDbKey();
3399+
vector<FieldValueTuple> tuples;
3400+
FieldValueTuple tup1("oper_error_status", std::to_string(port.m_oper_error_status));
3401+
tuples.push_back(tup1);
3402+
3403+
size_t count = pevent->getErrorCount();
3404+
FieldValueTuple tup2(key + "_count", std::to_string(count));
3405+
tuples.push_back(tup2);
3406+
3407+
auto time = pevent->getEventTime();
3408+
FieldValueTuple tup3(key + "_time", time);
3409+
tuples.push_back(tup3);
3410+
3411+
m_portOpErrTable.set(port.m_alias, tuples);
3412+
}
3413+
33543414
void PortsOrch::updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const
33553415
{
33563416
SWSS_LOG_ENTER();
@@ -4613,6 +4673,8 @@ void PortsOrch::doPortTask(Consumer &consumer)
46134673
/* create host_tx_ready field in state-db */
46144674
initHostTxReadyState(p);
46154675

4676+
initializePortOperErrors(p);
4677+
46164678
// Restore admin status if the port was brought down
46174679
if (admin_status != p.m_admin_state_up)
46184680
{
@@ -8019,12 +8081,14 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
80198081

80208082
for (uint32_t i = 0; i < count; i++)
80218083
{
8084+
Port port;
80228085
sai_object_id_t id = portoperstatus[i].port_id;
80238086
sai_port_oper_status_t status = portoperstatus[i].port_state;
8087+
sai_port_error_status_t port_oper_err = portoperstatus[i].port_error_status;
80248088

8025-
SWSS_LOG_NOTICE("Get port state change notification id:%" PRIx64 " status:%d", id, status);
8026-
8027-
Port port;
8089+
SWSS_LOG_NOTICE("Get port state change notification id:%" PRIx64 " status:%d "
8090+
"oper_error_status:0x%" PRIx32,
8091+
id, status, port_oper_err);
80288092

80298093
if (!getPort(id, port))
80308094
{
@@ -8061,6 +8125,11 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
80618125
{
80628126
updateDbPortOperFec(port, "N/A");
80638127
}
8128+
} else {
8129+
if (port_oper_err)
8130+
{
8131+
updatePortErrorStatus(port, port_oper_err);
8132+
}
80648133
}
80658134

80668135
/* update m_portList */
@@ -8089,6 +8158,53 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
80898158

80908159
}
80918160

8161+
void PortsOrch::updatePortErrorStatus(Port &port, sai_port_error_status_t errstatus)
8162+
{
8163+
size_t errors = 0;
8164+
string db_port_error_name;
8165+
PortOperErrorEvent *portOperErrorEvent = nullptr;
8166+
size_t error_count = PortOperErrorEvent::db_key_errors.size();
8167+
8168+
SWSS_LOG_NOTICE("Port %s error state set from 0x%" PRIx32 "-> 0x%" PRIx32,
8169+
port.m_alias.c_str(),
8170+
port.m_oper_error_status,
8171+
errstatus);
8172+
8173+
port.m_oper_error_status = errstatus;
8174+
8175+
// Iterate through all the port oper errors
8176+
while ((errstatus >> errors) && (errors < error_count))
8177+
{
8178+
sai_port_error_status_t error_status = static_cast<sai_port_error_status_t>(errstatus & (1 << errors));
8179+
8180+
if (port.m_portOperErrorToEvent.find(error_status) == port.m_portOperErrorToEvent.end())
8181+
{
8182+
++errors;
8183+
continue;
8184+
}
8185+
8186+
portOperErrorEvent = &port.m_portOperErrorToEvent[error_status];
8187+
8188+
if (portOperErrorEvent->isErrorSet(errstatus))
8189+
{
8190+
SWSS_LOG_NOTICE("Port %s oper error event: %s occurred",
8191+
port.m_alias.c_str(),
8192+
portOperErrorEvent->getDbKey().c_str());
8193+
portOperErrorEvent->recordEventTime();
8194+
portOperErrorEvent->incrementErrorCount();
8195+
updateDbPortOperError(port, portOperErrorEvent);
8196+
}
8197+
else
8198+
{
8199+
SWSS_LOG_WARN("Port %s port oper error %s not updated in DB",
8200+
port.m_alias.c_str(),
8201+
portOperErrorEvent->getDbKey().c_str());
8202+
}
8203+
8204+
++errors;
8205+
}
8206+
}
8207+
80928208
void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status)
80938209
{
80948210
SWSS_LOG_NOTICE("Port %s oper state set from %s to %s",

orchagent/portsorch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,14 @@ class PortsOrch : public Orch, public Subject
146146
void setPort(string alias, Port port);
147147
void getCpuPort(Port &port);
148148
void initHostTxReadyState(Port &port);
149+
void initializePortOperErrors(Port &port);
149150
bool getInbandPort(Port &port);
150151
bool getVlanByVlanId(sai_vlan_id_t vlan_id, Port &vlan);
151152

152153
bool setHostIntfsOperStatus(const Port& port, bool up) const;
153154
void updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const;
154155
void updateDbPortFlapCount(Port& port, sai_port_oper_status_t pstatus);
156+
void updateDbPortOperError(Port& port, PortOperErrorEvent *pevent);
155157

156158
bool createVlanHostIntf(Port& vl, string hostif_name);
157159
bool removeVlanHostIntf(Port vl);
@@ -263,6 +265,7 @@ class PortsOrch : public Orch, public Subject
263265
unique_ptr<Table> m_pgIndexTable;
264266
unique_ptr<Table> m_stateBufferMaximumValueTable;
265267
Table m_portStateTable;
268+
Table m_portOpErrTable;
266269

267270
std::string getQueueWatermarkFlexCounterTableKey(std::string s);
268271
std::string getPriorityGroupWatermarkFlexCounterTableKey(std::string s);
@@ -502,6 +505,7 @@ class PortsOrch : public Orch, public Subject
502505
bool initGearboxPort(Port &port);
503506
bool getPortOperFec(const Port& port, sai_port_fec_mode_t &fec_mode) const;
504507
void updateDbPortOperFec(Port &port, string fec_str);
508+
void updatePortErrorStatus(Port &port, sai_port_error_status_t port_oper_eror);
505509

506510
map<string, Port::Role> m_recircPortRole;
507511

orchagent/routeorch.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern FlowCounterRouteOrch *gFlowCounterRouteOrch;
2929
extern TunnelDecapOrch *gTunneldecapOrch;
3030

3131
extern size_t gMaxBulkSize;
32+
extern string gMySwitchType;
3233

3334
/* Default maximum number of next hop groups */
3435
#define DEFAULT_NUMBER_OF_ECMP_GROUPS 128
@@ -88,6 +89,37 @@ RouteOrch::RouteOrch(DBConnector *db, vector<table_name_with_pri_t> &tableNames,
8889

8990
SWSS_LOG_NOTICE("Maximum number of ECMP groups supported is %d", m_maxNextHopGroupCount);
9091

92+
/* fetch the MAX_ECMP_MEMBER_COUNT and for voq platform, set it to 128 */
93+
attr.id = SAI_SWITCH_ATTR_MAX_ECMP_MEMBER_COUNT;
94+
status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
95+
96+
if (status != SAI_STATUS_SUCCESS)
97+
{
98+
SWSS_LOG_WARN("Failed to get switch attribute max ECMP Group size. rv:%d", status);
99+
}
100+
else
101+
{
102+
uint32_t maxEcmpGroupSize = attr.value.u32;
103+
SWSS_LOG_NOTICE("Switch Type: %s, Max ECMP Group Size supported: %d", gMySwitchType.c_str(), attr.value.u32);
104+
105+
/*If the switch type is voq, and max Ecmp group size supported is greater or equal to 128, set it to 128 */
106+
if (gMySwitchType == "voq" && maxEcmpGroupSize >= 128)
107+
{
108+
maxEcmpGroupSize = 128;
109+
attr.id = SAI_SWITCH_ATTR_ECMP_MEMBER_COUNT;
110+
attr.value.s32 = maxEcmpGroupSize;
111+
status = sai_switch_api->set_switch_attribute(gSwitchId, &attr);
112+
if (status != SAI_STATUS_SUCCESS)
113+
{
114+
SWSS_LOG_ERROR("Failed to set switch attribute ECMP member count to 128. rv:%d", status);
115+
}
116+
else
117+
{
118+
SWSS_LOG_NOTICE("Set switch attribute ECMP member count to 128");
119+
}
120+
}
121+
}
122+
91123
m_stateDb = shared_ptr<DBConnector>(new DBConnector("STATE_DB", 0));
92124
m_stateDefaultRouteTb = unique_ptr<swss::Table>(new Table(m_stateDb.get(), STATE_ROUTE_TABLE_NAME));
93125

0 commit comments

Comments
 (0)