vslib/Sai.cpp (686 lines of code) (raw):
#include "Sai.h"
#include "SaiInternal.h"
#include "RealObjectIdManager.h"
#include "VirtualSwitchSaiInterface.h"
#include "SwitchStateBase.h"
#include "LaneMapFileParser.h"
#include "HostInterfaceInfo.h"
#include "SwitchConfigContainer.h"
#include "ResourceLimiterParser.h"
#include "CorePortIndexMapFileParser.h"
#include "ContextConfigContainer.h"
#include "swss/logger.h"
#include "swss/notificationconsumer.h"
#include "swss/select.h"
#include "saivs.h"
#include <unistd.h>
#include <inttypes.h>
#include <algorithm>
#include <cstring>
using namespace saivs;
#define VS_CHECK_API_INITIALIZED() \
if (!m_apiInitialized) { \
SWSS_LOG_ERROR("%s: api not initialized", __PRETTY_FUNCTION__); \
return SAI_STATUS_FAILURE; }
Sai::Sai()
{
SWSS_LOG_ENTER();
m_unittestChannelRun = false;
m_fdbAgingThreadRun = false;
m_eventQueueThreadRun = false;
m_apiInitialized = false;
m_globalContext = 0;
}
Sai::~Sai()
{
SWSS_LOG_ENTER();
if (m_apiInitialized)
{
apiUninitialize();
}
}
// INITIALIZE UNINITIALIZE
sai_status_t Sai::apiInitialize(
_In_ uint64_t flags,
_In_ const sai_service_method_table_t *service_method_table)
{
MUTEX();
SWSS_LOG_ENTER();
if (m_apiInitialized)
{
SWSS_LOG_ERROR("%s: api already initialized", __PRETTY_FUNCTION__);
return SAI_STATUS_FAILURE;
}
if (flags != 0)
{
SWSS_LOG_ERROR("invalid flags passed to SAI API initialize");
return SAI_STATUS_INVALID_PARAMETER;
}
if ((service_method_table == NULL) ||
(service_method_table->profile_get_next_value == NULL) ||
(service_method_table->profile_get_value == NULL))
{
SWSS_LOG_ERROR("invalid service_method_table handle passed to SAI API initialize");
return SAI_STATUS_INVALID_PARAMETER;
}
memcpy(&m_service_method_table, service_method_table, sizeof(m_service_method_table));
auto switch_type = service_method_table->profile_get_value(0, SAI_KEY_VS_SWITCH_TYPE);
if (switch_type == NULL)
{
SWSS_LOG_ERROR("failed to obtain service method table value: %s", SAI_KEY_VS_SWITCH_TYPE);
return SAI_STATUS_FAILURE;
}
auto sai_switch_type = service_method_table->profile_get_value(0, SAI_KEY_VS_SAI_SWITCH_TYPE);
sai_switch_type_t saiSwitchType;
if (sai_switch_type == NULL)
{
SWSS_LOG_NOTICE("failed to obtain service method table value: %s", SAI_KEY_VS_SAI_SWITCH_TYPE);
saiSwitchType = SAI_SWITCH_TYPE_NPU;
}
else if (!SwitchConfig::parseSaiSwitchType(sai_switch_type, saiSwitchType))
{
return SAI_STATUS_FAILURE;
}
auto *laneMapFile = service_method_table->profile_get_value(0, SAI_KEY_VS_INTERFACE_LANE_MAP_FILE);
m_laneMapContainer = LaneMapFileParser::parseLaneMapFile(laneMapFile);
auto *fabricLaneMapFile = service_method_table->profile_get_value(0, SAI_KEY_VS_INTERFACE_FABRIC_LANE_MAP_FILE);
if (fabricLaneMapFile)
{
m_fabricLaneMapContainer = LaneMapFileParser::parseLaneMapFile(fabricLaneMapFile);
}
auto *corePortIndexMapFile = service_method_table->profile_get_value(0, SAI_KEY_VS_CORE_PORT_INDEX_MAP_FILE);
m_corePortIndexMapContainer = CorePortIndexMapFileParser::parseCorePortIndexMapFile(corePortIndexMapFile);
auto *resourceLimiterFile = service_method_table->profile_get_value(0, SAI_KEY_VS_RESOURCE_LIMITER_FILE);
m_resourceLimiterContainer = ResourceLimiterParser::parseFromFile(resourceLimiterFile);
auto boot_type = service_method_table->profile_get_value(0, SAI_KEY_BOOT_TYPE);
m_warm_boot_read_file = service_method_table->profile_get_value(0, SAI_KEY_WARM_BOOT_READ_FILE);
m_warm_boot_write_file = service_method_table->profile_get_value(0, SAI_KEY_WARM_BOOT_WRITE_FILE);
sai_vs_boot_type_t bootType;
if (!SwitchConfig::parseBootType(boot_type, bootType))
{
return SAI_STATUS_FAILURE;
}
sai_vs_switch_type_t switchType;
if (!SwitchConfig::parseSwitchType(switch_type, switchType))
{
return SAI_STATUS_FAILURE;
}
const char *use_tap_dev = service_method_table->profile_get_value(0, SAI_KEY_VS_HOSTIF_USE_TAP_DEVICE);
auto useTapDevice = SwitchConfig::parseBool(use_tap_dev);
SWSS_LOG_NOTICE("hostif use TAP device: %s", (useTapDevice ? "true" : "false"));
const char *use_configured_speed_as_oper_speed = service_method_table->profile_get_value(0, SAI_KEY_VS_USE_CONFIGURED_SPEED_AS_OPER_SPEED);
auto useConfiguredSpeedAsOperSpeed = SwitchConfig::parseBool(use_configured_speed_as_oper_speed);
SWSS_LOG_NOTICE("use configured speed as oper speed: %s", (useConfiguredSpeedAsOperSpeed ? "true" : "false"));
auto cstrGlobalContext = service_method_table->profile_get_value(0, SAI_KEY_VS_GLOBAL_CONTEXT);
m_globalContext = 0;
if (cstrGlobalContext != nullptr)
{
if (sscanf(cstrGlobalContext, "%u", &m_globalContext) != 1)
{
SWSS_LOG_WARN("failed to parse '%s' as uint32 using default globalContext", cstrGlobalContext);
m_globalContext = 0;
}
}
SWSS_LOG_NOTICE("using globalContext = %u", m_globalContext);
auto cstrContextConfig = service_method_table->profile_get_value(0, SAI_KEY_VS_CONTEXT_CONFIG);
auto ccc = ContextConfigContainer::loadFromFile(cstrContextConfig);
for (auto& cc: ccc->getAllContextConfigs())
{
auto context = std::make_shared<Context>(cc);
m_contextMap[cc->m_guid] = context;
}
auto context = getContext(m_globalContext);
if (context == nullptr)
{
SWSS_LOG_ERROR("no context defined for global context %u", m_globalContext);
return SAI_STATUS_FAILURE;
}
auto contextConfig = context->getContextConfig();
auto scc = contextConfig->m_scc;
if (scc->getSwitchConfigs().size() == 0)
{
SWSS_LOG_WARN("no switch configs defined, using default switch config");
auto sc = std::make_shared<SwitchConfig>(0, "");
scc->insert(sc);
}
// TODO currently switch configuration will share signal and event queue
// but it should be moved to Context class
m_signal = std::make_shared<Signal>();
m_eventQueue = std::make_shared<EventQueue>(m_signal);
for (auto& sc: scc->getSwitchConfigs())
{
// NOTE: switch index and hardware info is already populated
sc->m_saiSwitchType = saiSwitchType;
sc->m_switchType = switchType;
sc->m_bootType = bootType;
sc->m_useTapDevice = useTapDevice;
sc->m_useConfiguredSpeedAsOperSpeed = useConfiguredSpeedAsOperSpeed;
sc->m_laneMap = m_laneMapContainer->getLaneMap(sc->m_switchIndex);
if (sc->m_laneMap == nullptr)
{
SWSS_LOG_WARN("lane map for switch index %u is empty, loading default map (may have ifname conflict)", sc->m_switchIndex);
sc->m_laneMap = LaneMap::getDefaultLaneMap(sc->m_switchIndex);
}
if (m_fabricLaneMapContainer)
{
sc->m_fabricLaneMap = m_fabricLaneMapContainer->getLaneMap(sc->m_switchIndex);
}
sc->m_eventQueue = m_eventQueue;
sc->m_resourceLimiter = m_resourceLimiterContainer->getResourceLimiter(sc->m_switchIndex);
sc->m_corePortIndexMap = m_corePortIndexMapContainer->getCorePortIndexMap(sc->m_switchIndex);
}
// most important
// TODO move to Context class
m_vsSai = std::make_shared<VirtualSwitchSaiInterface>(contextConfig);
m_meta = std::make_shared<saimeta::Meta>(m_vsSai);
m_vsSai->setMeta(m_meta);
if (bootType == SAI_VS_BOOT_TYPE_WARM)
{
if (!m_vsSai->readWarmBootFile(m_warm_boot_read_file))
{
SWSS_LOG_WARN("failed to read warm boot read file, switching to COLD BOOT");
for (auto& sc: scc->getSwitchConfigs())
{
sc->m_bootType = SAI_VS_BOOT_TYPE_COLD;
}
}
}
startEventQueueThread();
startUnittestThread();
if (saiSwitchType == SAI_SWITCH_TYPE_NPU)
{
startFdbAgingThread();
}
m_apiInitialized = true;
return SAI_STATUS_SUCCESS;
}
sai_status_t Sai::apiUninitialize(void)
{
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
SWSS_LOG_NOTICE("begin");
// no mutex on uninitialized to prevent deadlock
// if some thread would try to gram api mutex
// so threads must be stopped first
SWSS_LOG_NOTICE("stopping threads");
stopUnittestThread();
stopFdbAgingThread();
stopEventQueueThread();
// at this point packets may still arrive on hostif but event queue thread
// ended so they will not be processed
// NOTE: at this point we can have MUTEX();
// clear state after ending all threads
m_vsSai->writeWarmBootFile(m_warm_boot_write_file);
m_vsSai = nullptr;
m_meta = nullptr;
m_apiInitialized = false;
SWSS_LOG_NOTICE("end");
return SAI_STATUS_SUCCESS;
}
// QUAD OID
sai_status_t Sai::create(
_In_ sai_object_type_t objectType,
_Out_ sai_object_id_t* objectId,
_In_ sai_object_id_t switchId,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->create(
objectType,
objectId,
switchId,
attr_count,
attr_list);
}
sai_status_t Sai::remove(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->remove(objectType, objectId);
}
sai_status_t Sai::set(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
if (objectType == SAI_OBJECT_TYPE_SWITCH)
{
if (attr)
{
if (attr->id == SAI_VS_SWITCH_ATTR_META_ENABLE_UNITTESTS)
{
m_meta->meta_unittests_enable(attr->value.booldata);
return SAI_STATUS_SUCCESS;
}
if (attr->id == SAI_VS_SWITCH_ATTR_META_ALLOW_READ_ONLY_ONCE)
{
return m_meta->meta_unittests_allow_readonly_set_once(SAI_OBJECT_TYPE_SWITCH, attr->value.s32);
}
}
}
return m_meta->set(objectType, objectId, attr);
}
sai_status_t Sai::get(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ uint32_t attr_count,
_Inout_ sai_attribute_t *attr_list)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->get(
objectType,
objectId,
attr_count,
attr_list);
}
// QUAD ENTRY
#define DECLARE_CREATE_ENTRY(OT,ot) \
sai_status_t Sai::create( \
_In_ const sai_ ## ot ## _t* entry, \
_In_ uint32_t attr_count, \
_In_ const sai_attribute_t *attr_list) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->create(entry, attr_count, attr_list); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_CREATE_ENTRY);
#define DECLARE_REMOVE_ENTRY(OT,ot) \
sai_status_t Sai::remove( \
_In_ const sai_ ## ot ## _t* entry) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->remove(entry); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_REMOVE_ENTRY);
#define DECLARE_SET_ENTRY(OT,ot) \
sai_status_t Sai::set( \
_In_ const sai_ ## ot ## _t* entry, \
_In_ const sai_attribute_t *attr) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->set(entry, attr); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_SET_ENTRY);
#define DECLARE_GET_ENTRY(OT,ot) \
sai_status_t Sai::get( \
_In_ const sai_ ## ot ## _t* entry, \
_In_ uint32_t attr_count, \
_Inout_ sai_attribute_t *attr_list) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->get(entry, attr_count, attr_list); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_GET_ENTRY);
// STATS
sai_status_t Sai::getStats(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_Out_ uint64_t *counters)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->getStats(
object_type,
object_id,
number_of_counters,
counter_ids,
counters);
}
sai_status_t Sai::queryStatsCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_Inout_ sai_stat_capability_list_t *stats_capability)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->queryStatsCapability(
switchId,
objectType,
stats_capability);
}
sai_status_t Sai::queryStatsStCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_Inout_ sai_stat_st_capability_list_t *stats_capability)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->queryStatsStCapability(
switchId,
objectType,
stats_capability);
}
sai_status_t Sai::getStatsExt(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_In_ sai_stats_mode_t mode,
_Out_ uint64_t *counters)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->getStatsExt(
object_type,
object_id,
number_of_counters,
counter_ids,
mode,
counters);
}
sai_status_t Sai::clearStats(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t object_id,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->clearStats(
object_type,
object_id,
number_of_counters,
counter_ids);
}
sai_status_t Sai::bulkGetStats(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_key_t *object_key,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_In_ sai_stats_mode_t mode,
_Inout_ sai_status_t *object_statuses,
_Out_ uint64_t *counters)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return SAI_STATUS_NOT_IMPLEMENTED;
}
sai_status_t Sai::bulkClearStats(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_key_t *object_key,
_In_ uint32_t number_of_counters,
_In_ const sai_stat_id_t *counter_ids,
_In_ sai_stats_mode_t mode,
_Inout_ sai_status_t *object_statuses)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return SAI_STATUS_NOT_IMPLEMENTED;
}
// BULK QUAD OID
sai_status_t Sai::bulkCreate(
_In_ sai_object_type_t object_type,
_In_ sai_object_id_t switch_id,
_In_ uint32_t object_count,
_In_ const uint32_t *attr_count,
_In_ const sai_attribute_t **attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_object_id_t *object_id,
_Out_ sai_status_t *object_statuses)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->bulkCreate(
object_type,
switch_id,
object_count,
attr_count,
attr_list,
mode,
object_id,
object_statuses);
}
sai_status_t Sai::bulkRemove(
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_id_t *object_id,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->bulkRemove(
object_type,
object_count,
object_id,
mode,
object_statuses);
}
sai_status_t Sai::bulkSet(
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_id_t *object_id,
_In_ const sai_attribute_t *attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->bulkSet(
object_type,
object_count,
object_id,
attr_list,
mode,
object_statuses);
}
sai_status_t Sai::bulkGet(
_In_ sai_object_type_t object_type,
_In_ uint32_t object_count,
_In_ const sai_object_id_t *object_id,
_In_ const uint32_t *attr_count,
_Inout_ sai_attribute_t **attr_list,
_In_ sai_bulk_op_error_mode_t mode,
_Out_ sai_status_t *object_statuses)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->bulkGet(
object_type,
object_count,
object_id,
attr_count,
attr_list,
mode,
object_statuses);
}
// BULK QUAD ENTRY
#define DECLARE_BULK_CREATE_ENTRY(OT,ot) \
sai_status_t Sai::bulkCreate( \
_In_ uint32_t object_count, \
_In_ const sai_ ## ot ## _t* entries, \
_In_ const uint32_t *attr_count, \
_In_ const sai_attribute_t **attr_list, \
_In_ sai_bulk_op_error_mode_t mode, \
_Out_ sai_status_t *object_statuses) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->bulkCreate( \
object_count, \
entries, \
attr_count, \
attr_list, \
mode, \
object_statuses); \
}
SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_CREATE_ENTRY);
// BULK REMOVE
#define DECLARE_BULK_REMOVE_ENTRY(OT,ot) \
sai_status_t Sai::bulkRemove( \
_In_ uint32_t object_count, \
_In_ const sai_ ## ot ## _t *entries, \
_In_ sai_bulk_op_error_mode_t mode, \
_Out_ sai_status_t *object_statuses) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->bulkRemove( \
object_count, \
entries, \
mode, \
object_statuses); \
}
SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_REMOVE_ENTRY);
// BULK SET
#define DECLARE_BULK_SET_ENTRY(OT,ot) \
sai_status_t Sai::bulkSet( \
_In_ uint32_t object_count, \
_In_ const sai_ ## ot ## _t *entries, \
_In_ const sai_attribute_t *attr_list, \
_In_ sai_bulk_op_error_mode_t mode, \
_Out_ sai_status_t *object_statuses) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
VS_CHECK_API_INITIALIZED(); \
return m_meta->bulkSet( \
object_count, \
entries, \
attr_list, \
mode, \
object_statuses); \
}
SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_SET_ENTRY);
// BULK GET
#define DECLARE_BULK_GET_ENTRY(OT,ot) \
sai_status_t Sai::bulkGet( \
_In_ uint32_t object_count, \
_In_ const sai_ ## ot ## _t *ot, \
_In_ const uint32_t *attr_count, \
_Inout_ sai_attribute_t **attr_list, \
_In_ sai_bulk_op_error_mode_t mode, \
_Out_ sai_status_t *object_statuses) \
{ \
SWSS_LOG_ENTER(); \
MUTEX(); \
VS_CHECK_API_INITIALIZED(); \
SWSS_LOG_ERROR("FIXME not implemented"); \
return SAI_STATUS_NOT_IMPLEMENTED; \
}
SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_GET_ENTRY);
// NON QUAD API
sai_status_t Sai::flushFdbEntries(
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->flushFdbEntries(
switch_id,
attr_count,
attr_list);
}
// SAI API
sai_status_t Sai::objectTypeGetAvailability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_In_ uint32_t attrCount,
_In_ const sai_attribute_t *attrList,
_Out_ uint64_t *count)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->objectTypeGetAvailability(
switchId,
objectType,
attrCount,
attrList,
count);
}
sai_status_t Sai::queryAttributeCapability(
_In_ sai_object_id_t switchId,
_In_ sai_object_type_t objectType,
_In_ sai_attr_id_t attrId,
_Out_ sai_attr_capability_t *capability)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->queryAttributeCapability(
switchId,
objectType,
attrId,
capability);
}
sai_status_t Sai::queryAttributeEnumValuesCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ sai_attr_id_t attr_id,
_Inout_ sai_s32_list_t *enum_values_capability)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->queryAttributeEnumValuesCapability(
switch_id,
object_type,
attr_id,
enum_values_capability);
}
sai_object_type_t Sai::objectTypeQuery(
_In_ sai_object_id_t objectId)
{
SWSS_LOG_ENTER();
if (!m_apiInitialized)
{
SWSS_LOG_ERROR("%s: SAI API not initialized", __PRETTY_FUNCTION__);
return SAI_OBJECT_TYPE_NULL;
}
// not need for metadata check or mutex since this method is static
return RealObjectIdManager::objectTypeQuery(objectId);
}
sai_object_id_t Sai::switchIdQuery(
_In_ sai_object_id_t objectId)
{
SWSS_LOG_ENTER();
if (!m_apiInitialized)
{
SWSS_LOG_ERROR("%s: SAI API not initialized", __PRETTY_FUNCTION__);
return SAI_NULL_OBJECT_ID;
}
// not need for metadata check or mutex since this method is static
return RealObjectIdManager::switchIdQuery(objectId);
}
sai_status_t Sai::logSet(
_In_ sai_api_t api,
_In_ sai_log_level_t log_level)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->logSet(api, log_level);
}
sai_status_t Sai::queryApiVersion(
_Out_ sai_api_version_t *version)
{
MUTEX();
SWSS_LOG_ENTER();
VS_CHECK_API_INITIALIZED();
return m_meta->queryApiVersion(version);
}
std::shared_ptr<Context> Sai::getContext(
_In_ uint32_t globalContext) const
{
SWSS_LOG_ENTER();
auto it = m_contextMap.find(globalContext);
if (it == m_contextMap.end())
return nullptr;
return it->second;
}