Skip to content

Commit

Permalink
Add asic compile/switch skeleton in redis/syncd (#9)
Browse files Browse the repository at this point in the history
* Prevent copy and assignment for SaiAttributeList

* Make sairedis threadsafe

* Add asic compile/switch skeleton in redis/syncd

* Add SaiAttribute class

* Fix producer and consumer calls

* Add more serialization types
  • Loading branch information
kcudnik committed Apr 25, 2016
1 parent 0aaefff commit 2ddebf6
Show file tree
Hide file tree
Showing 13 changed files with 356 additions and 25 deletions.
75 changes: 75 additions & 0 deletions common/saiattribute.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "saiattribute.h"

#include "swss/logger.h"
#include "saiserialize.h"

#include "string.h"
extern "C" {
#include "sai.h"
}

SaiAttribute::SaiAttribute(
_In_ const sai_object_type_t objectType,
_In_ const swss::FieldValueTuple &value,
_In_ bool onlyCount) :
m_onlyCount(onlyCount),
m_objectType(objectType)
{
// TODO save those to make possible for copy constructor and assignment
const std::string &strAttrId = fvField(value);
const std::string &strAttrValue = fvValue(value);

if (strAttrId == "NULL")
{
SWSS_LOG_ERROR("NULL attribute passed");

exit(EXIT_FAILURE);
}

memset(&m_attr, 0, sizeof(sai_attribute_t));

int index = 0;
sai_deserialize_primitive(strAttrId, index, m_attr.id);

sai_status_t status = sai_get_serialization_type(m_objectType, m_attr.id, m_serializationType);

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("failed to get serialization type for object type %lx, attribute id: %lx",
m_objectType,
m_attr.id);

exit(EXIT_FAILURE);
}

index = 0;
status = sai_deserialize_attr_value(strAttrValue, index, m_serializationType, m_attr, m_onlyCount);

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("failed to deserialize attribute value: %s, serialization type: %d",
strAttrValue.c_str(),
m_serializationType);

exit(EXIT_FAILURE);
}
}

SaiAttribute::~SaiAttribute()
{
sai_status_t status = sai_deserialize_free_attribute_value(m_serializationType, m_attr);

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("failed to deserialize free");

exit(EXIT_FAILURE);
}
}

sai_attribute_t* SaiAttribute::getAttr()
{
// reference to member, we may need to
// replace VID to RID or vice versa
return &m_attr;
}
42 changes: 42 additions & 0 deletions common/saiattribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef __SAI_ATTRIBUTE__
#define __SAI_ATTRIBUTE__

#include <string>
#include <vector>

#include <hiredis/hiredis.h>
#include "swss/dbconnector.h"
#include "swss/table.h"
#include "swss/logger.h"
#include "sai.h"
#include "saiserialize.h"
#include "string.h"

class SaiAttribute
{
public:

SaiAttribute(
_In_ const sai_object_type_t objectType,
_In_ const swss::FieldValueTuple &value,
_In_ bool onlyCount);

~SaiAttribute();

sai_attribute_t* getAttr();

private:

SaiAttribute(const SaiAttribute&);
SaiAttribute& operator=(const SaiAttribute&);

bool m_onlyCount;

sai_object_type_t m_objectType;
sai_attribute_t m_attr;

sai_attr_serialization_type_t m_serializationType;
};

#endif // __SAI_ATTRIBUTE__

3 changes: 3 additions & 0 deletions common/saiattributelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class SaiAttributeList

private:

SaiAttributeList(const SaiAttributeList&);
SaiAttributeList& operator=(const SaiAttributeList&);

std::vector<sai_attribute_t> m_attr_list;
std::vector<sai_attr_serialization_type_t> m_serialization_type_list;
};
Expand Down
4 changes: 3 additions & 1 deletion common/saiserialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ sai_serialization_map_t sai_get_serialization_map()
map[SAI_OBJECT_TYPE_VLAN_MEMBER][SAI_VLAN_MEMBER_ATTR_PORT_ID] = SAI_SERIALIZATION_TYPE_OBJECT_ID;

map[SAI_OBJECT_TYPE_TRAP][SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION] = SAI_SERIALIZATION_TYPE_INT32;
map[SAI_OBJECT_TYPE_TRAP][SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL] = SAI_SERIALIZATION_TYPE_INT32;
map[SAI_OBJECT_TYPE_TRAP][SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY] = SAI_SERIALIZATION_TYPE_UINT32;

return map;
}
Expand Down Expand Up @@ -146,7 +148,7 @@ sai_status_t sai_get_serialization_type(

if (mit == map.end())
{
SWSS_LOG_ERROR("serialization attribute id not found %u", attr_id);
SWSS_LOG_ERROR("serialization attribute id not found %u for object type : %u", attr_id, object_type);

return SAI_STATUS_NOT_IMPLEMENTED;
}
Expand Down
6 changes: 6 additions & 0 deletions lib/inc/sai_redis.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef __SAI_REDIS__
#define __SAI_REDIS__

#include <mutex>

#include "stdint.h"
#include "stdio.h"

Expand All @@ -23,15 +25,19 @@ extern service_method_table_t g_services;
extern swss::DBConnector *g_db;
extern swss::ProducerTable *g_asicState;

extern swss::ProducerTable *g_notifySyncdProducer;
extern swss::ProducerTable *g_redisGetProducer;
extern swss::ConsumerTable *g_redisGetConsumer;
extern swss::ConsumerTable *g_redisNotifications;
extern swss::ConsumerTable *g_notifySyncdConsumer;

extern swss::Table *g_vidToRid;
extern swss::Table *g_ridToVid;

extern swss::RedisClient *g_redisClient;

extern std::mutex g_mutex;

extern const sai_acl_api_t redis_acl_api;
extern const sai_buffer_api_t redis_buffer_api;
extern const sai_fdb_api_t redis_fdb_api;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/sai_redis_generic_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ sai_status_t internal_redis_generic_create(
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *attr_list)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

std::vector<swss::FieldValueTuple> entry = SaiAttributeList::serialize_attr_list(
Expand Down
4 changes: 3 additions & 1 deletion lib/src/sai_redis_generic_get.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ sai_status_t internal_redis_generic_get(
_In_ uint32_t attr_count,
_Out_ sai_attribute_t *attr_list)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

std::vector<swss::FieldValueTuple> entry = SaiAttributeList::serialize_attr_list(
Expand Down Expand Up @@ -101,7 +103,7 @@ sai_status_t internal_redis_generic_get(
const std::string &op = kfvOp(kco);
const std::string &key = kfvKey(kco);

SWSS_LOG_DEBUG("response: %s op = %s, key = %s", key.c_str(), op.c_str());
SWSS_LOG_DEBUG("response: op = %s, key = %s", key.c_str(), op.c_str());

if (op != "getresponse") // ignore non response messages
continue;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/sai_redis_generic_remove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ sai_status_t internal_redis_generic_remove(
_In_ sai_object_type_t object_type,
_In_ const std::string &serialized_object_id)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

std::string str_object_type;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/sai_redis_generic_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ sai_status_t internal_redis_generic_set(
_In_ const std::string &serialized_object_id,
_In_ const sai_attribute_t *attr)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

std::vector<swss::FieldValueTuple> entry = SaiAttributeList::serialize_attr_list(
Expand Down
60 changes: 46 additions & 14 deletions lib/src/sai_redis_interfacequery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,43 @@

#include <string.h>

std::mutex g_mutex;

service_method_table_t g_services;
bool g_initialized = false;
bool g_apiInitialized = false;

swss::DBConnector *g_db = NULL;
swss::DBConnector *g_dbNtf = NULL;
swss::ProducerTable *g_asicState = NULL;

// we probably don't need those to tables to access GET requests
swss::ProducerTable *g_notifySyncdProducer = NULL;
swss::ProducerTable *g_redisGetProducer = NULL;
swss::ConsumerTable *g_redisGetConsumer = NULL;
swss::ConsumerTable *g_redisNotifications = NULL;
swss::ConsumerTable *g_notifySyncdConsumer = NULL;

swss::RedisClient *g_redisClient = NULL;

sai_status_t sai_api_initialize(
_In_ uint64_t flags,
_In_ const service_method_table_t* services)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

if ((NULL == services) || (NULL == services->profile_get_next_value) || (NULL == services->profile_get_value))
{
SWSS_LOG_ERROR("Invalid services handle passed to SAI API initialize\n");
SWSS_LOG_ERROR("Invalid services handle passed to SAI API initialize");
return SAI_STATUS_INVALID_PARAMETER;
}

memcpy(&g_services, services, sizeof(g_services));

if (0 != flags)
{
SWSS_LOG_ERROR("Invalid flags passed to SAI API initialize\n");
SWSS_LOG_ERROR("Invalid flags passed to SAI API initialize");
return SAI_STATUS_INVALID_PARAMETER;
}

Expand All @@ -51,11 +57,21 @@ sai_status_t sai_api_initialize(

g_asicState = new swss::ProducerTable(g_db, "ASIC_STATE");

if (g_notifySyncdProducer != NULL)
delete g_notifySyncdProducer;

g_notifySyncdProducer = new swss::ProducerTable(g_db, "NOTIFYSYNCDREQUERY");

if (g_redisGetProducer != NULL)
delete g_redisGetProducer;

g_redisGetProducer = new swss::ProducerTable(g_db, "GETREQUEST");

if (g_notifySyncdConsumer != NULL)
delete g_notifySyncdConsumer;

g_notifySyncdConsumer = new swss::ConsumerTable(g_db, "NOTIFYSYNCRESPONSE");

if (g_redisGetConsumer != NULL)
delete g_redisGetConsumer;

Expand All @@ -71,15 +87,17 @@ sai_status_t sai_api_initialize(

g_redisClient = new swss::RedisClient(g_db);

g_initialized = true;
g_apiInitialized = true;

return SAI_STATUS_SUCCESS;
}

sai_status_t sai_log_set(
_In_ sai_api_t sai_api_id,
_In_ sai_api_t sai_api_id,
_In_ sai_log_level_t log_level)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

switch (log_level)
Expand All @@ -103,11 +121,11 @@ sai_status_t sai_log_set(
break;

default:
SWSS_LOG_ERROR("Invalid log level %d\n", log_level);
SWSS_LOG_ERROR("Invalid log level %d", log_level);
return SAI_STATUS_INVALID_PARAMETER;
}

switch (sai_api_id)
switch (sai_api_id)
{
case SAI_API_SWITCH:
break;
Expand Down Expand Up @@ -158,28 +176,30 @@ sai_status_t sai_log_set(
break;

default:
SWSS_LOG_ERROR("Invalid API type %d\n", sai_api_id);
SWSS_LOG_ERROR("Invalid API type %d", sai_api_id);
return SAI_STATUS_INVALID_PARAMETER;
}

return SAI_STATUS_SUCCESS;
}

sai_status_t sai_api_query(
_In_ sai_api_t sai_api_id,
_In_ sai_api_t sai_api_id,
_Out_ void** api_method_table)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

if (NULL == api_method_table)
if (NULL == api_method_table)
{
SWSS_LOG_ERROR("NULL method table passed to SAI API initialize\n");
SWSS_LOG_ERROR("NULL method table passed to SAI API initialize");
return SAI_STATUS_INVALID_PARAMETER;
}

if (!g_initialized)
if (!g_apiInitialized)
{
SWSS_LOG_ERROR("SAI API not initialized before calling API query\n");
SWSS_LOG_ERROR("SAI API not initialized before calling API query");
return SAI_STATUS_UNINITIALIZED;
}

Expand Down Expand Up @@ -285,8 +305,20 @@ sai_status_t sai_api_query(
return SAI_STATUS_SUCCESS;

default:
SWSS_LOG_ERROR("Invalid API type %d\n", sai_api_id);
SWSS_LOG_ERROR("Invalid API type %d", sai_api_id);
return SAI_STATUS_INVALID_PARAMETER;
}
}

sai_status_t sai_api_uninitialize(void)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

g_apiInitialized = false;

SWSS_LOG_ERROR("not implemented");

return SAI_STATUS_NOT_IMPLEMENTED;
}
Loading

0 comments on commit 2ddebf6

Please sign in to comment.