syncd/NotificationHandler.cpp (156 lines of code) (raw):

#include "NotificationHandler.h" #include "Workaround.h" #include "sairediscommon.h" #include "swss/logger.h" #include "meta/sai_serialize.h" #include <inttypes.h> using namespace syncd; NotificationHandler::NotificationHandler( _In_ std::shared_ptr<NotificationProcessor> processor, _In_ sai_api_version_t apiVersion): m_processor(processor), m_apiVersion(apiVersion) { SWSS_LOG_ENTER(); memset(&m_switchNotifications, 0, sizeof(m_switchNotifications)); m_notificationQueue = processor->getQueue(); } NotificationHandler::~NotificationHandler() { SWSS_LOG_ENTER(); // empty } void NotificationHandler::setApiVersion( _In_ sai_api_version_t apiVersion) { SWSS_LOG_ENTER(); m_apiVersion = apiVersion; } sai_api_version_t NotificationHandler::getApiVersion() const { SWSS_LOG_ENTER(); return m_apiVersion; } void NotificationHandler::setSwitchNotifications( _In_ const sai_switch_notifications_t& switchNotifications) { SWSS_LOG_ENTER(); m_switchNotifications = switchNotifications; } const sai_switch_notifications_t& NotificationHandler::getSwitchNotifications() const { SWSS_LOG_ENTER(); return m_switchNotifications; } void NotificationHandler::updateNotificationsPointers( _In_ uint32_t attr_count, _In_ sai_attribute_t *attr_list) const { SWSS_LOG_ENTER(); /* * This function should only be called on CREATE/SET api when object is * SWITCH. * * Notifications pointers needs to be corrected since those we receive from * sairedis are in sairedis memory space and here we are using those ones * we declared in syncd memory space. * * Also notice that we are using the same pointers for ALL switches. */ sai_metadata_update_attribute_notification_pointers(&m_switchNotifications, attr_count, attr_list); } // TODO use same Notification class from sairedis lib // then this will handle deserialize free void NotificationHandler::onFdbEvent( _In_ uint32_t count, _In_ const sai_fdb_event_notification_data_t *data) { SWSS_LOG_ENTER(); std::string s = sai_serialize_fdb_event_ntf(count, data); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_FDB_EVENT, s); } void NotificationHandler::onNatEvent( _In_ uint32_t count, _In_ const sai_nat_event_notification_data_t *data) { SWSS_LOG_ENTER(); std::string s = sai_serialize_nat_event_ntf(count, data); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_NAT_EVENT, s); } void NotificationHandler::onPortStateChange( _In_ uint32_t count, _In_ const sai_port_oper_status_notification_t *data) { SWSS_LOG_ENTER(); auto ntfdata = Workaround::convertPortOperStatusNotification(count, data, m_apiVersion); auto s = sai_serialize_port_oper_status_ntf((uint32_t)ntfdata.size(), ntfdata.data()); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_PORT_STATE_CHANGE, s); } void NotificationHandler::onPortHostTxReady( _In_ sai_object_id_t switch_id, _In_ sai_object_id_t port_id, _In_ sai_port_host_tx_ready_status_t host_tx_ready_status) { SWSS_LOG_ENTER(); auto s = sai_serialize_port_host_tx_ready_ntf(switch_id, port_id, host_tx_ready_status); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_PORT_HOST_TX_READY, s); } void NotificationHandler::onQueuePfcDeadlock( _In_ uint32_t count, _In_ const sai_queue_deadlock_notification_data_t *data) { SWSS_LOG_ENTER(); auto s = sai_serialize_queue_deadlock_ntf(count, data); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_QUEUE_PFC_DEADLOCK, s); } void NotificationHandler::onSwitchShutdownRequest( _In_ sai_object_id_t switch_id) { SWSS_LOG_ENTER(); auto s = sai_serialize_switch_shutdown_request(switch_id); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_SWITCH_SHUTDOWN_REQUEST, s); } void NotificationHandler::onSwitchAsicSdkHealthEvent( _In_ sai_object_id_t switch_id, _In_ sai_switch_asic_sdk_health_severity_t severity, _In_ sai_timespec_t timestamp, _In_ sai_switch_asic_sdk_health_category_t category, _In_ sai_switch_health_data_t data, _In_ const sai_u8_list_t description) { SWSS_LOG_ENTER(); std::string s = sai_serialize_switch_asic_sdk_health_event(switch_id, severity, timestamp, category, data, description); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_SWITCH_ASIC_SDK_HEALTH_EVENT, s); } void NotificationHandler::onSwitchStateChange( _In_ sai_object_id_t switch_id, _In_ sai_switch_oper_status_t switch_oper_status) { SWSS_LOG_ENTER(); auto s = sai_serialize_switch_oper_status(switch_id, switch_oper_status); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_SWITCH_STATE_CHANGE, s); } void NotificationHandler::onBfdSessionStateChange( _In_ uint32_t count, _In_ const sai_bfd_session_state_notification_t *data) { SWSS_LOG_ENTER(); std::string s = sai_serialize_bfd_session_state_ntf(count, data); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_BFD_SESSION_STATE_CHANGE, s); } void NotificationHandler::enqueueNotification( _In_ const std::string& op, _In_ const std::string& data, _In_ const std::vector<swss::FieldValueTuple> &entry) { SWSS_LOG_ENTER(); SWSS_LOG_INFO("%s %s", op.c_str(), data.c_str()); swss::KeyOpFieldsValuesTuple item(op, data, entry); if (m_notificationQueue->enqueue(item)) { m_processor->signal(); } } void NotificationHandler::onTwampSessionEvent( _In_ uint32_t count, _In_ const sai_twamp_session_event_notification_data_t *data) { SWSS_LOG_ENTER(); std::string s = sai_serialize_twamp_session_event_ntf(count, data); enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_TWAMP_SESSION_EVENT, s); } void NotificationHandler::enqueueNotification( _In_ const std::string& op, _In_ const std::string& data) { SWSS_LOG_ENTER(); std::vector<swss::FieldValueTuple> entry; enqueueNotification(op, data, entry); }