lib/ClientServerSai.cpp (547 lines of code) (raw):
#include "ClientServerSai.h"
#include "ClientSai.h"
#include "ServerSai.h"
#include "SaiInternal.h"
#include "Sai.h"
#include "swss/logger.h"
#include "meta/sai_serialize.h"
using namespace sairedis;
using namespace std::placeholders;
#define REDIS_CHECK_API_INITIALIZED() \
if (!m_apiInitialized) { \
SWSS_LOG_ERROR("%s: api not initialized", __PRETTY_FUNCTION__); \
return SAI_STATUS_FAILURE; }
ClientServerSai::ClientServerSai()
{
SWSS_LOG_ENTER();
m_apiInitialized = false;
}
ClientServerSai::~ClientServerSai()
{
SWSS_LOG_ENTER();
if (m_apiInitialized)
{
apiUninitialize();
}
}
// INITIALIZE UNINITIALIZE
sai_status_t ClientServerSai::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));
const char* enableClient = service_method_table->profile_get_value(0, SAI_REDIS_KEY_ENABLE_CLIENT);
if (enableClient && strcmp(enableClient, "true") == 0)
{
SWSS_LOG_NOTICE("acting as a sairedis CLIENT");
m_sai = std::make_shared<ClientSai>();
}
else
{
SWSS_LOG_NOTICE("acting as a sairedis SERVER");
m_sai = std::make_shared<ServerSai>();
}
auto status = m_sai->apiInitialize(flags, service_method_table);
SWSS_LOG_NOTICE("init client/server sai: %s", sai_serialize_status(status).c_str());
if (status == SAI_STATUS_SUCCESS)
{
m_apiInitialized = true;
}
return status;
}
sai_status_t ClientServerSai::apiUninitialize(void)
{
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
SWSS_LOG_NOTICE("begin");
m_apiInitialized = false;
m_sai = nullptr;
SWSS_LOG_NOTICE("end");
return SAI_STATUS_SUCCESS;
}
// QUAD OID
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->create(
objectType,
objectId,
switchId,
attr_count,
attr_list);
}
sai_status_t ClientServerSai::remove(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
return m_sai->remove(objectType, objectId);
}
sai_status_t ClientServerSai::set(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
return m_sai->set(objectType, objectId, attr);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->get(
objectType,
objectId,
attr_count,
attr_list);
}
// QUAD ENTRY
#define DECLARE_CREATE_ENTRY(OT,ot) \
sai_status_t ClientServerSai::create( \
_In_ const sai_ ## ot ## _t* entry, \
_In_ uint32_t attr_count, \
_In_ const sai_attribute_t *attr_list) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->create(entry, attr_count, attr_list); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_CREATE_ENTRY);
#define DECLARE_REMOVE_ENTRY(OT,ot) \
sai_status_t ClientServerSai::remove( \
_In_ const sai_ ## ot ## _t* entry) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->remove(entry); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_REMOVE_ENTRY);
#define DECLARE_SET_ENTRY(OT,ot) \
sai_status_t ClientServerSai::set( \
_In_ const sai_ ## ot ## _t* entry, \
_In_ const sai_attribute_t *attr) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->set(entry, attr); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_SET_ENTRY);
#define DECLARE_GET_ENTRY(OT,ot) \
sai_status_t ClientServerSai::get( \
_In_ const sai_ ## ot ## _t* entry, \
_In_ uint32_t attr_count, \
_Inout_ sai_attribute_t *attr_list) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->get(entry, attr_count, attr_list); \
}
SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_GET_ENTRY);
// STATS
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->getStats(
object_type,
object_id,
number_of_counters,
counter_ids,
counters);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->queryStatsCapability(
switchId,
objectType,
stats_capability);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->queryStatsStCapability(
switchId,
objectType,
stats_capability);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->getStatsExt(
object_type,
object_id,
number_of_counters,
counter_ids,
mode,
counters);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->clearStats(
object_type,
object_id,
number_of_counters,
counter_ids);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->bulkGetStats(switchId,
object_type,
object_count,
object_key,
number_of_counters,
counter_ids,
mode,
object_statuses,
counters);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->bulkClearStats(switchId,
object_type,
object_count,
object_key,
number_of_counters,
counter_ids,
mode,
object_statuses);
}
// BULK QUAD OID
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->bulkCreate(
object_type,
switch_id,
object_count,
attr_count,
attr_list,
mode,
object_id,
object_statuses);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->bulkRemove(
object_type,
object_count,
object_id,
mode,
object_statuses);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->bulkSet(
object_type,
object_count,
object_id,
attr_list,
mode,
object_statuses);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->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 ClientServerSai::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(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->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 ClientServerSai::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(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->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 ClientServerSai::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(); \
REDIS_CHECK_API_INITIALIZED(); \
return m_sai->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 ClientServerSai::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) \
{ \
MUTEX(); \
SWSS_LOG_ENTER(); \
REDIS_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 ClientServerSai::flushFdbEntries(
_In_ sai_object_id_t switch_id,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
return m_sai->flushFdbEntries(switch_id, attr_count, attr_list);
}
// SAI API
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->objectTypeGetAvailability(
switchId,
objectType,
attrCount,
attrList,
count);
}
sai_status_t ClientServerSai::queryAttributeCapability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_In_ sai_attr_id_t attr_id,
_Out_ sai_attr_capability_t *capability)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
return m_sai->queryAttributeCapability(
switch_id,
object_type,
attr_id,
capability);
}
sai_status_t ClientServerSai::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();
REDIS_CHECK_API_INITIALIZED();
return m_sai->queryAttributeEnumValuesCapability(
switch_id,
object_type,
attr_id,
enum_values_capability);
}
sai_object_type_t ClientServerSai::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;
}
return m_sai->objectTypeQuery(objectId);
}
sai_object_id_t ClientServerSai::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;
}
return m_sai->switchIdQuery(objectId);
}
sai_status_t ClientServerSai::logSet(
_In_ sai_api_t api,
_In_ sai_log_level_t log_level)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
return m_sai->logSet(api, log_level);
}
sai_status_t ClientServerSai::queryApiVersion(
_Out_ sai_api_version_t *version)
{
MUTEX();
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();
return m_sai->queryApiVersion(version);
}