diff --git a/.gitmodules b/.gitmodules index cea7ddefd9..9fd9de1c09 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "SAI"] path = SAI url = https://github.com/sonic-otn/SAI.git + branch = 202411_otn diff --git a/SAI b/SAI index 4923e924ac..a73e92089a 160000 --- a/SAI +++ b/SAI @@ -1 +1 @@ -Subproject commit 4923e924ace60b702b1f166038a56c2b3120e2e0 +Subproject commit a73e92089aa593afc9dfcd9c24219cd0d7081648 diff --git a/debian/libsaimetadata-dev.install b/debian/libsaimetadata-dev.install index 7421e79035..aff4dd3e47 100644 --- a/debian/libsaimetadata-dev.install +++ b/debian/libsaimetadata-dev.install @@ -7,6 +7,7 @@ meta/OidRefCounter.h usr/include/sai meta/PortRelatedSet.h usr/include/sai meta/Notification*.h usr/include/sai meta/Globals.h usr/include/sai +meta/sai_serialize_otn.h usr/include/sai SAI/meta/sai*.h usr/include/sai usr/lib/*/libsaimetadata.so usr/lib/*/libsaimeta.so diff --git a/lib/RedisRemoteSaiInterface.cpp b/lib/RedisRemoteSaiInterface.cpp index b47e7de640..a4372026f1 100644 --- a/lib/RedisRemoteSaiInterface.cpp +++ b/lib/RedisRemoteSaiInterface.cpp @@ -575,8 +575,6 @@ sai_status_t RedisRemoteSaiInterface::notifyCounterGroupOperations( std::string key((const char*)flexCounterGroupParam->counter_group_name.list, flexCounterGroupParam->counter_group_name.count); emplaceStrings(POLL_INTERVAL_FIELD, flexCounterGroupParam->poll_interval, entries); - emplaceStrings(BULK_CHUNK_SIZE_FIELD, flexCounterGroupParam->bulk_chunk_size, entries); - emplaceStrings(BULK_CHUNK_SIZE_PER_PREFIX_FIELD, flexCounterGroupParam->bulk_chunk_size_per_prefix, entries); emplaceStrings(STATS_MODE_FIELD, flexCounterGroupParam->stats_mode, entries); emplaceStrings(flexCounterGroupParam->plugin_name, flexCounterGroupParam->plugins, entries); emplaceStrings(FLEX_COUNTER_STATUS_FIELD, flexCounterGroupParam->operation, entries); diff --git a/meta/Makefile.am b/meta/Makefile.am index 81c695d2e3..4855e448c5 100644 --- a/meta/Makefile.am +++ b/meta/Makefile.am @@ -45,6 +45,7 @@ libsaimeta_la_SOURCES = \ NotificationTamTelTypeConfigChange.cpp \ NotificationSwitchMacsecPostStatus.cpp \ NotificationMacsecPostStatus.cpp \ + NotificationOtnAlarmEvent.cpp \ NumberOidIndexGenerator.cpp \ OidRefCounter.cpp \ PerformanceIntervalTimer.cpp \ @@ -58,7 +59,8 @@ libsaimeta_la_SOURCES = \ SaiSerialize.cpp \ SelectableChannel.cpp \ DummySaiInterface.cpp \ - ZeroMQSelectableChannel.cpp + ZeroMQSelectableChannel.cpp \ + sai_serialize_otn.cpp libsaimeta_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) libsaimeta_la_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) diff --git a/meta/Meta.cpp b/meta/Meta.cpp index ca562b8167..47703f0528 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -3474,18 +3474,24 @@ sai_status_t Meta::meta_generic_validation_create( { const char* chardata = value.chardata; - size_t len = strnlen(chardata, SAI_HOSTIF_NAME_SIZE); + // Check the length of host interface name and genetlink multicast group name. + // Others should be less than the size defined for char data array. + size_t limit_len = attr->id == SAI_HOSTIF_ATTR_NAME ? SAI_HOSTIF_NAME_SIZE : + (attr->id == SAI_HOSTIF_ATTR_GENETLINK_MCGRP_NAME ? SAI_HOSTIF_GENETLINK_MCGRP_NAME_SIZE : + sizeof(((sai_attribute_value_t*)nullptr)->chardata)); - if (len == SAI_HOSTIF_NAME_SIZE) + size_t len = strnlen(chardata, limit_len); + + if (len == limit_len) { - META_LOG_ERROR(md, "host interface name is too long"); + META_LOG_ERROR(md, "char data is too long"); return SAI_STATUS_INVALID_PARAMETER; } if (len == 0) { - META_LOG_ERROR(md, "host interface name is zero"); + META_LOG_ERROR(md, "char data is zero"); return SAI_STATUS_INVALID_PARAMETER; } @@ -3496,7 +3502,7 @@ sai_status_t Meta::meta_generic_validation_create( if (c < 0x20 || c > 0x7e) { - META_LOG_ERROR(md, "interface name contains invalid character 0x%02x", c); + META_LOG_ERROR(md, "char data contains invalid character 0x%02x", c); return SAI_STATUS_INVALID_PARAMETER; } @@ -7591,3 +7597,67 @@ std::vector Meta::getValidIcmpEchoSessionObjectTypes() return v; } + +void Meta::meta_sai_on_otn_alarm_event_single( + _In_ const sai_otn_alarm_event_data_t& data) +{ + SWSS_LOG_ENTER(); + + auto ot = objectTypeQuery(data.object_id); + + bool valid = false; + + switch ((int)ot) + { + // TODO hardcoded types, must advance SAI repository commit to get metadata for this + case SAI_OBJECT_TYPE_OTN_DEVICE: + case SAI_OBJECT_TYPE_OTN_ATTENUATOR: + case SAI_OBJECT_TYPE_OTN_OA: + case SAI_OBJECT_TYPE_OTN_OCM: + case SAI_OBJECT_TYPE_OTN_OCM_CHANNEL: + case SAI_OBJECT_TYPE_OTN_OSC: + + valid = true; + break; + + default: + + SWSS_LOG_ERROR("data.object_id %s has unexpected type: %s, expected OTN_DEVICE", + sai_serialize_object_id(data.object_id).c_str(), + sai_serialize_object_type(ot).c_str()); + break; + } + + if (valid && !m_oids.objectReferenceExists(data.object_id)) + { + SWSS_LOG_NOTICE("data.object_id new object spotted %s not present in local DB (snoop!)", + sai_serialize_object_id(data.object_id).c_str()); + + sai_object_meta_key_t key = { .objecttype = (sai_object_type_t)ot, .objectkey = { .key = { .object_id = data.object_id } } }; + + m_oids.objectReferenceInsert(data.object_id); + + if (!m_saiObjectCollection.objectExists(key)) + { + m_saiObjectCollection.createObject(key); + } + } +} + +void Meta::meta_sai_on_otn_alarm_event( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + if (count && data == NULL) + { + SWSS_LOG_ERROR("sai_otn_alarm_event_notification_data_t pointer is NULL but count is %u", count); + return; + } + + for (uint32_t i = 0; i < count; ++i) + { + meta_sai_on_otn_alarm_event_single(data[i]); + } +} diff --git a/meta/Meta.h b/meta/Meta.h index 85d3466584..817ecd3039 100644 --- a/meta/Meta.h +++ b/meta/Meta.h @@ -273,7 +273,11 @@ namespace saimeta void meta_sai_on_tam_tel_type_config_change(_In_ sai_object_id_t m_tam_id); - private: // notifications helpers + void meta_sai_on_otn_alarm_event( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data); + + private: // notifications helpers void meta_sai_on_fdb_flush_event_consolidated( _In_ const sai_fdb_event_notification_data_t& data); @@ -308,7 +312,10 @@ namespace saimeta void meta_sai_on_twamp_session_event_single( _In_ const sai_twamp_session_event_notification_data_t& data); - private: // validation helpers + void meta_sai_on_otn_alarm_event_single( + _In_ const sai_otn_alarm_event_data_t& data); + + private: // validation helpers sai_status_t meta_generic_validation_objlist( _In_ const sai_attr_metadata_t& md, diff --git a/meta/NotificationFactory.cpp b/meta/NotificationFactory.cpp index fe8769d4d8..e849ae643e 100644 --- a/meta/NotificationFactory.cpp +++ b/meta/NotificationFactory.cpp @@ -16,6 +16,7 @@ #include "NotificationFlowBulkGetSessionEvent.h" #include "NotificationSwitchMacsecPostStatus.h" #include "NotificationMacsecPostStatus.h" +#include "NotificationOtnAlarmEvent.h" #include "sairediscommon.h" #include "swss/logger.h" @@ -79,5 +80,8 @@ std::shared_ptr NotificationFactory::deserialize( if (name == SAI_SWITCH_NOTIFICATION_NAME_MACSEC_POST_STATUS) return std::make_shared(serializedNotification); + if (name == SAI_SWITCH_NOTIFICATION_NAME_OTN_ALARM_EVENT) + return std::make_shared(serializedNotification); + SWSS_LOG_THROW("unknown notification: '%s', FIXME", name.c_str()); } diff --git a/meta/NotificationOtnAlarmEvent.cpp b/meta/NotificationOtnAlarmEvent.cpp new file mode 100644 index 0000000000..e3b8f396f6 --- /dev/null +++ b/meta/NotificationOtnAlarmEvent.cpp @@ -0,0 +1,80 @@ +#include "NotificationOtnAlarmEvent.h" + +#include "swss/logger.h" + +#include "meta/sai_serialize_otn.h" + +using namespace sairedis; + +NotificationOtnAlarmEvent::NotificationOtnAlarmEvent( + _In_ const std::string& serializeNotification): + Notification( + SAI_SWITCH_NOTIFICATION_TYPE_OTN_ALARM_EVENT, + serializeNotification), + m_otnAlarmEventData(nullptr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_otn_alarm_event_ntf( + serializeNotification, + m_count, + &m_otnAlarmEventData); +} + +NotificationOtnAlarmEvent::~NotificationOtnAlarmEvent() +{ + SWSS_LOG_ENTER(); + + sai_deserialize_free_otn_alarm_event_ntf(m_count, m_otnAlarmEventData); +} + +sai_object_id_t NotificationOtnAlarmEvent::getSwitchId() const +{ + SWSS_LOG_ENTER(); + + // Otn alarm event does not have switch id + return SAI_NULL_OBJECT_ID; +} + +sai_object_id_t NotificationOtnAlarmEvent::getAnyObjectId() const +{ + SWSS_LOG_ENTER(); + + if (m_otnAlarmEventData == nullptr) + { + return SAI_NULL_OBJECT_ID; + } + + for (uint32_t i = 0; i < m_count; ++i) + { + if (m_otnAlarmEventData[i].object_id != SAI_NULL_OBJECT_ID) + { + return m_otnAlarmEventData[i].object_id; + } + } + + return SAI_NULL_OBJECT_ID; +} + +void NotificationOtnAlarmEvent::processMetadata( + _In_ std::shared_ptr meta) const +{ + SWSS_LOG_ENTER(); + + meta->meta_sai_on_otn_alarm_event( + m_count, + m_otnAlarmEventData); +} + +void NotificationOtnAlarmEvent::executeCallback( + _In_ const sai_switch_notifications_t& switchNotifications) const +{ + SWSS_LOG_ENTER(); + + if(switchNotifications.on_otn_alarm_event) + { + switchNotifications.on_otn_alarm_event( + m_count, + m_otnAlarmEventData); + } +} diff --git a/meta/NotificationOtnAlarmEvent.h b/meta/NotificationOtnAlarmEvent.h new file mode 100644 index 0000000000..33749cd096 --- /dev/null +++ b/meta/NotificationOtnAlarmEvent.h @@ -0,0 +1,35 @@ +#pragma once + +#include "Notification.h" + +namespace sairedis +{ + class NotificationOtnAlarmEvent: + public Notification + { + public: + + NotificationOtnAlarmEvent( + _In_ const std::string& serializedNotification); + + virtual ~NotificationOtnAlarmEvent(); + + public: + + virtual sai_object_id_t getSwitchId() const override; + + virtual sai_object_id_t getAnyObjectId() const override; + + virtual void processMetadata( + _In_ std::shared_ptr meta) const override; + + virtual void executeCallback( + _In_ const sai_switch_notifications_t& switchNotifications) const override; + + private: + + uint32_t m_count; + + sai_otn_alarm_event_data_t* m_otnAlarmEventData; + }; +} diff --git a/meta/sai_serialize.h b/meta/sai_serialize.h index 2a9ec67363..c459cecf2c 100644 --- a/meta/sai_serialize.h +++ b/meta/sai_serialize.h @@ -820,3 +820,8 @@ void sai_deserialize_macsec_post_status_ntf( _In_ const std::string& s, _Out_ sai_object_id_t& macsec_id, _Out_ sai_macsec_post_status_t& macsec_post_status); + +void sai_deserialize_hex_binary( + _In_ const std::string &s, + _Out_ void *buffer, + _In_ size_t length); diff --git a/meta/sai_serialize_otn.cpp b/meta/sai_serialize_otn.cpp new file mode 100644 index 0000000000..65f41b1bee --- /dev/null +++ b/meta/sai_serialize_otn.cpp @@ -0,0 +1,186 @@ +#include "sai_serialize_otn.h" +#include "meta/sai_serialize.h" +#include + +using json = nlohmann::json; + + +std::string sai_serialize_otn_attenuator_attr( + _In_ const sai_otn_attenuator_attr_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_otn_attenuator_attr_t); +} + +void sai_deserialize_otn_attenuator_attr( + _In_ const std::string& s, + _Out_ sai_otn_attenuator_attr_t& attr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_enum(s, &sai_metadata_enum_sai_otn_attenuator_attr_t, (int32_t&)attr); +} + +std::string sai_serialize_otn_oa_attr( + _In_ const sai_otn_oa_attr_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_otn_oa_attr_t); +} + +void sai_deserialize_otn_oa_attr( + _In_ const std::string& s, + _Out_ sai_otn_oa_attr_t& attr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_enum(s, &sai_metadata_enum_sai_otn_oa_attr_t, (int32_t&)attr); +} + +std::string sai_serialize_otn_ocm_attr( + _In_ const sai_otn_ocm_attr_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_otn_ocm_attr_t); +} + +void sai_deserialize_otn_ocm_attr( + _In_ const std::string& s, + _Out_ sai_otn_ocm_attr_t& attr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_enum(s, &sai_metadata_enum_sai_otn_ocm_attr_t, (int32_t&)attr); +} + + +std::string sai_serialize_otn_ocm_channel_attr( + _In_ const sai_otn_ocm_channel_attr_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_otn_ocm_channel_attr_t); +} + +void sai_deserialize_otn_ocm_channel_attr( + _In_ const std::string& s, + _Out_ sai_otn_ocm_channel_attr_t& attr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_enum(s, &sai_metadata_enum_sai_otn_ocm_channel_attr_t, (int32_t&)attr); +} + +std::string sai_serialize_otn_osc_attr( + _In_ const sai_otn_osc_attr_t counter) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_enum(counter, &sai_metadata_enum_sai_otn_osc_attr_t); +} + +void sai_deserialize_otn_osc_attr( + _In_ const std::string& s, + _Out_ sai_otn_osc_attr_t& attr) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_enum(s, &sai_metadata_enum_sai_otn_osc_attr_t, (int32_t&)attr); +} + +std::string sai_serialize_otn_alarm_event_ntf( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t* otn_alarm_event) +{ + SWSS_LOG_ENTER(); + + if (otn_alarm_event == NULL) + { + SWSS_LOG_THROW("otn_alarm_event pointer is null"); + } + + json j = json::array(); + + for (uint32_t i = 0; i < count; ++i) + { + json item; + + item["object_id"] = sai_serialize_object_id(otn_alarm_event[i].object_id); + /* cast from uint8_t* to string */ + item["event_name"] = std::string((char*)otn_alarm_event[i].event_name.list, otn_alarm_event[i].event_name.count); + item["timestamp"] = sai_serialize_timespec(otn_alarm_event[i].timestamp); + item["severity"] = sai_serialize_enum(otn_alarm_event[i].severity, &sai_metadata_enum_sai_otn_alarm_severity_t); + item["action"] = sai_serialize_enum(otn_alarm_event[i].action, &sai_metadata_enum_sai_otn_alarm_action_t); + /* cast from uint8_t* to string */ + item["description"] = std::string((char*)otn_alarm_event[i].description.list, otn_alarm_event[i].description.count); + /* cast from uint8_t* to hex binary */ + item["data"] = sai_serialize_hex_binary(otn_alarm_event[i].data.list, otn_alarm_event[i].data.count); + j.push_back(item); + } + + return j.dump(); +} + +void sai_deserialize_otn_alarm_event_ntf( + _In_ const std::string& s, + _Out_ uint32_t& count, + _Out_ sai_otn_alarm_event_data_t** otn_alarm_event) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + count = (uint32_t)j.size(); + + auto data = new sai_otn_alarm_event_data_t[count]; + + for (uint32_t i = 0; i < count; ++i) + { + sai_deserialize_object_id(j[i]["object_id"], data[i].object_id); + + std::string s_event_name = j[i]["event_name"]; + data[i].event_name.count = (uint32_t)s_event_name.length(); + data[i].event_name.list = new uint8_t[data[i].event_name.count + 1]; + memcpy(data[i].event_name.list, s_event_name.c_str(), data[i].event_name.count + 1); + + sai_deserialize_timespec(j[i]["timestamp"], data[i].timestamp); + + int32_t val; + sai_deserialize_enum(j[i]["severity"], &sai_metadata_enum_sai_otn_alarm_severity_t, val); + data[i].severity = (sai_otn_alarm_severity_t)val; + + sai_deserialize_enum(j[i]["action"], &sai_metadata_enum_sai_otn_alarm_action_t, val); + data[i].action = (sai_otn_alarm_action_t)val; + + std::string s_desc = j[i]["description"]; + data[i].description.count = (uint32_t)s_desc.length(); + data[i].description.list = new uint8_t[data[i].description.count + 1]; + memcpy(data[i].description.list, s_desc.c_str(), data[i].description.count + 1); + + std::string s_data = j[i]["data"]; + data[i].data.count = (uint32_t)s_data.length() / 2; + data[i].data.list = new uint8_t[data[i].data.count]; + sai_deserialize_hex_binary(s_data, data[i].data.list, data[i].data.count); + } + + *otn_alarm_event = data; +} + +void sai_deserialize_free_otn_alarm_event_ntf( + _In_ uint32_t count, + _In_ sai_otn_alarm_event_data_t* otn_alarm_event) +{ + SWSS_LOG_ENTER(); + + for (uint32_t i = 0; i < count; ++i) + { + delete[] otn_alarm_event[i].event_name.list; + delete[] otn_alarm_event[i].description.list; + delete[] otn_alarm_event[i].data.list; + } + + delete[] otn_alarm_event; +} diff --git a/meta/sai_serialize_otn.h b/meta/sai_serialize_otn.h new file mode 100644 index 0000000000..3dad05c674 --- /dev/null +++ b/meta/sai_serialize_otn.h @@ -0,0 +1,62 @@ +#pragma once + +extern "C" { +#include "sai.h" +#include "saimetadata.h" +} + +#include + +// OTN attenuator +std::string sai_serialize_otn_attenuator_attr( + _In_ const sai_otn_attenuator_attr_t counter); + +void sai_deserialize_otn_attenuator_attr( + _In_ const std::string& s, + _Out_ sai_otn_attenuator_attr_t& attr); + +// OTN oa +std::string sai_serialize_otn_oa_attr( + _In_ const sai_otn_oa_attr_t counter); + +void sai_deserialize_otn_oa_attr( + _In_ const std::string& s, + _Out_ sai_otn_oa_attr_t& attr); + +// OTN ocm +std::string sai_serialize_otn_ocm_attr( + _In_ const sai_otn_ocm_attr_t counter); + +void sai_deserialize_otn_ocm_attr( + _In_ const std::string& s, + _Out_ sai_otn_ocm_attr_t& attr); + +// OTN ocm channel +std::string sai_serialize_otn_ocm_channel_attr( + _In_ const sai_otn_ocm_channel_attr_t counter); + +void sai_deserialize_otn_ocm_channel_attr( + _In_ const std::string& s, + _Out_ sai_otn_ocm_channel_attr_t& attr); + +// OTN osc +std::string sai_serialize_otn_osc_attr( + _In_ const sai_otn_osc_attr_t counter); + +void sai_deserialize_otn_osc_attr( + _In_ const std::string& s, + _Out_ sai_otn_osc_attr_t& attr); + +// OTN alarm event notification +std::string sai_serialize_otn_alarm_event_ntf( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *otn_alarm_event); + +void sai_deserialize_otn_alarm_event_ntf( + _In_ const std::string& s, + _Out_ uint32_t& count, + _Out_ sai_otn_alarm_event_data_t** otn_alarm_event); + +void sai_deserialize_free_otn_alarm_event_ntf( + _In_ uint32_t count, + _In_ sai_otn_alarm_event_data_t* otn_alarm_event); diff --git a/proxylib/Proxy.cpp b/proxylib/Proxy.cpp index b48e20fc4a..6021df0ca0 100644 --- a/proxylib/Proxy.cpp +++ b/proxylib/Proxy.cpp @@ -6,6 +6,7 @@ #include "meta/SaiAttributeList.h" #include "meta/sai_serialize.h" +#include "meta/sai_serialize_otn.h" #include "meta/ZeroMQSelectableChannel.h" #include "syncd/ZeroMQNotificationProducer.h" @@ -1296,3 +1297,14 @@ uint64_t Proxy::getNotificationsSentCount() const return m_notificationsSentCount; } + +void Proxy::onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + std::string s = sai_serialize_otn_alarm_event_ntf(count, data); + + sendNotification(SAI_SWITCH_NOTIFICATION_NAME_OTN_ALARM_EVENT, s); +} diff --git a/proxylib/Proxy.h b/proxylib/Proxy.h index 6c3df76e0d..fd98ed69a3 100644 --- a/proxylib/Proxy.h +++ b/proxylib/Proxy.h @@ -172,6 +172,10 @@ namespace saiproxy void onTamTelTypeConfigChange( _In_ sai_object_id_t tam_tel_id); + void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data); + void sendNotification( _In_ const std::string& op, _In_ const std::string& data); diff --git a/pyext/pysairedis.i b/pyext/pysairedis.i index d749d4efaa..fee151fa07 100644 --- a/pyext/pysairedis.i +++ b/pyext/pysairedis.i @@ -84,6 +84,8 @@ sai_ip_prefix_t* sai_ip_prefix_t_from_string(const std::string& s); %pointer_functions(sai_port_oper_status_notification_t, sai_port_oper_status_notification_t_p); %array_functions(sai_queue_deadlock_notification_data_t, sai_queue_deadlock_notification_data_t_arr); %pointer_functions(sai_queue_deadlock_notification_data_t, sai_queue_deadlock_notification_data_t_p); +%array_functions(sai_otn_alarm_event_data_t, sai_otn_alarm_event_data_t_arr); +%pointer_functions(sai_otn_alarm_event_data_t, sai_otn_alarm_event_data_t_p); %{ PyObject *py_convert_sai_fdb_event_notification_data_t_to_PyObject(const sai_fdb_event_notification_data_t*ntf) @@ -102,6 +104,8 @@ PyObject *py_convert_sai_port_oper_status_notification_t_to_PyObject(const sai_p { return SWIG_NewPointerObj((void*)ntf, SWIGTYPE_p__sai_port_oper_status_notification_t, 0 | 0); } PyObject *py_convert_sai_queue_deadlock_notification_data_t_to_PyObject(const sai_queue_deadlock_notification_data_t*ntf) { return SWIG_NewPointerObj((void*)ntf, SWIGTYPE_p__sai_queue_deadlock_notification_data_t, 0 | 0); } +PyObject *py_convert_sai_otn_alarm_event_data_t_to_PyObject(const sai_otn_alarm_event_data_t*ntf) +{ return SWIG_NewPointerObj((void*)ntf, SWIGTYPE_p__sai_otn_alarm_event_data_t, 0 | 0); } %} diff --git a/saiplayer/SaiPlayer.cpp b/saiplayer/SaiPlayer.cpp index eff9a8e5a6..65090c34c3 100644 --- a/saiplayer/SaiPlayer.cpp +++ b/saiplayer/SaiPlayer.cpp @@ -96,6 +96,8 @@ SaiPlayer::SaiPlayer( m_sn.onFlowBulkGetSessionEvent = std::bind(&SaiPlayer::onFlowBulkGetSessionEvent, this, _1, _2, _3); m_sn.onPortHostTxReady = std::bind(&SaiPlayer::onPortHostTxReady, this, _1, _2, _3); m_sn.onIcmpEchoSessionStateChange = std::bind(&SaiPlayer::onIcmpEchoSessionStateChange, this, _1, _2); + m_sn.onOtnAlarmEvent = std::bind(&SaiPlayer::onOtnAlarmEvent, this, _1, _2); + m_switchNotifications= m_sn.getSwitchNotifications(); } @@ -227,6 +229,15 @@ void SaiPlayer::onPortHostTxReady( // empty } +void SaiPlayer::onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + // empty +} + void SaiPlayer::onQueuePfcDeadlock( _In_ uint32_t count, _In_ const sai_queue_deadlock_notification_data_t *data) diff --git a/saiplayer/SaiPlayer.h b/saiplayer/SaiPlayer.h index da320a16de..40ab06447e 100644 --- a/saiplayer/SaiPlayer.h +++ b/saiplayer/SaiPlayer.h @@ -289,6 +289,10 @@ namespace saiplayer _In_ sai_object_id_t port_id, _In_ sai_port_host_tx_ready_status_t host_tx_ready_status); + void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data); + private: std::shared_ptr m_sai; diff --git a/syncd/FlexCounter.cpp b/syncd/FlexCounter.cpp index 40978ff8fe..f179bb08a2 100644 --- a/syncd/FlexCounter.cpp +++ b/syncd/FlexCounter.cpp @@ -97,9 +97,8 @@ const std::map, std::string> FlexCoun {{SAI_OBJECT_TYPE_SWITCH, SWITCH_COUNTER_ID_LIST}, COUNTER_TYPE_SWITCH}, }; -BaseCounterContext::BaseCounterContext(const std::string &name, const std::string &instance): -m_name(name), -m_instanceId(instance) +BaseCounterContext::BaseCounterContext(const std::string &name): +m_name(name) { SWSS_LOG_ENTER(); } @@ -130,20 +129,6 @@ void BaseCounterContext::setNoDoubleCheckBulkCapability( no_double_check_bulk_capability = noDoubleCheckBulkCapability; } -void BaseCounterContext::setBulkChunkSize( - _In_ uint32_t bulkChunkSize) -{ - SWSS_LOG_ENTER(); - default_bulk_chunk_size = bulkChunkSize; -} - -void BaseCounterContext::setBulkChunkSizePerPrefix( - _In_ const std::string& bulkChunkSizePerPrefix) -{ - SWSS_LOG_ENTER(); - m_bulkChunkSizePerPrefix = bulkChunkSizePerPrefix; -} - template struct CounterIds @@ -544,11 +529,10 @@ class CounterContext : public BaseCounterContext CounterContext( _In_ const std::string &name, - _In_ const std::string &instance, _In_ sai_object_type_t object_type, _In_ sairedis::SaiInterface *vendor_sai, _In_ sai_stats_mode_t &stats_mode): - BaseCounterContext(name, instance), m_objectType(object_type), m_vendorSai(vendor_sai), m_groupStatsMode(stats_mode) + BaseCounterContext(name), m_objectType(object_type), m_vendorSai(vendor_sai), m_groupStatsMode(stats_mode) { SWSS_LOG_ENTER(); } @@ -646,10 +630,10 @@ class CounterContext : public BaseCounterContext } m_objectIdsMap.emplace(vid, counter_data); } - else if (m_counterChunkSizeMapFromPrefix.empty()) + else { std::sort(supportedIds.begin(), supportedIds.end()); - auto bulkContext = getBulkStatsContext(supportedIds, "default", default_bulk_chunk_size); + auto bulkContext = getBulkStatsContext(supportedIds); addBulkStatsContext(vid, rid, supportedIds, *bulkContext.get()); } else @@ -1188,9 +1172,6 @@ class CounterContext : public BaseCounterContext { return; } - - SWSS_LOG_DEBUG("Before running plugin %s %s", m_instanceId.c_str(), m_name.c_str()); - std::vector idStrings; idStrings.reserve(m_objectIdsMap.size()); std::transform(m_objectIdsMap.begin(), @@ -1209,8 +1190,6 @@ class CounterContext : public BaseCounterContext std::for_each(m_plugins.begin(), m_plugins.end(), [&] (auto &sha) { runRedisScript(counters_db, sha, idStrings, argv); }); - - SWSS_LOG_DEBUG("After running plugin %s %s", m_instanceId.c_str(), m_name.c_str()); } bool hasObject() const override @@ -1313,11 +1292,19 @@ class CounterContext : public BaseCounterContext { SWSS_LOG_ENTER(); auto statsMode = m_groupStatsMode == SAI_STATS_MODE_READ ? SAI_STATS_MODE_BULK_READ : SAI_STATS_MODE_BULK_READ_AND_CLEAR; - uint32_t bulk_chunk_size = ctx.default_bulk_chunk_size; - uint32_t size = static_cast(ctx.object_keys.size()); - if (bulk_chunk_size > size || bulk_chunk_size == 0) + sai_status_t status = m_vendorSai->bulkGetStats( + SAI_NULL_OBJECT_ID, + m_objectType, + static_cast(ctx.object_keys.size()), + ctx.object_keys.data(), + static_cast(ctx.counter_ids.size()), + reinterpret_cast(ctx.counter_ids.data()), + statsMode, + ctx.object_statuses.data(), + ctx.counters.data()); + if (SAI_STATUS_SUCCESS != status) { - bulk_chunk_size = size; + SWSS_LOG_WARN("Failed to bulk get stats for %s: %u", m_name.c_str(), status); } uint32_t current = 0; @@ -1384,9 +1371,7 @@ class CounterContext : public BaseCounterContext } auto getBulkStatsContext( - _In_ const std::vector& counterIds, - _In_ const std::string& name, - _In_ uint32_t bulk_chunk_size=0) + _In_ const std::vector& counterIds) { SWSS_LOG_ENTER(); auto iter = m_bulkContexts.find(counterIds); @@ -1395,23 +1380,10 @@ class CounterContext : public BaseCounterContext return iter->second; } - SWSS_LOG_NOTICE("Create bulk stat context %s %s %s", m_instanceId.c_str(), m_name.c_str(), name.c_str()); auto ret = m_bulkContexts.emplace(counterIds, std::make_shared()); - ret.first->second.get()->name = name; - ret.first->second.get()->default_bulk_chunk_size = bulk_chunk_size; - ret.first->second.get()->counter_ids = counterIds; return ret.first->second; } - void setBulkStatsContext( - _In_ const std::vector& counterIds, - _In_ const std::shared_ptr ptr) - { - SWSS_LOG_ENTER(); - m_bulkContexts.emplace(counterIds, ptr); - ptr.get()->counter_ids = counterIds; - } - void addBulkStatsContext( _In_ sai_object_id_t vid, _In_ sai_object_id_t rid, @@ -1431,6 +1403,10 @@ class CounterContext : public BaseCounterContext sai_object_key_t object_key; object_key.key.object_id = rid; ctx.object_keys.push_back(object_key); + if (ctx.counter_ids.empty()) + { + ctx.counter_ids = counterIds; + } ctx.object_statuses.push_back(SAI_STATUS_SUCCESS); ctx.counters.resize(counterIds.size() * ctx.object_keys.size()); } @@ -1468,7 +1444,6 @@ class CounterContext : public BaseCounterContext _In_ sai_object_id_t vid) { SWSS_LOG_ENTER(); - std::set> bulkContextsToBeRemoved; bool found = false; for (auto iter = m_bulkContexts.begin(); iter != m_bulkContexts.end(); iter++) { @@ -1484,9 +1459,7 @@ class CounterContext : public BaseCounterContext ctx.object_vids_set.erase(vid); if (ctx.object_vids.empty()) { - // It can change the order of the map to erase an element in a loop iterating the map - // which can cause some elements to be skipped or iterated for multiple times - bulkContextsToBeRemoved.insert(iter->first); + m_bulkContexts.erase(iter); } else { @@ -1496,20 +1469,7 @@ class CounterContext : public BaseCounterContext ctx.counters.resize(ctx.counter_ids.size() * ctx.object_keys.size()); ctx.object_statuses.pop_back(); } - if (m_counterChunkSizeMapFromPrefix.empty()) - { - break; - } - else - { - // There can be more than one bulk context containing the VID when the per counter ID bulk chunk size is configured - continue; - } - } - - for (auto iter : bulkContextsToBeRemoved) - { - m_bulkContexts.erase(iter); + break; } return found; @@ -1522,7 +1482,6 @@ class CounterContext : public BaseCounterContext { SWSS_LOG_ENTER(); BulkContextType ctx; - ctx.counter_ids = counter_ids; addBulkStatsContext(vid, rid, counter_ids, ctx); auto statsMode = m_groupStatsMode == SAI_STATS_MODE_READ ? SAI_STATS_MODE_BULK_READ : SAI_STATS_MODE_BULK_READ_AND_CLEAR; sai_status_t status = m_vendorSai->bulkGetStats( @@ -1667,11 +1626,10 @@ class AttrContext : public CounterContext typedef CounterContext Base; AttrContext( _In_ const std::string &name, - _In_ const std::string &instance, _In_ sai_object_type_t object_type, _In_ sairedis::SaiInterface *vendor_sai, _In_ sai_stats_mode_t &stats_mode): - CounterContext(name, instance, object_type, vendor_sai, stats_mode) + CounterContext(name, object_type, vendor_sai, stats_mode) { SWSS_LOG_ENTER(); } @@ -2627,10 +2585,9 @@ class DashMeterCounterContext : public BaseCounterContext public: DashMeterCounterContext( _In_ const std::string &name, - _In_ const std::string &instance, _In_ sairedis::SaiInterface *vendor_sai, _In_ std::string dbCounters): - BaseCounterContext(name, instance), m_dbCounters(dbCounters), m_vendorSai(vendor_sai) + BaseCounterContext(name), m_dbCounters(dbCounters), m_vendorSai(vendor_sai) { SWSS_LOG_ENTER(); } @@ -3007,6 +2964,8 @@ class DashMeterCounterContext : public BaseCounterContext bool m_initalized = false; }; +FLEX_COUNTER_OTN_IMPLEMENT(); + FlexCounter::FlexCounter( _In_ const std::string& instanceId, _In_ std::shared_ptr vendorSai, @@ -3024,6 +2983,10 @@ FlexCounter::FlexCounter( m_enable = false; m_isDiscarded = false; + m_flexCounterOtn = make_shared( + std::bind(&FlexCounter::getCounterContext, this, std::placeholders::_1), + std::bind(&FlexCounter::hasCounterContext, this, std::placeholders::_1)); + startFlexCounterThread(); } @@ -3131,8 +3094,6 @@ void FlexCounter::addCounterPlugin( SWSS_LOG_ENTER(); m_isDiscarded = false; - uint32_t bulkChunkSize = 0; - std::string bulkChunkSizePerPrefix; for (auto& fvt: values) { @@ -3145,34 +3106,6 @@ void FlexCounter::addCounterPlugin( { setPollInterval(stoi(value)); } - else if (field == BULK_CHUNK_SIZE_FIELD) - { - if (value != "NULL") - { - try - { - bulkChunkSize = stoi(value); - } - catch (...) - { - SWSS_LOG_ERROR("Invalid bulk chunk size %s", value.c_str()); - } - } - for (auto &context : m_counterContext) - { - SWSS_LOG_NOTICE("Set counter context %s %s bulk size %u", m_instanceId.c_str(), COUNTER_TYPE_PORT.c_str(), bulkChunkSize); - context.second->setBulkChunkSize(bulkChunkSize); - } - } - else if (field == BULK_CHUNK_SIZE_PER_PREFIX_FIELD) - { - bulkChunkSizePerPrefix = value; - for (auto &context : m_counterContext) - { - SWSS_LOG_NOTICE("Set counter context %s %s bulk chunk prefix map %s", m_instanceId.c_str(), COUNTER_TYPE_PORT.c_str(), bulkChunkSizePerPrefix.c_str()); - context.second->setBulkChunkSizePerPrefix(bulkChunkSizePerPrefix); - } - } else if (field == FLEX_COUNTER_STATUS_FIELD) { setStatus(value); @@ -3195,21 +3128,14 @@ void FlexCounter::addCounterPlugin( SWSS_LOG_NOTICE("Do not double check bulk capability counter context %s %s", m_instanceId.c_str(), counterTypeRef->second.c_str()); } - - if (bulkChunkSize > 0) - { - getCounterContext(counterTypeRef->second)->setBulkChunkSize(bulkChunkSize); - SWSS_LOG_NOTICE("Create counter context %s %s with bulk size %u", m_instanceId.c_str(), counterTypeRef->second.c_str(), bulkChunkSize); - } - - if (!bulkChunkSizePerPrefix.empty()) - { - getCounterContext(counterTypeRef->second)->setBulkChunkSizePerPrefix(bulkChunkSizePerPrefix); - SWSS_LOG_NOTICE("Create counter context %s %s with bulk prefix map %s", m_instanceId.c_str(), counterTypeRef->second.c_str(), bulkChunkSizePerPrefix.c_str()); - } } else { + if (m_flexCounterOtn ->addCounterPlugin(field, shaStrings)) + { + continue; + } + SWSS_LOG_ERROR("Field is not supported %s", field.c_str()); } } @@ -3266,13 +3192,12 @@ bool FlexCounter::allPluginsEmpty() const } std::shared_ptr FlexCounter::createCounterContext( - _In_ const std::string& context_name, - _In_ const std::string& instance) + _In_ const std::string& context_name) { SWSS_LOG_ENTER(); if (context_name == COUNTER_TYPE_PORT) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_PORT, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_PORT, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; return context; } @@ -3284,7 +3209,7 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_PORT_DEBUG) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_PORT, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_PORT, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; context->use_sai_stats_capa_query = false; context->use_sai_stats_ext = true; @@ -3293,7 +3218,7 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_QUEUE) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_QUEUE, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_QUEUE, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; context->double_confirm_supported_counters = true; return context; @@ -3307,18 +3232,18 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_PG) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; context->double_confirm_supported_counters = true; return context; } else if (context_name == COUNTER_TYPE_RIF) { - return std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_ROUTER_INTERFACE, m_vendorSai.get(), m_statsMode); + return std::make_shared>(context_name, SAI_OBJECT_TYPE_ROUTER_INTERFACE, m_vendorSai.get(), m_statsMode); } else if (context_name == COUNTER_TYPE_SWITCH_DEBUG) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_SWITCH, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_SWITCH, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; context->use_sai_stats_capa_query = false; context->use_sai_stats_ext = true; @@ -3327,13 +3252,13 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_MACSEC_FLOW) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_MACSEC_FLOW, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_MACSEC_FLOW, m_vendorSai.get(), m_statsMode); context->use_sai_stats_capa_query = false; return context; } else if (context_name == COUNTER_TYPE_MACSEC_SA) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_MACSEC_SA, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_MACSEC_SA, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; context->use_sai_stats_capa_query = false; context->dont_clear_support_counter = true; @@ -3341,7 +3266,7 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_FLOW) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_COUNTER, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_COUNTER, m_vendorSai.get(), m_statsMode); context->use_sai_stats_capa_query = false; context->use_sai_stats_ext = true; @@ -3349,19 +3274,19 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_TUNNEL) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_TUNNEL, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_TUNNEL, m_vendorSai.get(), m_statsMode); context->use_sai_stats_capa_query = false; return context; } else if (context_name == COUNTER_TYPE_BUFFER_POOL) { - auto context = std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_BUFFER_POOL, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, SAI_OBJECT_TYPE_BUFFER_POOL, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; return context; } else if (context_name == COUNTER_TYPE_ENI) { - auto context = std::make_shared>(context_name, instance, (sai_object_type_t)SAI_OBJECT_TYPE_ENI, m_vendorSai.get(), m_statsMode); + auto context = std::make_shared>(context_name, (sai_object_type_t)SAI_OBJECT_TYPE_ENI, m_vendorSai.get(), m_statsMode); context->always_check_supported_counters = true; return context; } @@ -3373,7 +3298,7 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == COUNTER_TYPE_METER_BUCKET) { - return std::make_shared(context_name, instance, m_vendorSai.get(), m_dbCounters); + return std::make_shared(context_name, m_vendorSai.get(), m_dbCounters); } else if (context_name == ATTR_TYPE_PORT_PHY_ATTR) { @@ -3385,23 +3310,23 @@ std::shared_ptr FlexCounter::createCounterContext( } else if (context_name == ATTR_TYPE_QUEUE) { - return std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_QUEUE, m_vendorSai.get(), m_statsMode); + return std::make_shared>(context_name, SAI_OBJECT_TYPE_QUEUE, m_vendorSai.get(), m_statsMode); } else if (context_name == ATTR_TYPE_PG) { - return std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, m_vendorSai.get(), m_statsMode); + return std::make_shared>(context_name, SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, m_vendorSai.get(), m_statsMode); } else if (context_name == ATTR_TYPE_MACSEC_SA) { - return std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_MACSEC_SA, m_vendorSai.get(), m_statsMode); + return std::make_shared>(context_name, SAI_OBJECT_TYPE_MACSEC_SA, m_vendorSai.get(), m_statsMode); } else if (context_name == ATTR_TYPE_ACL_COUNTER) { - return std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_ACL_COUNTER, m_vendorSai.get(), m_statsMode); + return std::make_shared>(context_name, SAI_OBJECT_TYPE_ACL_COUNTER, m_vendorSai.get(), m_statsMode); } else if (context_name == COUNTER_TYPE_POLICER) { - return std::make_shared>(context_name, instance, SAI_OBJECT_TYPE_POLICER, m_vendorSai.get(), m_statsMode); + return std::make_shared>(context_name, SAI_OBJECT_TYPE_POLICER, m_vendorSai.get(), m_statsMode); } else if (context_name == COUNTER_TYPE_SRV6) { @@ -3418,6 +3343,13 @@ std::shared_ptr FlexCounter::createCounterContext( return context; } + // Create OTN counter context here + auto otn_context = createOtnCounterContext(context_name, m_vendorSai, m_statsMode); + if (otn_context != nullptr) + { + return otn_context; + } + SWSS_LOG_THROW("Invalid counter type %s", context_name.c_str()); // GCC 8.3 requires a return value here return nullptr; @@ -3747,6 +3679,11 @@ void FlexCounter::removeCounter( } else { + if (m_flexCounterOtn->removeCounter(vid, objectType)) + { + return; + } + SWSS_LOG_ERROR("Object type for removal not supported, %s", sai_serialize_object_type(objectType).c_str()); } @@ -3793,6 +3730,11 @@ void FlexCounter::addCounter( } else { + if (m_flexCounterOtn->addCounter(vid, rid, objectType, field, idStrings)) + { + continue; + } + SWSS_LOG_ERROR("Object type and field combination is not supported, object type %s, field %s", sai_serialize_object_type(objectType).c_str(), field.c_str()); diff --git a/syncd/FlexCounter.h b/syncd/FlexCounter.h index 62e846e5c8..bb6fd72f1e 100644 --- a/syncd/FlexCounter.h +++ b/syncd/FlexCounter.h @@ -5,6 +5,7 @@ extern "C" { } #include "meta/SaiInterface.h" +#include "FlexCounterOtn.h" #include "swss/table.h" @@ -43,19 +44,13 @@ namespace syncd class BaseCounterContext { public: - BaseCounterContext(const std::string &name, const std::string &instance); + BaseCounterContext(const std::string &name); void addPlugins( _In_ const std::vector& shaStrings); void setNoDoubleCheckBulkCapability( _In_ bool); - virtual void setBulkChunkSize( - _In_ uint32_t bulkChunkSize); - - virtual void setBulkChunkSizePerPrefix( - _In_ const std::string& bulkChunkSizePerPrefix); - bool hasPlugin() const {return !m_plugins.empty();} void removePlugins() {m_plugins.clear();} @@ -86,9 +81,7 @@ namespace syncd protected: std::string m_name; - std::string m_instanceId; std::set m_plugins; - std::string m_bulkChunkSizePerPrefix; public: bool always_check_supported_counters = false; @@ -163,8 +156,7 @@ namespace syncd _In_ const std::string &name); std::shared_ptr createCounterContext( - _In_ const std::string &name, - _In_ const std::string &instance); + _In_ const std::string &name); void removeCounterContext( _In_ const std::string &name); diff --git a/syncd/FlexCounterOtn.cpp b/syncd/FlexCounterOtn.cpp new file mode 100644 index 0000000000..055f576012 --- /dev/null +++ b/syncd/FlexCounterOtn.cpp @@ -0,0 +1,158 @@ +#include "FlexCounterOtn.h" +#include "FlexCounter.h" + +using namespace syncd; +using namespace std; + + +const std::string FlexCounterOtn::COUNTER_TYPE_OTN_ATTENUATOR_ATTR = "OTN Attenuator Attributes Counter"; +const std::string FlexCounterOtn::COUNTER_TYPE_OTN_OA_ATTR = "OTN OA Attributes Counter"; +const std::string FlexCounterOtn::COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR = "OTN OCM Channel Attributes Counter"; +const std::string FlexCounterOtn::COUNTER_TYPE_OTN_OSC_ATTR = "OTN OSC Attributes Counter"; + + +FlexCounterOtn::FlexCounterOtn( + std::function(_In_ const std::string &name)> getCounterContext, + std::function hasCounterContext): +m_getCounterContext(getCounterContext), +m_hasCounterContext(hasCounterContext) +{ + SWSS_LOG_ENTER(); +} + +FlexCounterOtn::~FlexCounterOtn() +{ + SWSS_LOG_ENTER(); +} + +bool FlexCounterOtn::addCounter( + _In_ sai_object_id_t vid, + _In_ sai_object_id_t rid, + _In_ sai_object_type_t objectType, + _In_ const std::string &field, + _In_ const std::vector &idStrings) +{ + SWSS_LOG_ENTER(); + + sai_object_type_extensions_t extObjectType = (sai_object_type_extensions_t)objectType; + if (extObjectType == SAI_OBJECT_TYPE_OTN_ATTENUATOR && field == OTN_ATTENUATOR_ATTR_ID_LIST) + { + m_getCounterContext(COUNTER_TYPE_OTN_ATTENUATOR_ATTR)->addObject( + vid, + rid, + idStrings, + ""); + return true; + } + + if (extObjectType == SAI_OBJECT_TYPE_OTN_OA && field == OTN_OA_ATTR_ID_LIST) + { + m_getCounterContext(COUNTER_TYPE_OTN_OA_ATTR)->addObject( + vid, + rid, + idStrings, + ""); + return true; + } + + if (extObjectType == SAI_OBJECT_TYPE_OTN_OCM_CHANNEL && field == OTN_OCM_CHANNEL_ATTR_ID_LIST) + { + m_getCounterContext(COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR)->addObject( + vid, + rid, + idStrings, + ""); + return true; + } + + if (extObjectType == SAI_OBJECT_TYPE_OTN_OSC && field == OTN_OSC_ATTR_ID_LIST) + { + m_getCounterContext(COUNTER_TYPE_OTN_OSC_ATTR)->addObject( + vid, + rid, + idStrings, + ""); + return true; + } + + return false; +} + +bool FlexCounterOtn::removeCounter( + _In_ sai_object_id_t vid, + _In_ sai_object_type_t objectType) +{ + SWSS_LOG_ENTER(); + + sai_object_type_extensions_t extObjectType = (sai_object_type_extensions_t)objectType; + if (extObjectType == SAI_OBJECT_TYPE_OTN_ATTENUATOR) + { + if (m_hasCounterContext(COUNTER_TYPE_OTN_ATTENUATOR_ATTR)) + { + m_getCounterContext(COUNTER_TYPE_OTN_ATTENUATOR_ATTR)->removeObject(vid); + } + return true; + } + + if (extObjectType == SAI_OBJECT_TYPE_OTN_OA) + { + if (m_hasCounterContext(COUNTER_TYPE_OTN_OA_ATTR)) + { + m_getCounterContext(COUNTER_TYPE_OTN_OA_ATTR)->removeObject(vid); + } + return true; + } + + if (extObjectType == SAI_OBJECT_TYPE_OTN_OCM_CHANNEL) + { + if (m_hasCounterContext(COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR)) + { + m_getCounterContext(COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR)->removeObject(vid); + } + return true; + } + + if (extObjectType == SAI_OBJECT_TYPE_OTN_OSC) + { + if (m_hasCounterContext(COUNTER_TYPE_OTN_OSC_ATTR)) + { + m_getCounterContext(COUNTER_TYPE_OTN_OSC_ATTR)->removeObject(vid); + } + return true; + } + + return false; +} + +bool FlexCounterOtn::addCounterPlugin( + _In_ const std::string &field, + _In_ const std::vector &shaStrings) +{ + SWSS_LOG_ENTER(); + + if (field == OTN_ATTENUATOR_PLUGIN_FIELD) + { + m_getCounterContext(COUNTER_TYPE_OTN_ATTENUATOR_ATTR)->addPlugins(shaStrings); + return true; + } + + if (field == OTN_OA_PLUGIN_FIELD) + { + m_getCounterContext(COUNTER_TYPE_OTN_OA_ATTR)->addPlugins(shaStrings); + return true; + } + + if (field == OTN_OCM_CHANNEL_PLUGIN_FIELD) + { + m_getCounterContext(COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR)->addPlugins(shaStrings); + return true; + } + + if (field == OTN_OSC_PLUGIN_FIELD) + { + m_getCounterContext(COUNTER_TYPE_OTN_OSC_ATTR)->addPlugins(shaStrings); + return true; + } + + return false; +} diff --git a/syncd/FlexCounterOtn.h b/syncd/FlexCounterOtn.h new file mode 100644 index 0000000000..f21183c4ba --- /dev/null +++ b/syncd/FlexCounterOtn.h @@ -0,0 +1,119 @@ +#pragma once + +extern "C" { +#include "sai.h" +} + +#include "meta/SaiInterface.h" +#include "meta/sai_serialize_otn.h" + +#include +#include +#include + +namespace syncd +{ + class BaseCounterContext; + + class FlexCounterOtn + { + public: + FlexCounterOtn( + std::function(_In_ const std::string &name)> getCounterContext, + std::function hasCounterContext); + virtual ~FlexCounterOtn(); + + bool addCounter( + _In_ sai_object_id_t vid, + _In_ sai_object_id_t rid, + _In_ sai_object_type_t objectType, + _In_ const std::string &field, + _In_ const std::vector &idStrings); + + bool removeCounter( + _In_ sai_object_id_t vid, + _In_ sai_object_type_t objectType); + + bool addCounterPlugin( + _In_ const std::string &field, + _In_ const std::vector &shaStrings); + + public: + static const std::string COUNTER_TYPE_OTN_ATTENUATOR_ATTR; + static const std::string COUNTER_TYPE_OTN_OA_ATTR; + static const std::string COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR; + static const std::string COUNTER_TYPE_OTN_OSC_ATTR; + + private: + std::function(_In_ const std::string &name)> m_getCounterContext; + std::function m_hasCounterContext; + }; + + + #define FLEX_COUNTER_OTN_IMPLEMENT() \ + std::shared_ptr createOtnCounterContext( \ + _In_ const std::string &context_name, \ + _In_ std::shared_ptr vendorSai, \ + _In_ sai_stats_mode_t statsMode) \ + { \ + SWSS_LOG_ENTER(); \ + if (context_name == FlexCounterOtn::COUNTER_TYPE_OTN_ATTENUATOR_ATTR)\ + { \ + return std::make_shared>(context_name, (sai_object_type_t)SAI_OBJECT_TYPE_OTN_ATTENUATOR, vendorSai.get(), statsMode);\ + } \ + \ + if (context_name == FlexCounterOtn::COUNTER_TYPE_OTN_OA_ATTR)\ + { \ + return std::make_shared>(context_name, (sai_object_type_t)SAI_OBJECT_TYPE_OTN_OA, vendorSai.get(), statsMode);\ + } \ + \ + if (context_name == FlexCounterOtn::COUNTER_TYPE_OTN_OCM_CHANNEL_ATTR)\ + { \ + return std::make_shared>(context_name, (sai_object_type_t)SAI_OBJECT_TYPE_OTN_OCM_CHANNEL, vendorSai.get(), statsMode);\ + } \ + \ + if (context_name == FlexCounterOtn::COUNTER_TYPE_OTN_OSC_ATTR)\ + { \ + return std::make_shared>(context_name, (sai_object_type_t)SAI_OBJECT_TYPE_OTN_OSC, vendorSai.get(), statsMode);\ + } \ + \ + return nullptr; \ + } \ + \ + template <> \ + void deserializeAttr( \ + _In_ const std::string &name, \ + _Out_ sai_otn_attenuator_attr_t &attr) \ + { \ + SWSS_LOG_ENTER(); \ + sai_deserialize_otn_attenuator_attr(name, attr); \ + } \ + \ + template <> \ + void deserializeAttr( \ + _In_ const std::string &name, \ + _Out_ sai_otn_oa_attr_t &attr) \ + { \ + SWSS_LOG_ENTER(); \ + sai_deserialize_otn_oa_attr(name, attr); \ + } \ + \ + template <> \ + void deserializeAttr( \ + _In_ const std::string &name, \ + _Out_ sai_otn_ocm_channel_attr_t &attr) \ + { \ + SWSS_LOG_ENTER(); \ + sai_deserialize_otn_ocm_channel_attr(name, attr); \ + } \ + \ + template <> \ + void deserializeAttr( \ + _In_ const std::string &name, \ + _Out_ sai_otn_osc_attr_t &attr) \ + { \ + SWSS_LOG_ENTER(); \ + sai_deserialize_otn_osc_attr(name, attr); \ + } + +} diff --git a/syncd/Makefile.am b/syncd/Makefile.am index cf6af17ab1..358dcdc296 100644 --- a/syncd/Makefile.am +++ b/syncd/Makefile.am @@ -59,7 +59,8 @@ libSyncd_a_SOURCES = \ WatchdogScope.cpp \ Workaround.cpp \ ZeroMQNotificationProducer.cpp \ - syncd_main.cpp + syncd_main.cpp \ + FlexCounterOtn.cpp libSyncd_a_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) libSyncd_a_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) diff --git a/syncd/NotificationHandler.cpp b/syncd/NotificationHandler.cpp index 9918ecbd15..cb339c19eb 100644 --- a/syncd/NotificationHandler.cpp +++ b/syncd/NotificationHandler.cpp @@ -6,6 +6,7 @@ #include "swss/logger.h" #include "meta/sai_serialize.h" +#include "meta/sai_serialize_otn.h" #include @@ -329,6 +330,17 @@ void NotificationHandler::onMacsecPostStatus( enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_MACSEC_POST_STATUS, s); } +void NotificationHandler::onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + std::string s = sai_serialize_otn_alarm_event_ntf(count, data); + + enqueueNotification(SAI_SWITCH_NOTIFICATION_NAME_OTN_ALARM_EVENT, s); +} + void NotificationHandler::enqueueNotification( _In_ const std::string& op, _In_ const std::string& data) diff --git a/syncd/NotificationHandler.h b/syncd/NotificationHandler.h index 440b29cd72..99591f8475 100644 --- a/syncd/NotificationHandler.h +++ b/syncd/NotificationHandler.h @@ -116,6 +116,10 @@ namespace syncd _In_ sai_object_id_t macsec_id, _In_ sai_macsec_post_status_t macsec_post_status); + void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data); + private: void enqueueNotification( diff --git a/syncd/NotificationProcessor.cpp b/syncd/NotificationProcessor.cpp index 1bd5ce0b97..6dbd44d270 100644 --- a/syncd/NotificationProcessor.cpp +++ b/syncd/NotificationProcessor.cpp @@ -5,6 +5,7 @@ #include "sairediscommon.h" #include "meta/sai_serialize.h" +#include "meta/sai_serialize_otn.h" #include "meta/SaiAttributeList.h" #include "swss/logger.h" @@ -679,6 +680,26 @@ void NotificationProcessor::process_on_twamp_session_event( sendNotification(SAI_SWITCH_NOTIFICATION_NAME_TWAMP_SESSION_EVENT, s); } +void NotificationProcessor::process_on_otn_alarm_event( + _In_ uint32_t count, + _In_ sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_DEBUG("otn alarm event notification count: %u", count); + + for (uint32_t i = 0; i < count; i++) + { + sai_otn_alarm_event_data_t *otn_alarm_event = &data[i]; + + otn_alarm_event->object_id = m_translator->translateRidToVid(otn_alarm_event->object_id, SAI_NULL_OBJECT_ID); + } + + std::string s = sai_serialize_otn_alarm_event_ntf(count, data); + + sendNotification(SAI_SWITCH_NOTIFICATION_NAME_OTN_ALARM_EVENT, s); +} + void NotificationProcessor::handle_switch_state_change( _In_ const std::string &data) { @@ -990,6 +1011,21 @@ void NotificationProcessor::handle_macsec_post_status( sai_serialize_macsec_post_status(macsec_post_status)); } +void NotificationProcessor::handle_otn_alarm_event( + _In_ const std::string &data) +{ + SWSS_LOG_ENTER(); + + uint32_t count; + sai_otn_alarm_event_data_t *otn_alarm_event = NULL; + + sai_deserialize_otn_alarm_event_ntf(data, count, &otn_alarm_event); + + process_on_otn_alarm_event(count, otn_alarm_event); + + sai_deserialize_free_otn_alarm_event_ntf(count, otn_alarm_event); +} + void NotificationProcessor::processNotification( _In_ const swss::KeyOpFieldsValuesTuple& item) { @@ -1094,6 +1130,10 @@ void NotificationProcessor::syncProcessNotification( { handle_flow_bulk_get_session_event(data); } + else if (notification == SAI_SWITCH_NOTIFICATION_NAME_OTN_ALARM_EVENT) + { + handle_otn_alarm_event(data); + } else { SWSS_LOG_ERROR("unknown notification: %s", notification.c_str()); diff --git a/syncd/NotificationProcessor.h b/syncd/NotificationProcessor.h index 3ee4a941cf..435d8bbd38 100644 --- a/syncd/NotificationProcessor.h +++ b/syncd/NotificationProcessor.h @@ -125,6 +125,10 @@ namespace syncd _In_ uint32_t count, _In_ sai_twamp_session_event_notification_data_t *data); + void process_on_otn_alarm_event( + _In_ uint32_t count, + _In_ sai_otn_alarm_event_data_t *data); + private: // handlers void handle_switch_state_change( @@ -179,6 +183,9 @@ namespace syncd void handle_macsec_post_status( _In_ const std::string &data); + void handle_otn_alarm_event( + _In_ const std::string &data); + void processNotification( _In_ const swss::KeyOpFieldsValuesTuple& item); diff --git a/syncd/SwitchNotifications.cpp b/syncd/SwitchNotifications.cpp index 17e9050951..6d030ef118 100644 --- a/syncd/SwitchNotifications.cpp +++ b/syncd/SwitchNotifications.cpp @@ -231,6 +231,16 @@ void SwitchNotifications::SlotBase::onSwitchIpsecPostStatus( return m_slots.at(context)->m_handler->onSwitchIpsecPostStatus(switch_id, post_status); } +void SwitchNotifications::SlotBase::onOtnAlarmEvent( + _In_ int context, + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + return m_slots.at(context)->m_handler->onOtnAlarmEvent(count, data); +} + const sai_switch_notifications_t& SwitchNotifications::SlotBase::getSwitchNotifications() const { SWSS_LOG_ENTER(); diff --git a/syncd/SwitchNotifications.h b/syncd/SwitchNotifications.h index a63a723ce5..8b665b9370 100644 --- a/syncd/SwitchNotifications.h +++ b/syncd/SwitchNotifications.h @@ -134,6 +134,11 @@ namespace syncd _In_ int context, _In_ sai_object_id_t switch_id, _In_ sai_switch_ipsec_post_status_t post_status ); + + static void onOtnAlarmEvent( + _In_ int context, + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data); protected: SwitchNotifications* m_handler; @@ -172,6 +177,7 @@ namespace syncd .on_ha_set_event = &Slot::onHaSetEvent, .on_ha_scope_event = &Slot::onHaScopeEvent, .on_flow_bulk_get_session_event = &Slot::onFlowBulkGetSessionEvent, + .on_otn_alarm_event = &Slot::onOtnAlarmEvent, }) { } virtual ~Slot() {} @@ -355,6 +361,15 @@ namespace syncd return SlotBase::onSwitchIpsecPostStatus(context, switch_id, post_status); } + + static void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) + { + SWSS_LOG_ENTER(); + + return SlotBase::onOtnAlarmEvent(context, count, data); + } }; static std::vector m_slots; @@ -395,7 +410,9 @@ namespace syncd std::function onIpsecPostStatus; std::function onSwitchMacsecPostStatus; std::function onSwitchIpsecPostStatus; - private: + std::function onOtnAlarmEvent; + + private: SlotBase*m_slot; }; diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 1280dcbe77..cffc1e0bdb 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -185,6 +185,7 @@ Syncd::Syncd( m_sn.onHaSetEvent = std::bind(&NotificationHandler::onHaSetEvent, m_handler.get(), _1, _2); m_sn.onHaScopeEvent = std::bind(&NotificationHandler::onHaScopeEvent, m_handler.get(), _1, _2); m_sn.onFlowBulkGetSessionEvent = std::bind(&NotificationHandler::onFlowBulkGetSessionEvent, m_handler.get(), _1, _2, _3); + m_sn.onOtnAlarmEvent = std::bind(&NotificationHandler::onOtnAlarmEvent, m_handler.get(), _1, _2); m_handler->setSwitchNotifications(m_sn.getSwitchNotifications()); diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index 6ef4d0c9b6..89a7cb980b 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -36,7 +36,6 @@ ecmp ECMP FDB FDBs -FEC FIXME FlexCounter gbsyncd diff --git a/unittest/meta/Makefile.am b/unittest/meta/Makefile.am index 61f4989aa7..24d443dcb8 100644 --- a/unittest/meta/Makefile.am +++ b/unittest/meta/Makefile.am @@ -33,6 +33,7 @@ tests_SOURCES = \ TestNotificationTam.cpp \ TestNotificationMacsecPostStatus.cpp \ TestNotificationSwitchMacsecPostStatus.cpp \ + TestNotificationOtnAlarmEvent.cpp \ TestOidRefCounter.cpp \ TestPerformanceIntervalTimer.cpp \ TestPortRelatedSet.cpp \ diff --git a/unittest/meta/TestDummySaiInterface.cpp b/unittest/meta/TestDummySaiInterface.cpp index e5b98d9ac2..9d10480621 100644 --- a/unittest/meta/TestDummySaiInterface.cpp +++ b/unittest/meta/TestDummySaiInterface.cpp @@ -251,6 +251,17 @@ void onTamTelTypeConfigChange( ntfCounter++; } +static void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_NOTICE("received: onOtnAlarmEvent"); + + ntfCounter++; +} + TEST(DummySaiInterface, sendNotification) { DummySaiInterface sai; @@ -278,6 +289,7 @@ TEST(DummySaiInterface, sendNotification) EXPECT_EQ(sai.enqueueNotificationToSend(SAI_SWITCH_ATTR_SHUTDOWN_REQUEST_NOTIFY), SAI_STATUS_SUCCESS); EXPECT_EQ(sai.enqueueNotificationToSend(SAI_SWITCH_ATTR_TAM_TEL_TYPE_CONFIG_CHANGE_NOTIFY), SAI_STATUS_SUCCESS); + EXPECT_EQ(sai.enqueueNotificationToSend(SAI_SWITCH_ATTR_OTN_ALARM_EVENT_NOTIFY), SAI_STATUS_SUCCESS); sai_attribute_t attr; @@ -340,6 +352,10 @@ TEST(DummySaiInterface, sendNotification) attr.value.ptr = (void*)&onTamTelTypeConfigChange; sai.set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + attr.id = SAI_SWITCH_ATTR_OTN_ALARM_EVENT_NOTIFY; + attr.value.ptr = (void*)&onOtnAlarmEvent; + sai.set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + EXPECT_EQ(sai.start(), SAI_STATUS_SUCCESS); sleep(1); diff --git a/unittest/meta/TestNotificationOtnAlarmEvent.cpp b/unittest/meta/TestNotificationOtnAlarmEvent.cpp new file mode 100644 index 0000000000..7820a65b09 --- /dev/null +++ b/unittest/meta/TestNotificationOtnAlarmEvent.cpp @@ -0,0 +1,110 @@ +#include "MetaTestSaiInterface.h" +#include "NotificationOtnAlarmEvent.h" + +#include "sairediscommon.h" +#include "sai_serialize.h" + +#include + +#include + +using namespace sairedis; +using namespace saimeta; + +static std::string s = "[" + "{" + "\"timestamp\":\"{" + "\\\"tv_nsec\\\":\\\"28715881\\\"," + "\\\"tv_sec\\\":\\\"1700042919\\\"" + "}\"," + "\"object_id\":\"oid:0x123456789abcdef\"," + "\"event_name\": \"OTN OA LOS\"," + "\"severity\": \"SAI_OTN_ALARM_SEVERITY_CRITICAL\"," + "\"action\": \"SAI_OTN_ALARM_ACTION_RAISE\"," + "\"description\": \"OA input LOS, power -60dBm\"," + "\"data\": \"0\"" + "}" + "]"; + +static std::string null = "[" + "{" + "\"timestamp\":\"{" + "\\\"tv_nsec\\\":\\\"28715881\\\"," + "\\\"tv_sec\\\":\\\"1700042919\\\"" + "}\"," + "\"object_id\":\"oid:0x0\"," + "\"event_name\": \"OTN OA LOS\"," + "\"severity\": \"SAI_OTN_ALARM_SEVERITY_CRITICAL\"," + "\"action\": \"SAI_OTN_ALARM_ACTION_RAISE\"," + "\"description\": \"OA input LOS, power -60dBm\"," + "\"data\": \"0\"" + "}" + "]"; + +static std::string fullnull = "[]"; + +TEST(NotificationOtnAlarmEvent, otn_alarm) +{ + NotificationOtnAlarmEvent n(s); +} + +TEST(NotificationOtnAlarmEvent, getSwitchId) +{ + NotificationOtnAlarmEvent n(s); + + EXPECT_EQ(n.getSwitchId(), SAI_NULL_OBJECT_ID); + + NotificationOtnAlarmEvent n2(null); + + EXPECT_EQ(n2.getSwitchId(), SAI_NULL_OBJECT_ID); + + NotificationOtnAlarmEvent n3(fullnull); + + EXPECT_EQ(n3.getSwitchId(), SAI_NULL_OBJECT_ID); +} + +TEST(NotificationOtnAlarmEvent, getAnyObjectId) +{ + NotificationOtnAlarmEvent n(s); + + EXPECT_EQ(n.getAnyObjectId(), 0x123456789abcdef); + + NotificationOtnAlarmEvent n2(null); + + EXPECT_EQ(n2.getAnyObjectId(), SAI_NULL_OBJECT_ID); + + NotificationOtnAlarmEvent n3(fullnull); + + EXPECT_EQ(n3.getAnyObjectId(), SAI_NULL_OBJECT_ID); +} + +TEST(NotificationOtnAlarmEvent, processMetadata) +{ + NotificationOtnAlarmEvent n(s); + + auto sai = std::make_shared(); + auto meta = std::make_shared(sai); + + n.processMetadata(meta); +} + +static void on_otn_alarm_event( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_NOTICE("received: on_otn_alarm_event"); +} + +TEST(NotificationOtnAlarmEvent, executeCallback) +{ + NotificationOtnAlarmEvent n(s); + + sai_switch_notifications_t switchNotifications; + memset(&switchNotifications, 0, sizeof(switchNotifications)); + + switchNotifications.on_otn_alarm_event = &on_otn_alarm_event; + + n.executeCallback(switchNotifications); +} diff --git a/unittest/proxylib/TestProxy.cpp b/unittest/proxylib/TestProxy.cpp index bcb36012bb..eb65e78e02 100644 --- a/unittest/proxylib/TestProxy.cpp +++ b/unittest/proxylib/TestProxy.cpp @@ -229,6 +229,17 @@ static void onTamTelTypeConfigChange( ntfCounter++; } +static void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_NOTICE("received: onOtnAlarmEvent"); + + ntfCounter++; +} + TEST(Proxy, notifications) { Sai sai; @@ -251,6 +262,7 @@ TEST(Proxy, notifications) EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_ICMP_ECHO_SESSION_STATE_CHANGE_NOTIFY), SAI_STATUS_SUCCESS); EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_TWAMP_SESSION_EVENT_NOTIFY), SAI_STATUS_SUCCESS); EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_TAM_TEL_TYPE_CONFIG_CHANGE_NOTIFY), SAI_STATUS_SUCCESS); + EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_OTN_ALARM_EVENT_NOTIFY), SAI_STATUS_SUCCESS); auto thread = std::make_shared(fun,proxy); @@ -334,6 +346,10 @@ TEST(Proxy, notifications) attr.value.ptr = (void*)&onTamTelTypeConfigChange; sai.set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + attr.id = SAI_SWITCH_ATTR_OTN_ALARM_EVENT_NOTIFY; + attr.value.ptr = (void*)&onOtnAlarmEvent; + sai.set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + // dummy start sending notifications EXPECT_EQ(dummy->start(), SAI_STATUS_SUCCESS); @@ -342,7 +358,7 @@ TEST(Proxy, notifications) // dummy stop sending notifications EXPECT_EQ(dummy->stop(), SAI_STATUS_SUCCESS); - EXPECT_EQ(proxy->getNotificationsSentCount(), 4+7+1); + EXPECT_EQ(proxy->getNotificationsSentCount(), 4+7+1+1); proxy->stop(); diff --git a/unittest/proxylib/TestSai.cpp b/unittest/proxylib/TestSai.cpp index eb1647249e..8bf33c031d 100644 --- a/unittest/proxylib/TestSai.cpp +++ b/unittest/proxylib/TestSai.cpp @@ -759,6 +759,17 @@ static void onTamTelTypeConfigChange( ntfCounter++; } +static void onOtnAlarmEvent( + _In_ uint32_t count, + _In_ const sai_otn_alarm_event_data_t *data) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_NOTICE("received: onOtnAlarmEvent"); + + ntfCounter++; +} + TEST(Sai, handleNotification) { Sai sai; @@ -781,6 +792,7 @@ TEST(Sai, handleNotification) EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_ICMP_ECHO_SESSION_STATE_CHANGE_NOTIFY), SAI_STATUS_SUCCESS); EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_TWAMP_SESSION_EVENT_NOTIFY), SAI_STATUS_SUCCESS); EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_TAM_TEL_TYPE_CONFIG_CHANGE_NOTIFY), SAI_STATUS_SUCCESS); + EXPECT_EQ(dummy->enqueueNotificationToSend(SAI_SWITCH_ATTR_OTN_ALARM_EVENT_NOTIFY), SAI_STATUS_SUCCESS); auto thread = std::make_shared(fun, proxy); @@ -860,6 +872,10 @@ TEST(Sai, handleNotification) attr.value.ptr = (void*)&onTamTelTypeConfigChange; sai.set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + attr.id = SAI_SWITCH_ATTR_OTN_ALARM_EVENT_NOTIFY; + attr.value.ptr = (void*)&onOtnAlarmEvent; + sai.set(SAI_OBJECT_TYPE_SWITCH, switch_id, &attr); + // dummy start sending notifications EXPECT_EQ(dummy->start(), SAI_STATUS_SUCCESS); @@ -868,10 +884,10 @@ TEST(Sai, handleNotification) // dummy stop sending notifications EXPECT_EQ(dummy->stop(), SAI_STATUS_SUCCESS); - EXPECT_EQ(proxy->getNotificationsSentCount(), 12); + EXPECT_EQ(proxy->getNotificationsSentCount(), 13); // important check, whether Sai class processed notifications correctly - EXPECT_EQ(ntfCounter, 12); + EXPECT_EQ(ntfCounter, 13); proxy->stop(); diff --git a/unittest/syncd/TestFlexCounter.cpp b/unittest/syncd/TestFlexCounter.cpp index f68b15cf54..f9b43d8782 100644 --- a/unittest/syncd/TestFlexCounter.cpp +++ b/unittest/syncd/TestFlexCounter.cpp @@ -248,20 +248,6 @@ void testAddRemoveCounter( values.emplace_back(POLL_INTERVAL_FIELD, "1000"); values.emplace_back(FLEX_COUNTER_STATUS_FIELD, "enable"); values.emplace_back(STATS_MODE_FIELD, statsMode); - std::vector fcValues = values; - auto &bulkChunkSizeValues = bulkChunkSizeAfterPort ? fcValues : values; - if (!bulkChunkSize.empty()) - { - bulkChunkSizeValues.emplace_back(BULK_CHUNK_SIZE_FIELD, bulkChunkSize); - } - if (!bulkChunkSizePerCounter.empty()) - { - bulkChunkSizeValues.emplace_back(BULK_CHUNK_SIZE_PER_PREFIX_FIELD, bulkChunkSizePerCounter); - } - if (!pluginName.empty()) - { - values.emplace_back(pluginName, ""); - } fc.addCounterPlugin(values); values.clear(); @@ -2194,3 +2180,4 @@ TEST(FlexCounter, noEniDashMeterCounter) counterVerifyFunc, false); } +