@@ -308,6 +308,25 @@ static char* hostif_vlan_tag[] = {
308
308
[SAI_HOSTIF_VLAN_TAG_ORIGINAL] = " SAI_HOSTIF_VLAN_TAG_ORIGINAL"
309
309
};
310
310
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
+
311
330
// functions ----------------------------------------------------------------------------------------------------------
312
331
313
332
static bool isValidPortTypeForLagMember (const Port& port)
@@ -509,6 +528,7 @@ bool PortsOrch::checkPathTracingCapability()
509
528
PortsOrch::PortsOrch (DBConnector *db, DBConnector *stateDb, vector<table_name_with_pri_t > &tableNames, DBConnector *chassisAppDb) :
510
529
Orch(db, tableNames),
511
530
m_portStateTable(stateDb, STATE_PORT_TABLE_NAME),
531
+ m_portOpErrTable(stateDb, STATE_PORT_OPER_ERR_TABLE_NAME),
512
532
port_stat_manager(PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, PORT_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false ),
513
533
gb_port_stat_manager(true ,
514
534
PORT_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ,
@@ -808,6 +828,26 @@ void PortsOrch::initializeCpuPort()
808
828
SWSS_LOG_NOTICE (" Get CPU port pid:%" PRIx64, this ->m_cpuPort .m_port_id );
809
829
}
810
830
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
+
811
851
void PortsOrch::initializePorts ()
812
852
{
813
853
SWSS_LOG_ENTER ();
@@ -3351,6 +3391,26 @@ void PortsOrch::updateDbPortFlapCount(Port& port, sai_port_oper_status_t pstatus
3351
3391
m_portTable->set (port.m_alias , tuples);
3352
3392
}
3353
3393
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
+
3354
3414
void PortsOrch::updateDbPortOperStatus (const Port& port, sai_port_oper_status_t status) const
3355
3415
{
3356
3416
SWSS_LOG_ENTER ();
@@ -4613,6 +4673,8 @@ void PortsOrch::doPortTask(Consumer &consumer)
4613
4673
/* create host_tx_ready field in state-db */
4614
4674
initHostTxReadyState (p);
4615
4675
4676
+ initializePortOperErrors (p);
4677
+
4616
4678
// Restore admin status if the port was brought down
4617
4679
if (admin_status != p.m_admin_state_up )
4618
4680
{
@@ -8019,12 +8081,14 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
8019
8081
8020
8082
for (uint32_t i = 0 ; i < count; i++)
8021
8083
{
8084
+ Port port;
8022
8085
sai_object_id_t id = portoperstatus[i].port_id ;
8023
8086
sai_port_oper_status_t status = portoperstatus[i].port_state ;
8087
+ sai_port_error_status_t port_oper_err = portoperstatus[i].port_error_status ;
8024
8088
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) ;
8028
8092
8029
8093
if (!getPort (id, port))
8030
8094
{
@@ -8061,6 +8125,11 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
8061
8125
{
8062
8126
updateDbPortOperFec (port, " N/A" );
8063
8127
}
8128
+ } else {
8129
+ if (port_oper_err)
8130
+ {
8131
+ updatePortErrorStatus (port, port_oper_err);
8132
+ }
8064
8133
}
8065
8134
8066
8135
/* update m_portList */
@@ -8089,6 +8158,53 @@ void PortsOrch::doTask(NotificationConsumer &consumer)
8089
8158
8090
8159
}
8091
8160
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
+
8092
8208
void PortsOrch::updatePortOperStatus (Port &port, sai_port_oper_status_t status)
8093
8209
{
8094
8210
SWSS_LOG_NOTICE (" Port %s oper state set from %s to %s" ,
0 commit comments