meta/SaiSerialize.cpp (4,250 lines of code) (raw):
#include "sai_serialize.h"
#include "sairediscommon.h"
#include "swss/tokenize.h"
#include <nlohmann/json.hpp>
#include <inttypes.h>
#include <vector>
#include <climits>
#include <unordered_map>
#include <arpa/inet.h>
#include <errno.h>
using json = nlohmann::json;
static const std::unordered_map<sai_redis_link_event_damping_algorithm_t, std::string> sai_redis_link_event_damping_algorithm_to_name_map = {
{SAI_REDIS_LINK_EVENT_DAMPING_ALGORITHM_DISABLED, "SAI_REDIS_LINK_EVENT_DAMPING_ALGORITHM_DISABLED"},
{SAI_REDIS_LINK_EVENT_DAMPING_ALGORITHM_AIED, "SAI_REDIS_LINK_EVENT_DAMPING_ALGORITHM_AIED"}};
static const std::unordered_map<sai_redis_port_attr_t, std::string> sai_redis_port_attr_to_name_map = {
{SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGORITHM, "SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGORITHM"},
{SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGO_AIED_CONFIG, "SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGO_AIED_CONFIG"}};
static int char_to_int(
_In_ const char c)
{
SWSS_LOG_ENTER();
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
SWSS_LOG_THROW("unable to convert char %d to int", c);
}
template<class T, typename U>
T* sai_alloc_n_of_ptr_type(U count, T*)
{
SWSS_LOG_ENTER();
return new T[count];
}
template<typename T, typename U>
void sai_alloc_list(
_In_ T count,
_In_ U &element)
{
SWSS_LOG_ENTER();
element.count = count;
element.list = sai_alloc_n_of_ptr_type(count, element.list);
}
template<typename T>
void sai_free_list(
_In_ T &element)
{
SWSS_LOG_ENTER();
delete[] element.list;
element.list = NULL;
}
template<typename T>
static void transfer_primitive(
_In_ const T &src_element,
_In_ T &dst_element)
{
SWSS_LOG_ENTER();
const unsigned char* src_mem = reinterpret_cast<const unsigned char*>(&src_element);
unsigned char* dst_mem = reinterpret_cast<unsigned char*>(&dst_element);
memcpy(dst_mem, src_mem, sizeof(T));
}
template<typename T>
static sai_status_t transfer_list(
_In_ const T &src_element,
_In_ T &dst_element,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (countOnly || dst_element.count == 0)
{
transfer_primitive(src_element.count, dst_element.count);
return SAI_STATUS_SUCCESS;
}
if (dst_element.list == NULL)
{
SWSS_LOG_ERROR("destination list is null, unable to transfer elements");
return SAI_STATUS_FAILURE;
}
if (dst_element.count >= src_element.count)
{
if (src_element.list == NULL && src_element.count > 0)
{
SWSS_LOG_THROW("source list is NULL when count is %u, wrong db insert?", src_element.count);
}
transfer_primitive(src_element.count, dst_element.count);
for (size_t i = 0; i < src_element.count; i++)
{
transfer_primitive(src_element.list[i], dst_element.list[i]);
}
return SAI_STATUS_SUCCESS;
}
// input buffer is too small to get all list elements, so return count only
transfer_primitive(src_element.count, dst_element.count);
return SAI_STATUS_BUFFER_OVERFLOW;
}
#define RETURN_ON_ERROR(x)\
{\
sai_status_t s = (x);\
if (s != SAI_STATUS_SUCCESS)\
return s;\
}
sai_status_t transfer_attribute(
_In_ sai_attr_value_type_t serialization_type,
_In_ const sai_attribute_t &src_attr,
_In_ sai_attribute_t &dst_attr,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
switch (serialization_type)
{
case SAI_ATTR_VALUE_TYPE_BOOL:
transfer_primitive(src_attr.value.booldata, dst_attr.value.booldata);
break;
case SAI_ATTR_VALUE_TYPE_CHARDATA:
transfer_primitive(src_attr.value.chardata, dst_attr.value.chardata);
break;
case SAI_ATTR_VALUE_TYPE_UINT8:
transfer_primitive(src_attr.value.u8, dst_attr.value.u8);
break;
case SAI_ATTR_VALUE_TYPE_INT8:
transfer_primitive(src_attr.value.s8, dst_attr.value.s8);
break;
case SAI_ATTR_VALUE_TYPE_UINT16:
transfer_primitive(src_attr.value.u16, dst_attr.value.u16);
break;
case SAI_ATTR_VALUE_TYPE_INT16:
transfer_primitive(src_attr.value.s16, dst_attr.value.s16);
break;
case SAI_ATTR_VALUE_TYPE_UINT32:
transfer_primitive(src_attr.value.u32, dst_attr.value.u32);
break;
case SAI_ATTR_VALUE_TYPE_INT32:
transfer_primitive(src_attr.value.s32, dst_attr.value.s32);
break;
case SAI_ATTR_VALUE_TYPE_UINT64:
transfer_primitive(src_attr.value.u64, dst_attr.value.u64);
break;
// case SAI_ATTR_VALUE_TYPE_INT64:
// transfer_primitive(src_attr.value.s64, dst_attr.value.s64);
// break;
case SAI_ATTR_VALUE_TYPE_MAC:
transfer_primitive(src_attr.value.mac, dst_attr.value.mac);
break;
case SAI_ATTR_VALUE_TYPE_IPV4:
transfer_primitive(src_attr.value.ip4, dst_attr.value.ip4);
break;
case SAI_ATTR_VALUE_TYPE_IPV6:
transfer_primitive(src_attr.value.ip6, dst_attr.value.ip6);
break;
case SAI_ATTR_VALUE_TYPE_POINTER:
transfer_primitive(src_attr.value.ptr, dst_attr.value.ptr);
break;
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS:
transfer_primitive(src_attr.value.ipaddr, dst_attr.value.ipaddr);
break;
case SAI_ATTR_VALUE_TYPE_IP_PREFIX:
transfer_primitive(src_attr.value.ipprefix, dst_attr.value.ipprefix);
break;
case SAI_ATTR_VALUE_TYPE_OBJECT_ID:
transfer_primitive(src_attr.value.oid, dst_attr.value.oid);
break;
case SAI_ATTR_VALUE_TYPE_OBJECT_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.objlist, dst_attr.value.objlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_UINT8_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.u8list, dst_attr.value.u8list, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_INT8_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.s8list, dst_attr.value.s8list, countOnly));
break;
// case SAI_ATTR_VALUE_TYPE_UINT16_LIST:
// RETURN_ON_ERROR(transfer_list(src_attr.value.u16list, dst_attr.value.u16list, countOnly));
// break;
//
// case SAI_ATTR_VALUE_TYPE_INT16_LIST:
// RETURN_ON_ERROR(transfer_list(src_attr.value.s16list, dst_attr.value.s16list, countOnly));
// break;
case SAI_ATTR_VALUE_TYPE_UINT32_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.u32list, dst_attr.value.u32list, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_INT32_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.s32list, dst_attr.value.s32list, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
transfer_primitive(src_attr.value.u32range, dst_attr.value.u32range);
break;
// case SAI_ATTR_VALUE_TYPE_INT32_RANGE:
// transfer_primitive(src_attr.value.s32range, dst_attr.value.s32range);
// break;
case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.u16rangelist, dst_attr.value.u16rangelist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_TIMESPEC:
transfer_primitive(src_attr.value.timespec, dst_attr.value.timespec);
break;
case SAI_ATTR_VALUE_TYPE_JSON:
transfer_primitive(src_attr.value.json, dst_attr.value.json);
break;
case SAI_ATTR_VALUE_TYPE_PORT_LANE_LATCH_STATUS_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.portlanelatchstatuslist, dst_attr.value.portlanelatchstatuslist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_LATCH_STATUS:
transfer_primitive(src_attr.value.latchstatus, dst_attr.value.latchstatus);
break;
case SAI_ATTR_VALUE_TYPE_VLAN_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.vlanlist, dst_attr.value.vlanlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.qosmap, dst_attr.value.qosmap, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.aclresource, dst_attr.value.aclresource, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.ipaddrlist, dst_attr.value.ipaddrlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.segmentlist, dst_attr.value.segmentlist, countOnly));
break;
/* ACL FIELD DATA */
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.data.booldata, dst_attr.value.aclfield.data.booldata);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.u8, dst_attr.value.aclfield.mask.u8);
transfer_primitive(src_attr.value.aclfield.data.u8, dst_attr.value.aclfield.data.u8);
break;
// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
// transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
// transfer_primitive(src_attr.value.aclfield.mask.s8, dst_attr.value.aclfield.mask.s8);
// transfer_primitive(src_attr.value.aclfield.data.s8, dst_attr.value.aclfield.data.s8);
// break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.u16, dst_attr.value.aclfield.mask.u16);
transfer_primitive(src_attr.value.aclfield.data.u16, dst_attr.value.aclfield.data.u16);
break;
// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
// transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
// transfer_primitive(src_attr.value.aclfield.mask.s16, dst_attr.value.aclfield.mask.s16);
// transfer_primitive(src_attr.value.aclfield.data.s16, dst_attr.value.aclfield.data.s16);
// break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.u32, dst_attr.value.aclfield.mask.u32);
transfer_primitive(src_attr.value.aclfield.data.u32, dst_attr.value.aclfield.data.u32);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.s32, dst_attr.value.aclfield.mask.s32);
transfer_primitive(src_attr.value.aclfield.data.s32, dst_attr.value.aclfield.data.s32);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.u64, dst_attr.value.aclfield.mask.u64);
transfer_primitive(src_attr.value.aclfield.data.u64, dst_attr.value.aclfield.data.u64);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.mac, dst_attr.value.aclfield.mask.mac);
transfer_primitive(src_attr.value.aclfield.data.mac, dst_attr.value.aclfield.data.mac);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.ip4, dst_attr.value.aclfield.mask.ip4);
transfer_primitive(src_attr.value.aclfield.data.ip4, dst_attr.value.aclfield.data.ip4);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.mask.ip6, dst_attr.value.aclfield.mask.ip6);
transfer_primitive(src_attr.value.aclfield.data.ip6, dst_attr.value.aclfield.data.ip6);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
transfer_primitive(src_attr.value.aclfield.data.oid, dst_attr.value.aclfield.data.oid);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
RETURN_ON_ERROR(transfer_list(src_attr.value.aclfield.data.objlist, dst_attr.value.aclfield.data.objlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:
transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable);
RETURN_ON_ERROR(transfer_list(src_attr.value.aclfield.mask.u8list, dst_attr.value.aclfield.mask.u8list, countOnly));
transfer_list(src_attr.value.aclfield.data.u8list, dst_attr.value.aclfield.data.u8list, countOnly);
break;
/* ACL ACTION DATA */
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.booldata, dst_attr.value.aclaction.parameter.booldata);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.u8, dst_attr.value.aclaction.parameter.u8);
break;
// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
// transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
// transfer_primitive(src_attr.value.aclaction.parameter.s8, dst_attr.value.aclaction.parameter.s8);
// break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.u16, dst_attr.value.aclaction.parameter.u16);
break;
// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
// transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
// transfer_primitive(src_attr.value.aclaction.parameter.s16, dst_attr.value.aclaction.parameter.s16);
// break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.u32, dst_attr.value.aclaction.parameter.u32);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.s32, dst_attr.value.aclaction.parameter.s32);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.mac, dst_attr.value.aclaction.parameter.mac);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.ip4, dst_attr.value.aclaction.parameter.ip4);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.ip6, dst_attr.value.aclaction.parameter.ip6);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.ipaddr, dst_attr.value.aclaction.parameter.ipaddr);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
transfer_primitive(src_attr.value.aclaction.parameter.oid, dst_attr.value.aclaction.parameter.oid);
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable);
RETURN_ON_ERROR(transfer_list(src_attr.value.aclaction.parameter.objlist, dst_attr.value.aclaction.parameter.objlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY:
transfer_primitive(src_attr.value.aclcapability.is_action_list_mandatory, dst_attr.value.aclcapability.is_action_list_mandatory);
RETURN_ON_ERROR(transfer_list(src_attr.value.aclcapability.action_list, dst_attr.value.aclcapability.action_list, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG:
transfer_primitive(src_attr.value.sysportconfig, dst_attr.value.sysportconfig);
break;
case SAI_ATTR_VALUE_TYPE_AUTH_KEY:
transfer_primitive(src_attr.value.authkey, dst_attr.value.authkey);
break;
case SAI_ATTR_VALUE_TYPE_MACSEC_AUTH_KEY:
transfer_primitive(src_attr.value.macsecauthkey, dst_attr.value.macsecauthkey);
break;
case SAI_ATTR_VALUE_TYPE_MACSEC_SALT:
transfer_primitive(src_attr.value.macsecsalt, dst_attr.value.macsecsalt);
break;
case SAI_ATTR_VALUE_TYPE_MACSEC_SAK:
transfer_primitive(src_attr.value.macsecsak, dst_attr.value.macsecsak);
break;
case SAI_ATTR_VALUE_TYPE_ENCRYPT_KEY:
transfer_primitive(src_attr.value.encrypt_key, dst_attr.value.encrypt_key);
break;
case SAI_ATTR_VALUE_TYPE_PORT_ERR_STATUS_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.porterror, dst_attr.value.porterror, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_PORT_EYE_VALUES_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.porteyevalues, dst_attr.value.porteyevalues, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_FABRIC_PORT_REACHABILITY:
transfer_primitive(src_attr.value.reachability, dst_attr.value.reachability);
break;
case SAI_ATTR_VALUE_TYPE_PRBS_RX_STATE:
transfer_primitive(src_attr.value.rx_state, dst_attr.value.rx_state);
break;
case SAI_ATTR_VALUE_TYPE_MAP_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.maplist, dst_attr.value.maplist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_TLV_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.tlvlist, dst_attr.value.tlvlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.sysportconfiglist, dst_attr.value.sysportconfiglist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.ipprefixlist, dst_attr.value.ipprefixlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_PORT_FREQUENCY_OFFSET_PPM_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.portfrequencyoffsetppmlist, dst_attr.value.portfrequencyoffsetppmlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_PORT_SNR_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.portsnrlist, dst_attr.value.portsnrlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_ACL_CHAIN_LIST:
RETURN_ON_ERROR(transfer_list(src_attr.value.aclchainlist, dst_attr.value.aclchainlist, countOnly));
break;
case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION:
transfer_primitive(src_attr.value.portpowerconsumption, dst_attr.value.portpowerconsumption);
break;
default:
SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(serialization_type).c_str());
}
return SAI_STATUS_SUCCESS;
}
sai_status_t transfer_attributes(
_In_ sai_object_type_t object_type,
_In_ uint32_t attr_count,
_In_ const sai_attribute_t *src_attr_list,
_In_ sai_attribute_t *dst_attr_list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
for (uint32_t i = 0; i < attr_count; i++)
{
const sai_attribute_t &src_attr = src_attr_list[i];
sai_attribute_t &dst_attr = dst_attr_list[i];
auto meta = sai_metadata_get_attr_metadata(object_type, src_attr.id);
if (src_attr.id != dst_attr.id)
{
SWSS_LOG_THROW("src (%d) vs dst (%d) attr id don't match GET mismatch", src_attr.id, dst_attr.id);
}
if (meta == NULL)
{
SWSS_LOG_THROW("unable to get metadata for object type %s, attribute %d",
sai_serialize_object_type(object_type).c_str(),
src_attr.id);
}
RETURN_ON_ERROR(transfer_attribute(meta->attrvaluetype, src_attr, dst_attr, countOnly));
}
return SAI_STATUS_SUCCESS;
}
// util
static uint8_t get_ip_mask(
_In_ const uint8_t* mask,
_In_ bool ipv6)
{
SWSS_LOG_ENTER();
uint8_t ones = 0;
bool zeros = false;
uint8_t count = ipv6 ? 128 : 32;
for (uint8_t i = 0; i < count; i++)
{
bool bit = (mask[i/8]) & (1 << (7 - (i%8)));
if (zeros && bit)
{
SWSS_LOG_THROW("FATAL: invalid ipv%d mask", ipv6 ? 6 : 4);
}
zeros |= !bit;
if (bit)
{
ones++;
}
}
return ones;
}
static uint8_t get_ipv4_mask(
_In_ const sai_ip4_t mask)
{
SWSS_LOG_ENTER();
return get_ip_mask((const uint8_t*)&mask, false);
}
static int get_ipv6_mask(
_In_ const sai_ip6_t &mask)
{
SWSS_LOG_ENTER();
return get_ip_mask(mask, true);
}
static void sai_populate_ip_mask(
_In_ uint8_t bits,
_Out_ uint8_t *mask,
_In_ bool ipv6)
{
SWSS_LOG_ENTER();
if (mask == NULL)
{
SWSS_LOG_THROW("mask pointer is null");
}
if ((ipv6 && (bits > 128)) || (!ipv6 && (bits > 32)))
{
SWSS_LOG_THROW("invalid ip mask bits %u", bits);
}
// zero all mask
memset(mask, 0, ipv6 ? 16 : 4);
// set full bytes to all ones
for (uint8_t i = 0; i < bits/8; i++)
{
mask[i] = 0xFF;
}
int rem = bits % 8;
if (rem)
{
// set last non zero byte
mask[bits/8] =(uint8_t)(0xFF << (8 - rem));
}
}
// new methods
std::string sai_serialize_bool(
_In_ bool b)
{
SWSS_LOG_ENTER();
return b ? "true" : "false";
}
#define CHAR_LEN 32
std::string sai_serialize_chardata(
_In_ const char data[CHAR_LEN])
{
SWSS_LOG_ENTER();
std::string s;
char buf[8];
size_t len = strnlen(data, CHAR_LEN);
for (size_t i = 0; i < len; ++i)
{
unsigned char c = (unsigned char)data[i];
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
s += c;
continue;
}
if (c == '\\')
{
s += "\\\\";
continue;
}
snprintf(buf, sizeof(buf), "\\x%02X", (int)c);
s += buf;
}
return s;
}
std::string sai_serialize_mac(
_In_ const sai_mac_t mac)
{
SWSS_LOG_ENTER();
char buf[32];
snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return buf;
}
template <typename T>
std::string sai_serialize_number(
_In_ const T number,
_In_ bool hex = false)
{
SWSS_LOG_ENTER();
if (hex)
{
char buf[32];
snprintf(buf, sizeof(buf), "0x%" PRIx64, (uint64_t)number);
return buf;
}
return std::to_string(number);
}
std::string sai_serialize_enum(
_In_ const int32_t value,
_In_ const sai_enum_metadata_t* meta)
{
SWSS_LOG_ENTER();
if (meta == NULL)
{
return sai_serialize_number(value);
}
for (size_t i = 0; i < meta->valuescount; ++i)
{
if (meta->values[i] == value)
{
return meta->valuesnames[i];
}
}
SWSS_LOG_WARN("enum value %d not found in enum %s", value, meta->name);
return sai_serialize_number(value);
}
std::string sai_serialize_number(
_In_ const uint32_t number,
_In_ bool hex)
{
SWSS_LOG_ENTER();
return sai_serialize_number<uint32_t>(number, hex);
}
std::string sai_serialize_attr_id(
_In_ const sai_attr_metadata_t& meta)
{
SWSS_LOG_ENTER();
return meta.attridname;
}
std::string sai_serialize_status(
_In_ const sai_status_t status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(status, &sai_metadata_enum_sai_status_t);
}
std::string sai_serialize_common_api(
_In_ const sai_common_api_t common_api)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(common_api, &sai_metadata_enum_sai_common_api_t);
}
std::string sai_serialize_object_type(
_In_ const sai_object_type_t object_type)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(object_type, &sai_metadata_enum_sai_object_type_t);
}
std::string sai_serialize_log_level(
_In_ sai_log_level_t log_level)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(log_level, &sai_metadata_enum_sai_log_level_t);
}
std::string sai_serialize_api(
_In_ sai_api_t api)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(api, &sai_metadata_enum_sai_api_t);
}
std::string sai_serialize_attr_value_type(
_In_ const sai_attr_value_type_t attr_value_type)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(attr_value_type, &sai_metadata_enum_sai_attr_value_type_t);
}
std::string sai_serialize_packet_color(
_In_ sai_packet_color_t color)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(color, &sai_metadata_enum_sai_packet_color_t);
}
std::string sai_serialize_vlan_id(
_In_ sai_vlan_id_t vlan_id)
{
SWSS_LOG_ENTER();
return sai_serialize_number(vlan_id);
}
std::string sai_serialize_neighbor_entry(
_In_ const sai_neighbor_entry_t &ne)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(ne.switch_id);
j["rif"] = sai_serialize_object_id(ne.rif_id);
j["ip"] = sai_serialize_ip_address(ne.ip_address);
return j.dump();
}
#define EMIT(x) buf += sprintf(buf, x)
#define EMIT_QUOTE EMIT("\"")
#define EMIT_KEY(k) EMIT("\"" k "\":")
#define EMIT_NEXT_KEY(k) { EMIT(","); EMIT_KEY(k); }
#define EMIT_CHECK(expr, suffix) { \
ret = (expr); \
if (ret < 0) { \
SWSS_LOG_THROW("failed to serialize " #suffix ""); } \
buf += ret; }
#define EMIT_QUOTE_CHECK(expr, suffix) {\
EMIT_QUOTE; EMIT_CHECK(expr, suffix); EMIT_QUOTE; }
std::string sai_serialize_route_entry(
_In_ const sai_route_entry_t& route_entry)
{
SWSS_LOG_ENTER();
// NOTE: this serialize is copy from SAI/meta auto generated serialization
// but since previously we used json.hpp, then order of serialized item is
// different, so we copy actual serialize method and reorder names
// {"dest":"0.0.0.0/0","switch_id":"oid:0x21000000000000","vr":"oid:0x3000000000022"}
char buffer[256];
char *buf = buffer;
char *begin_buf = buf;
int ret;
EMIT("{");
EMIT_KEY("dest");
EMIT_QUOTE_CHECK(sai_serialize_ip_prefix(buf, &route_entry.destination), ip_prefix);
EMIT_NEXT_KEY("switch_id");
EMIT_QUOTE_CHECK(sai_serialize_object_id(buf, route_entry.switch_id), object_id);
EMIT_NEXT_KEY("vr");
EMIT_QUOTE_CHECK(sai_serialize_object_id(buf, route_entry.vr_id), object_id);
EMIT("}");
*buf = 0;
return std::string(begin_buf, (int)(buf - begin_buf));
}
std::string sai_serialize_ipmc_entry(
_In_ const sai_ipmc_entry_t& ipmc_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(ipmc_entry.switch_id);
j["vr_id"] = sai_serialize_object_id(ipmc_entry.vr_id);
j["type"] = sai_serialize_ipmc_entry_type(ipmc_entry.type);
j["destination"] = sai_serialize_ip_address(ipmc_entry.destination);
j["source"] = sai_serialize_ip_address(ipmc_entry.source);
return j.dump();
}
std::string sai_serialize_l2mc_entry(
_In_ const sai_l2mc_entry_t& l2mc_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(l2mc_entry.switch_id);
j["bv_id"] = sai_serialize_object_id(l2mc_entry.bv_id);
j["type"] = sai_serialize_l2mc_entry_type(l2mc_entry.type);
j["destination"] = sai_serialize_ip_address(l2mc_entry.destination);
j["source"] = sai_serialize_ip_address(l2mc_entry.source);
return j.dump();
}
std::string sai_serialize_mcast_fdb_entry(
_In_ const sai_mcast_fdb_entry_t& mcast_fdb_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(mcast_fdb_entry.switch_id);
j["bv_id"] = sai_serialize_object_id(mcast_fdb_entry.bv_id);
j["mac_address"] = sai_serialize_mac(mcast_fdb_entry.mac_address);
return j.dump();
}
std::string sai_serialize_inseg_entry(
_In_ const sai_inseg_entry_t& inseg_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(inseg_entry.switch_id);
j["label"] = sai_serialize_number(inseg_entry.label);
return j.dump();
}
std::string sai_serialize_fdb_entry(
_In_ const sai_fdb_entry_t& fdb_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(fdb_entry.switch_id);
j["mac"] = sai_serialize_mac(fdb_entry.mac_address);
j["bvid"] = sai_serialize_object_id(fdb_entry.bv_id);
return j.dump();
}
std::string sai_serialize_meter_bucket_entry(
_In_ const sai_meter_bucket_entry_t &meter_bucket_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(meter_bucket_entry.switch_id);
j["eni_id"] = sai_serialize_object_id(meter_bucket_entry.eni_id);
j["meter_class"] = sai_serialize_number<uint32_t>(meter_bucket_entry.meter_class);
return j.dump();
}
std::string sai_serialize_flow_entry(
_In_ const sai_flow_entry_t &flow_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(flow_entry.switch_id);
j["eni_mac"] = sai_serialize_mac(flow_entry.eni_mac);
j["vnet_id"] = sai_serialize_number<uint16_t>(flow_entry.vnet_id);
j["ip_proto"] = sai_serialize_number<uint8_t>(flow_entry.ip_proto);
j["src_ip"] = sai_serialize_ip_address(flow_entry.src_ip);
j["dst_ip"] = sai_serialize_ip_address(flow_entry.dst_ip);
j["src_port"] = sai_serialize_number<uint16_t>(flow_entry.src_port);
j["dst_port"] = sai_serialize_number<uint16_t>(flow_entry.dst_port);
return j.dump();
}
std::string sai_serialize_l2mc_entry_type(
_In_ const sai_l2mc_entry_type_t type)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(type, &sai_metadata_enum_sai_l2mc_entry_type_t);
}
std::string sai_serialize_ipmc_entry_type(
_In_ const sai_ipmc_entry_type_t type)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(type, &sai_metadata_enum_sai_ipmc_entry_type_t);
}
std::string sai_serialize_port_stat(
_In_ const sai_port_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_port_stat_t);
}
std::string sai_serialize_switch_stat(
_In_ const sai_switch_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_switch_stat_t);
}
std::string sai_serialize_port_pool_stat(
_In_ const sai_port_pool_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_port_pool_stat_t);
}
std::string sai_serialize_queue_stat(
_In_ const sai_queue_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_queue_stat_t);
}
std::string sai_serialize_router_interface_stat(
_In_ const sai_router_interface_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_router_interface_stat_t);
}
std::string sai_serialize_ingress_priority_group_stat(
_In_ const sai_ingress_priority_group_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_ingress_priority_group_stat_t);
}
std::string sai_serialize_ingress_priority_group_attr(
_In_ const sai_ingress_priority_group_attr_t attr)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(attr, &sai_metadata_enum_sai_ingress_priority_group_attr_t);
}
std::string sai_serialize_buffer_pool_stat(
_In_ const sai_buffer_pool_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_buffer_pool_stat_t);
}
std::string sai_serialize_eni_stat(
_In_ const sai_eni_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_eni_stat_t);
}
std::string sai_serialize_meter_bucket_entry_stat(
_In_ const sai_meter_bucket_entry_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_meter_bucket_entry_stat_t);
}
std::string sai_serialize_tunnel_stat(
_In_ const sai_tunnel_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_tunnel_stat_t);
}
std::string sai_serialize_counter_stat(
_In_ const sai_counter_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_counter_stat_t);
}
std::string sai_serialize_policer_stat(
_In_ const sai_policer_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_policer_stat_t);
}
std::string sai_serialize_queue_attr(
_In_ const sai_queue_attr_t attr)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(attr, &sai_metadata_enum_sai_queue_attr_t);
}
std::string sai_serialize_macsec_flow_stat(
_In_ const sai_macsec_flow_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_macsec_flow_stat_t);
}
std::string sai_serialize_macsec_sa_stat(
_In_ const sai_macsec_sa_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_macsec_sa_stat_t);
}
std::string sai_serialize_macsec_sa_attr(
_In_ const sai_macsec_sa_attr_t &attr)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(attr, &sai_metadata_enum_sai_macsec_sa_attr_t);
}
std::string sai_serialize_acl_counter_attr(
_In_ const sai_acl_counter_attr_t &attr)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(attr, &sai_metadata_enum_sai_acl_counter_attr_t);
}
std::string sai_serialize_switch_oper_status(
_In_ sai_object_id_t switch_id,
_In_ sai_switch_oper_status_t status)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(switch_id);
j["status"] = sai_serialize_enum(status, &sai_metadata_enum_sai_switch_oper_status_t);
return j.dump();
}
std::string sai_serialize_port_host_tx_ready_status(
_In_ const sai_port_host_tx_ready_status_t status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(status, &sai_metadata_enum_sai_port_host_tx_ready_status_t);
}
std::string sai_serialize_ingress_drop_reason(
_In_ const sai_in_drop_reason_t reason)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(reason, &sai_metadata_enum_sai_in_drop_reason_t);
}
std::string sai_serialize_egress_drop_reason(
_In_ const sai_out_drop_reason_t reason)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(reason, &sai_metadata_enum_sai_out_drop_reason_t);
}
std::string sai_serialize_timespec(
_In_ const sai_timespec_t ×pec)
{
SWSS_LOG_ENTER();
json j;
j["tv_sec"] = sai_serialize_number<uint64_t>(timespec.tv_sec);
j["tv_nsec"] = sai_serialize_number<uint32_t>(timespec.tv_nsec);
return j.dump();
}
std::string sai_serialize_switch_asic_sdk_health_event(
_In_ sai_object_id_t switch_id,
_In_ sai_switch_asic_sdk_health_severity_t severity,
_In_ const sai_timespec_t ×tamp,
_In_ sai_switch_asic_sdk_health_category_t category,
_In_ const sai_switch_health_data_t &data,
_In_ const sai_u8_list_t &description)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(switch_id);
j["severity"] = sai_serialize_enum(severity, &sai_metadata_enum_sai_switch_asic_sdk_health_severity_t);
j["timestamp"] = sai_serialize_timespec(timestamp);
j["category"] = sai_serialize_enum(category, &sai_metadata_enum_sai_switch_asic_sdk_health_category_t);
j["data.data_type"] = sai_serialize_enum(data.data_type, &sai_metadata_enum_sai_health_data_type_t);
j["description"] = sai_serialize_number_list(description, false);
return j.dump();
}
std::string sai_serialize_switch_shutdown_request(
_In_ sai_object_id_t switch_id)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(switch_id);
return j.dump();
}
std::string sai_serialize_ipv4(
_In_ sai_ip4_t ip)
{
SWSS_LOG_ENTER();
char buf[INET_ADDRSTRLEN];
struct sockaddr_in sa;
memcpy(&sa.sin_addr, &ip, 4);
if (inet_ntop(AF_INET, &(sa.sin_addr), buf, INET_ADDRSTRLEN) == NULL)
{
SWSS_LOG_THROW("FATAL: failed to convert IPv4 address, errno: %s", strerror(errno));
}
return buf;
}
std::string sai_serialize_pointer(
_In_ sai_pointer_t ptr)
{
SWSS_LOG_ENTER();
return sai_serialize_number((uint64_t)ptr, true);
}
std::string sai_serialize_ipv6(
_In_ const sai_ip6_t& ip)
{
SWSS_LOG_ENTER();
char buf[INET6_ADDRSTRLEN];
struct sockaddr_in6 sa6;
memcpy(&sa6.sin6_addr, ip, 16);
if (inet_ntop(AF_INET6, &(sa6.sin6_addr), buf, INET6_ADDRSTRLEN) == NULL)
{
SWSS_LOG_THROW("FATAL: failed to convert IPv6 address, errno: %s", strerror(errno));
}
return buf;
}
std::string sai_serialize_ip_address(
_In_ const sai_ip_address_t& ipaddress)
{
SWSS_LOG_ENTER();
switch (ipaddress.addr_family)
{
case SAI_IP_ADDR_FAMILY_IPV4:
return sai_serialize_ipv4(ipaddress.addr.ip4);
case SAI_IP_ADDR_FAMILY_IPV6:
return sai_serialize_ipv6(ipaddress.addr.ip6);
default:
SWSS_LOG_THROW("FATAL: invalid ip address family: %d", ipaddress.addr_family);
}
}
std::string sai_serialize_object_id(
_In_ sai_object_id_t oid)
{
SWSS_LOG_ENTER();
char buf[32];
snprintf(buf, sizeof(buf), "oid:0x%" PRIx64, oid);
return buf;
}
template<typename T, typename F>
std::string sai_serialize_list(
_In_ const T& list,
_In_ bool countOnly,
F serialize_item)
{
SWSS_LOG_ENTER();
std::string s = sai_serialize_number(list.count);
if (countOnly)
{
return s;
}
if (list.list == NULL || list.count == 0)
{
return s + ":null";
}
std::string l;
for (uint32_t i = 0; i < list.count; ++i)
{
l += serialize_item(list.list[i]);
if (i != list.count -1)
{
l += ",";
}
}
return s + ":" + l;
}
std::string sai_serialize_ip_address_list(
_In_ const sai_ip_address_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
return sai_serialize_list(list, countOnly, [&](sai_ip_address_t item) { return sai_serialize_ip_address(item);} );
}
std::string sai_serialize_ip_prefix_list(
_In_ const sai_ip_prefix_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
return sai_serialize_list(list, countOnly, [&](sai_ip_prefix_t item) { return sai_serialize_ip_prefix(item);} );
}
std::string sai_serialize_enum_list(
_In_ const sai_s32_list_t& list,
_In_ const sai_enum_metadata_t* meta,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
return sai_serialize_list(list, countOnly, [&](int32_t item) { return sai_serialize_enum(item, meta);} );
}
std::string sai_serialize_oid_list(
_In_ const sai_object_list_t &list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
return sai_serialize_list(list, countOnly, [&](sai_object_id_t item) { return sai_serialize_object_id(item);} );
}
template <typename T>
std::string sai_serialize_number_list(
_In_ const T& list,
_In_ bool countOnly,
_In_ bool hex)
{
SWSS_LOG_ENTER();
return sai_serialize_list(list, countOnly, [&](decltype(*list.list)& item) { return sai_serialize_number(item, hex);} );
}
static json sai_serialize_qos_map_params(
_In_ const sai_qos_map_params_t& params)
{
SWSS_LOG_ENTER();
json j;
j["tc"] = params.tc;
j["dscp"] = params.dscp;
j["dot1p"] = params.dot1p;
j["prio"] = params.prio;
j["pg"] = params.pg;
j["qidx"] = params.queue_index;
j["mpls_exp"] = params.mpls_exp;
j["color"] = sai_serialize_packet_color(params.color);
j["fc"] = params.fc;
return j;
}
json sai_serialize_qos_map(
_In_ const sai_qos_map_t& qosmap)
{
SWSS_LOG_ENTER();
json j;
j["key"] = sai_serialize_qos_map_params(qosmap.key);
j["value"] = sai_serialize_qos_map_params(qosmap.value);;
return j;
}
std::string sai_serialize_qos_map_item(
_In_ const sai_qos_map_t& qosmap)
{
SWSS_LOG_ENTER();
json j;
j["key"] = sai_serialize_qos_map_params(qosmap.key);
j["value"] = sai_serialize_qos_map_params(qosmap.value);;
return j.dump();
}
std::string sai_serialize_qos_map_list(
_In_ const sai_qos_map_list_t& qosmap,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j;
j["count"] = qosmap.count;
if (qosmap.list == NULL || countOnly)
{
j["list"] = nullptr;
return j.dump();
}
json arr = json::array();
for (uint32_t i = 0; i < qosmap.count; ++i)
{
json item = sai_serialize_qos_map(qosmap.list[i]);
arr.push_back(item);
}
j["list"] = arr;
return j.dump();
}
json sai_serialize_map(
_In_ const sai_map_t &map)
{
SWSS_LOG_ENTER();
json j;
j["key"] = map.key;
j["value"] = map.value;
return j;
}
std::string sai_serialize_map_list(
_In_ const sai_map_list_t &maplist,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j;
j["count"] = maplist.count;
if (maplist.list == NULL || countOnly)
{
j["list"] = nullptr;
return j.dump();
}
json arr = json::array();
for (uint32_t i = 0; i < maplist.count; ++i)
{
json item = sai_serialize_map(maplist.list[i]);
arr.push_back(item);
}
j["list"] = arr;
return j.dump();
}
json sai_serialize_acl_resource(
_In_ const sai_acl_resource_t& aclresource)
{
SWSS_LOG_ENTER();
json j;
j["stage"] = sai_serialize_enum(aclresource.stage, &sai_metadata_enum_sai_acl_stage_t);
j["bind_point"] = sai_serialize_enum(aclresource.bind_point, &sai_metadata_enum_sai_acl_bind_point_type_t);
j["avail_num"] = sai_serialize_number(aclresource.avail_num);
return j;
}
std::string sai_serialize_acl_resource_list(
_In_ const sai_acl_resource_list_t& aclresource,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j;
j["count"] = aclresource.count;
if (aclresource.list == NULL || countOnly)
{
j["list"] = nullptr;
return j.dump();
}
json arr = json::array();
for (uint32_t i = 0; i < aclresource.count; ++i)
{
json item = sai_serialize_acl_resource(aclresource.list[i]);
arr.push_back(item);
}
j["list"] = arr;
return j.dump();
}
std::string sai_serialize_latch_status(
_In_ const sai_latch_status_t& latch_status)
{
SWSS_LOG_ENTER();
auto changed = sai_serialize_bool(latch_status.changed);
auto current_status = sai_serialize_bool(latch_status.current_status);
return changed + ":" + current_status;
}
json sai_serialize_port_lane_latch_status_item(
_In_ const sai_port_lane_latch_status_t& lane_latch_status)
{
SWSS_LOG_ENTER();
json j;
j["lane"] = lane_latch_status.lane;
j["value"] = sai_serialize_latch_status(lane_latch_status.value);
return j;
}
std::string sai_serialize_port_lane_latch_status_list(
_In_ const sai_port_lane_latch_status_list_t& status_list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j;
j["count"] = status_list.count;
if (status_list.list == NULL || countOnly)
{
j["list"] = nullptr;
return j.dump();
}
json arr = json::array();
for (uint32_t i = 0; i < status_list.count; ++i)
{
json item = sai_serialize_port_lane_latch_status_item(status_list.list[i]);
arr.push_back(item);
}
j["list"] = arr;
return j.dump();
}
template <typename T>
std::string sai_serialize_range(
_In_ const T& range)
{
SWSS_LOG_ENTER();
return sai_serialize_number(range.min) + "," + sai_serialize_number(range.max);
}
std::string sai_serialize_u16_range_list(
_In_ const sai_u16_range_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
return sai_serialize_list(list, countOnly, [&](sai_u16_range_t item) { return sai_serialize_range(item);} );
}
std::string sai_serialize_acl_action(
_In_ const sai_attr_metadata_t& meta,
_In_ const sai_acl_action_data_t& action,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (action.enable == false)
{
// parameter is not needed when action is disabled
return "disabled";
}
switch (meta.attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
return sai_serialize_bool(action.parameter.booldata);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
return sai_serialize_number(action.parameter.u8);
// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
// return sai_serialize_number(action.parameter.s8);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
return sai_serialize_number(action.parameter.u16);
// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
// return sai_serialize_number(action.parameter.s16);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
return sai_serialize_number(action.parameter.u32);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
return sai_serialize_enum(action.parameter.s32, meta.enummetadata);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
return sai_serialize_mac(action.parameter.mac);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
return sai_serialize_ipv4(action.parameter.ip4);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
return sai_serialize_ipv6(action.parameter.ip6);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS:
return sai_serialize_ip_address(action.parameter.ipaddr);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
return sai_serialize_object_id(action.parameter.oid);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
return sai_serialize_oid_list(action.parameter.objlist, countOnly);
default:
SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
}
}
std::string sai_serialize_acl_field(
_In_ const sai_attr_metadata_t& meta,
_In_ const sai_acl_field_data_t& field,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (field.enable == false)
{
// parameter is not needed when field is disabled
return "disabled";
}
switch (meta.attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
return sai_serialize_bool(field.data.booldata);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
return sai_serialize_number(field.data.u8) + "&mask:" + sai_serialize_number(field.mask.u8, true);
// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
// return sai_serialize_number(field.data.s8) + "&mask:" + sai_serialize_number(field.mask.s8, true);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
return sai_serialize_number(field.data.u16) + "&mask:" + sai_serialize_number(field.mask.u16, true);
// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
// return sai_serialize_number(field.data.s16) + "&mask:" + sai_serialize_number(field.mask.s16, true);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
return sai_serialize_number(field.data.u32) + "&mask:" + sai_serialize_number(field.mask.u32, true);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
return sai_serialize_enum(field.data.s32, meta.enummetadata) + "&mask:" + sai_serialize_number(field.mask.s32, true);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
return sai_serialize_number(field.data.u64) + "&mask:" + sai_serialize_number(field.mask.u64, true);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
return sai_serialize_mac(field.data.mac) +"&mask:" + sai_serialize_mac(field.mask.mac);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
return sai_serialize_ipv4(field.data.ip4) +"&mask:" + sai_serialize_ipv4(field.mask.ip4);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
return sai_serialize_ipv6(field.data.ip6) +"&mask:" + sai_serialize_ipv6(field.mask.ip6);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
return sai_serialize_object_id(field.data.oid);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
return sai_serialize_oid_list(field.data.objlist, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:
return sai_serialize_number_list(field.data.u8list, countOnly) + "&mask:" + sai_serialize_number_list(field.mask.u8list, countOnly, true);
default:
SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
}
}
std::string sai_serialize_acl_capability(
_In_ const sai_attr_metadata_t &meta,
_In_ const sai_acl_capability_t &cap,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
auto mandatory = sai_serialize_bool(cap.is_action_list_mandatory);
auto list = sai_serialize_enum_list(cap.action_list, &sai_metadata_enum_sai_acl_action_type_t, countOnly);
return mandatory + ":" + list;
}
std::string sai_serialize_hex_binary(
_In_ const void *buffer,
_In_ size_t length)
{
SWSS_LOG_ENTER();
std::string s;
if (buffer == NULL || length == 0)
{
return s;
}
s.resize(2 * length, '0');
const unsigned char *input = static_cast<const unsigned char *>(buffer);
char *output = &s[0];
for (size_t i = 0; i < length; i++)
{
snprintf(&output[i * 2], 3, "%02X", input[i]);
}
return s;
}
std::string sai_serialize_direction_lookup_entry(
_In_ const sai_direction_lookup_entry_t &direction_lookup_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(direction_lookup_entry.switch_id);
j["vni"] = sai_serialize_number(direction_lookup_entry.vni);
return j.dump();
}
std::string sai_serialize_eni_ether_address_map_entry(
_In_ const sai_eni_ether_address_map_entry_t &eni_ether_address_map_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(eni_ether_address_map_entry.switch_id);
j["address"] = sai_serialize_mac(eni_ether_address_map_entry.address);
return j.dump();
}
std::string sai_serialize_vip_entry(
_In_ const sai_vip_entry_t &vip_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(vip_entry.switch_id);
j["vip"] = sai_serialize_ip_address(vip_entry.vip);
return j.dump();
}
std::string sai_serialize_inbound_routing_entry(
_In_ const sai_inbound_routing_entry_t &inbound_routing_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(inbound_routing_entry.switch_id);
j["eni_id"] = sai_serialize_object_id(inbound_routing_entry.eni_id);
j["vni"] = sai_serialize_number(inbound_routing_entry.vni);
j["sip"] = sai_serialize_ip_address(inbound_routing_entry.sip);
j["sip_mask"] = sai_serialize_ip_address(inbound_routing_entry.sip_mask);
j["priority"] = sai_serialize_number(inbound_routing_entry.priority);
return j.dump();
}
std::string sai_serialize_pa_validation_entry(
_In_ const sai_pa_validation_entry_t &pa_validation_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(pa_validation_entry.switch_id);
j["vnet_id"] = sai_serialize_object_id(pa_validation_entry.vnet_id);
j["sip"] = sai_serialize_ip_address(pa_validation_entry.sip);
return j.dump();
}
std::string sai_serialize_outbound_routing_entry(
_In_ const sai_outbound_routing_entry_t &outbound_routing_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(outbound_routing_entry.switch_id);
j["destination"] = sai_serialize_ip_prefix(outbound_routing_entry.destination);
j["outbound_routing_group_id"] = sai_serialize_object_id(outbound_routing_entry.outbound_routing_group_id);
return j.dump();
}
std::string sai_serialize_outbound_ca_to_pa_entry(
_In_ const sai_outbound_ca_to_pa_entry_t &outbound_ca_to_pa_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(outbound_ca_to_pa_entry.switch_id);
j["dst_vnet_id"] = sai_serialize_object_id(outbound_ca_to_pa_entry.dst_vnet_id);
j["dip"] = sai_serialize_ip_address(outbound_ca_to_pa_entry.dip);
return j.dump();
}
std::string sai_serialize_system_port_config(
_In_ const sai_attr_metadata_t &meta,
_In_ const sai_system_port_config_t &sysportconfig)
{
SWSS_LOG_ENTER();
json j;
j["port_id"] = sai_serialize_number(sysportconfig.port_id, false);
j["attached_switch_id"] = sai_serialize_number(sysportconfig.attached_switch_id, false);
j["attached_core_index"] = sai_serialize_number(sysportconfig.attached_core_index, false);
j["attached_core_port_index"] = sai_serialize_number(sysportconfig.attached_core_port_index, false);
j["speed"] = sai_serialize_number(sysportconfig.speed, false);
j["num_voq"] = sai_serialize_number(sysportconfig.num_voq, false);
return j.dump();
}
std::string sai_serialize_json(
_In_ const sai_json_t js)
{
SWSS_LOG_ENTER();
json j;
j["json"] = sai_serialize_number_list(js.json, false);
return j.dump();
}
json sai_serialize_system_port_cfg_list_item(
_In_ const sai_system_port_config_t &sysportconfig)
{
SWSS_LOG_ENTER();
json j;
j["port_id"] = sai_serialize_number(sysportconfig.port_id, false);
j["attached_switch_id"] = sai_serialize_number(sysportconfig.attached_switch_id, false);
j["attached_core_index"] = sai_serialize_number(sysportconfig.attached_core_index, false);
j["attached_core_port_index"] = sai_serialize_number(sysportconfig.attached_core_port_index, false);
j["speed"] = sai_serialize_number(sysportconfig.speed, false);
j["num_voq"] = sai_serialize_number(sysportconfig.num_voq, false);
return j;
}
std::string sai_serialize_system_port_config_list(
_In_ const sai_attr_metadata_t &meta,
_In_ const sai_system_port_config_list_t& sysportconfiglist,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j;
j["count"] = sysportconfiglist.count;
if (sysportconfiglist.list == NULL || countOnly)
{
j["list"] = nullptr;
return j.dump();
}
json arr = json::array();
for (uint32_t i = 0; i < sysportconfiglist.count; ++i)
{
json item = sai_serialize_system_port_cfg_list_item(sysportconfiglist.list[i]);
arr.push_back(item);
}
j["list"] = arr;
return j.dump();
}
std::string sai_serialize_segment_list(
_In_ const sai_segment_list_t& segmentlist,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
std::string s = sai_serialize_number(segmentlist.count);
if (countOnly)
{
return s;
}
if (segmentlist.list == NULL || segmentlist.count == 0)
{
return s + ":null";
}
std::string l;
for (uint32_t i = 0; i < segmentlist.count; ++i)
{
l += sai_serialize_ipv6(segmentlist.list[i]);
if (i != segmentlist.count -1)
{
l += ",";
}
}
return s + ":" + l;
}
std::string sai_serialize_attr_value(
_In_ const sai_attr_metadata_t& meta,
_In_ const sai_attribute_t &attr,
_In_ const bool countOnly)
{
SWSS_LOG_ENTER();
switch (meta.attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_BOOL:
return sai_serialize_bool(attr.value.booldata);
case SAI_ATTR_VALUE_TYPE_CHARDATA:
return sai_serialize_chardata(attr.value.chardata);
case SAI_ATTR_VALUE_TYPE_UINT8:
return sai_serialize_number(attr.value.u8);
case SAI_ATTR_VALUE_TYPE_INT8:
return sai_serialize_number(attr.value.s8);
case SAI_ATTR_VALUE_TYPE_UINT16:
return sai_serialize_number(attr.value.u16);
case SAI_ATTR_VALUE_TYPE_JSON:
return sai_serialize_json(attr.value.json);
case SAI_ATTR_VALUE_TYPE_INT16:
return sai_serialize_number(attr.value.s16);
case SAI_ATTR_VALUE_TYPE_UINT32:
return sai_serialize_number(attr.value.u32);
case SAI_ATTR_VALUE_TYPE_INT32:
return sai_serialize_enum(attr.value.s32, meta.enummetadata);
case SAI_ATTR_VALUE_TYPE_UINT64:
return sai_serialize_number(attr.value.u64);
// case SAI_ATTR_VALUE_TYPE_INT64:
// return sai_serialize_number(attr.value.s64);
case SAI_ATTR_VALUE_TYPE_MAC:
return sai_serialize_mac(attr.value.mac);
case SAI_ATTR_VALUE_TYPE_IPV4:
return sai_serialize_ipv4(attr.value.ip4);
case SAI_ATTR_VALUE_TYPE_IPV6:
return sai_serialize_ipv6(attr.value.ip6);
case SAI_ATTR_VALUE_TYPE_POINTER:
return sai_serialize_pointer(attr.value.ptr);
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS:
return sai_serialize_ip_address(attr.value.ipaddr);
case SAI_ATTR_VALUE_TYPE_IP_PREFIX:
return sai_serialize_ip_prefix(attr.value.ipprefix);
case SAI_ATTR_VALUE_TYPE_OBJECT_ID:
return sai_serialize_object_id(attr.value.oid);
case SAI_ATTR_VALUE_TYPE_OBJECT_LIST:
return sai_serialize_oid_list(attr.value.objlist, countOnly);
case SAI_ATTR_VALUE_TYPE_UINT8_LIST:
return sai_serialize_number_list(attr.value.u8list, countOnly);
case SAI_ATTR_VALUE_TYPE_INT8_LIST:
return sai_serialize_number_list(attr.value.s8list, countOnly);
case SAI_ATTR_VALUE_TYPE_LATCH_STATUS:
return sai_serialize_latch_status(attr.value.latchstatus);
case SAI_ATTR_VALUE_TYPE_PORT_LANE_LATCH_STATUS_LIST:
return sai_serialize_port_lane_latch_status_list(attr.value.portlanelatchstatuslist, countOnly);
// case SAI_ATTR_VALUE_TYPE_UINT16_LIST:
// return sai_serialize_number_list(attr.value.u16list, countOnly);
//
// case SAI_ATTR_VALUE_TYPE_INT16_LIST:
// return sai_serialize_number_list(attr.value.s16list, countOnly);
case SAI_ATTR_VALUE_TYPE_UINT32_LIST:
return sai_serialize_number_list(attr.value.u32list, countOnly);
case SAI_ATTR_VALUE_TYPE_INT32_LIST:
return sai_serialize_enum_list(attr.value.s32list, meta.enummetadata, countOnly);
case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
return sai_serialize_range(attr.value.u32range);
// case SAI_ATTR_VALUE_TYPE_INT32_RANGE:
// return sai_serialize_range(attr.value.s32range);
case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST:
return sai_serialize_u16_range_list(attr.value.u16rangelist, countOnly);
case SAI_ATTR_VALUE_TYPE_VLAN_LIST:
return sai_serialize_number_list(attr.value.vlanlist, countOnly);
case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST:
return sai_serialize_qos_map_list(attr.value.qosmap, countOnly);
case SAI_ATTR_VALUE_TYPE_MAP_LIST:
return sai_serialize_map_list(attr.value.maplist, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST:
return sai_serialize_acl_resource_list(attr.value.aclresource, countOnly);
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST:
return sai_serialize_ip_address_list(attr.value.ipaddrlist, countOnly);
case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST:
return sai_serialize_segment_list(attr.value.segmentlist, countOnly);
// ACL FIELD DATA
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:
return sai_serialize_acl_field(meta, attr.value.aclfield, countOnly);
// ACL ACTION DATA
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS:
return sai_serialize_acl_action(meta, attr.value.aclaction, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY:
return sai_serialize_acl_capability(meta, attr.value.aclcapability, countOnly);
// MACsec Attributions
case SAI_ATTR_VALUE_TYPE_MACSEC_SAK:
return sai_serialize_hex_binary(attr.value.macsecsak);
case SAI_ATTR_VALUE_TYPE_MACSEC_AUTH_KEY:
return sai_serialize_hex_binary(attr.value.macsecauthkey);
case SAI_ATTR_VALUE_TYPE_MACSEC_SALT:
return sai_serialize_hex_binary(attr.value.macsecsalt);
case SAI_ATTR_VALUE_TYPE_AUTH_KEY:
return sai_serialize_hex_binary(attr.value.authkey);
case SAI_ATTR_VALUE_TYPE_ENCRYPT_KEY:
return sai_serialize_hex_binary(attr.value.encrypt_key);
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG:
return sai_serialize_system_port_config(meta, attr.value.sysportconfig);
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST:
return sai_serialize_system_port_config_list(meta, attr.value.sysportconfiglist, countOnly);
case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST:
return sai_serialize_ip_prefix_list(attr.value.ipprefixlist, countOnly);
case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION:
return sai_serialize_poe_port_power_consumption(attr.value.portpowerconsumption);
default:
SWSS_LOG_THROW("sai attr value type %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
}
}
std::string sai_serialize_ip_prefix(
_In_ const sai_ip_prefix_t& prefix)
{
SWSS_LOG_ENTER();
switch (prefix.addr_family)
{
case SAI_IP_ADDR_FAMILY_IPV4:
return sai_serialize_ipv4(prefix.addr.ip4) + "/" + sai_serialize_number((get_ipv4_mask(prefix.mask.ip4)));
case SAI_IP_ADDR_FAMILY_IPV6:
return sai_serialize_ipv6(prefix.addr.ip6) + "/" + sai_serialize_number(get_ipv6_mask(prefix.mask.ip6));
default:
SWSS_LOG_THROW("FATAL: invalid ip prefix address family: %d", prefix.addr_family);
}
}
std::string sai_serialize_port_oper_status(
_In_ sai_port_oper_status_t status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(status, &sai_metadata_enum_sai_port_oper_status_t);
}
std::string sai_serialize_port_error_status(
_In_ sai_port_error_status_t status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(status, &sai_metadata_enum_sai_port_error_status_t);
}
std::string sai_serialize_port_host_tx_ready(
_In_ sai_port_host_tx_ready_status_t host_tx_ready_status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(host_tx_ready_status, &sai_metadata_enum_sai_port_host_tx_ready_status_t);
}
std::string sai_serialize_queue_deadlock_event(
_In_ sai_queue_pfc_deadlock_event_type_t event)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(event, &sai_metadata_enum_sai_queue_pfc_deadlock_event_type_t);
}
std::string sai_serialize_fdb_event(
_In_ sai_fdb_event_t event)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(event, &sai_metadata_enum_sai_fdb_event_t);
}
static json sai_serialize_json_fdb_event_notification_data(
_In_ const sai_fdb_event_notification_data_t& fdb_event)
{
SWSS_LOG_ENTER();
json j;
j["fdb_event"] = sai_serialize_fdb_event(fdb_event.event_type);
j["fdb_entry"] = sai_serialize_fdb_entry(fdb_event.fdb_entry);
json arr = json::array();
for (uint32_t i = 0; i < fdb_event.attr_count; ++i)
{
auto meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_FDB_ENTRY, fdb_event.attr[i].id);
if (meta == NULL)
{
SWSS_LOG_THROW("unable to get metadata for object type %s, attribute %d",
sai_serialize_object_type(SAI_OBJECT_TYPE_FDB_ENTRY).c_str(),
fdb_event.attr[i].id);
}
json item;
item["id"] = meta->attridname;
item["value"] = sai_serialize_attr_value(*meta, fdb_event.attr[i]);
arr.push_back(item);
}
j["list"] = arr;
// we don't need count since it can be deduced
return j;
}
std::string sai_serialize_nat_event(
_In_ sai_nat_event_t event)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(event, &sai_metadata_enum_sai_nat_event_t);
}
static json sai_serialize_json_nat_event_notification_data(
_In_ const sai_nat_event_notification_data_t& nat_event)
{
SWSS_LOG_ENTER();
json j;
j["nat_event"] = sai_serialize_nat_event(nat_event.event_type);
j["nat_entry"] = sai_serialize_nat_entry(nat_event.nat_entry);
// we don't need count since it can be deduced
return j;
}
std::string sai_serialize_bfd_session_state(
_In_ sai_bfd_session_state_t status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(status, &sai_metadata_enum_sai_bfd_session_state_t);
}
std::string sai_serialize_twamp_session_state(
_In_ sai_twamp_session_state_t status)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(status, &sai_metadata_enum_sai_twamp_session_state_t);
}
std::string sai_serialize_twamp_session_stat(
_In_ sai_twamp_session_stat_t counter)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(counter, &sai_metadata_enum_sai_twamp_session_stat_t);
}
static json sai_serialize_json_twamp_session_event_notification_data(
_In_ const sai_twamp_session_event_notification_data_t& twamp_session_data)
{
SWSS_LOG_ENTER();
json j;
j["twamp_session_id"] = sai_serialize_object_id(twamp_session_data.twamp_session_id);
j["session_state"] = sai_serialize_twamp_session_state(twamp_session_data.session_state);
j["index"] = sai_serialize_number(twamp_session_data.session_stats.index);
json arr = json::array();
for (uint32_t i = 0; i < twamp_session_data.session_stats.number_of_counters; ++i)
{
json item;
item["counters_ids"] = sai_serialize_twamp_session_stat(twamp_session_data.session_stats.counters_ids[i]);
item["counters"] = sai_serialize_number(twamp_session_data.session_stats.counters[i]);
arr.push_back(item);
}
j["list"] = arr;
// we don't need count since it can be deduced
return j;
}
std::string sai_serialize_fdb_event_ntf(
_In_ uint32_t count,
_In_ const sai_fdb_event_notification_data_t* fdb_event)
{
SWSS_LOG_ENTER();
if (fdb_event == NULL)
{
SWSS_LOG_THROW("fdb_event pointer is null");
}
json j = json::array();
for (uint32_t i = 0; i < count; ++i)
{
json item = sai_serialize_json_fdb_event_notification_data(fdb_event[i]);
j.push_back(item);
}
// we don't need count since it can be deduced
return j.dump();
}
std::string sai_serialize_nat_event_ntf(
_In_ uint32_t count,
_In_ const sai_nat_event_notification_data_t* nat_event)
{
SWSS_LOG_ENTER();
if (nat_event == NULL)
{
SWSS_LOG_THROW("nat_event pointer is null");
}
json j = json::array();
for (uint32_t i = 0; i < count; ++i)
{
json item = sai_serialize_json_nat_event_notification_data(nat_event[i]);
j.push_back(item);
}
// we don't need count since it can be deduced
return j.dump();
}
std::string sai_serialize_port_oper_status_ntf(
_In_ uint32_t count,
_In_ const sai_port_oper_status_notification_t* port_oper_status)
{
SWSS_LOG_ENTER();
if (port_oper_status == NULL)
{
SWSS_LOG_THROW("port_oper_status pointer is null");
}
json j = json::array();
for (uint32_t i = 0; i < count; ++i)
{
json item;
item["port_id"] = sai_serialize_object_id(port_oper_status[i].port_id);
item["port_state"] = sai_serialize_port_oper_status(port_oper_status[i].port_state);
item["port_error_status"] = sai_serialize_port_error_status(port_oper_status[i].port_error_status);
j.push_back(item);
}
// we don't need count since it can be deduced
return j.dump();
}
std::string sai_serialize_port_host_tx_ready_ntf(
_In_ sai_object_id_t switch_id,
_In_ sai_object_id_t port_id,
_In_ sai_port_host_tx_ready_status_t host_tx_ready_status)
{
SWSS_LOG_ENTER();
json j = json::array();
json item;
item["port_id"] = sai_serialize_object_id(port_id);
item["switch_id"] = sai_serialize_object_id(switch_id);
item["host_tx_ready_status"] = sai_serialize_port_host_tx_ready_status(host_tx_ready_status);
j.push_back(item);
return j.dump();
}
std::string sai_serialize_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ const sai_queue_deadlock_notification_data_t* deadlock_data)
{
SWSS_LOG_ENTER();
if (deadlock_data == NULL)
{
SWSS_LOG_THROW("deadlock_data pointer is null");
}
json j = json::array();
for (uint32_t i = 0; i < count; ++i)
{
json item;
item["queue_id"] = sai_serialize_object_id(deadlock_data[i].queue_id);
item["event"] = sai_serialize_queue_deadlock_event(deadlock_data[i].event);
j.push_back(item);
}
// we don't need count since it can be deduced
return j.dump();
}
std::string sai_serialize_bfd_session_state_ntf(
_In_ uint32_t count,
_In_ const sai_bfd_session_state_notification_t* bfd_session_state)
{
SWSS_LOG_ENTER();
if (bfd_session_state == NULL)
{
SWSS_LOG_THROW("bfd_session_state pointer is null");
}
json j = json::array();
for (uint32_t i = 0; i < count; ++i)
{
json item;
item["bfd_session_id"] = sai_serialize_object_id(bfd_session_state[i].bfd_session_id);
item["session_state"] = sai_serialize_bfd_session_state(bfd_session_state[i].session_state);
j.push_back(item);
}
// we don't need count since it can be deduced
return j.dump();
}
std::string sai_serialize_twamp_session_event_ntf(
_In_ uint32_t count,
_In_ const sai_twamp_session_event_notification_data_t* twamp_session_event)
{
SWSS_LOG_ENTER();
if (twamp_session_event == NULL)
{
SWSS_LOG_THROW("twamp_session_state pointer is null");
}
json j = json::array();
for (uint32_t i = 0; i < count; ++i)
{
json item = sai_serialize_json_twamp_session_event_notification_data(twamp_session_event[i]);
j.push_back(item);
}
// we don't need count since it can be deduced
return j.dump();
}
json sai_serialize_nat_entry_key(
_In_ const sai_nat_entry_key_t& nat_entry_key)
{
SWSS_LOG_ENTER();
json j;
j["src_ip"] = sai_serialize_ipv4(nat_entry_key.src_ip);
j["dst_ip"] = sai_serialize_ipv4(nat_entry_key.dst_ip);
j["proto"] = sai_serialize_number(nat_entry_key.proto);
j["l4_src_port"] = sai_serialize_number(nat_entry_key.l4_src_port);
j["l4_dst_port"] = sai_serialize_number(nat_entry_key.l4_dst_port);
return j;
}
json sai_serialize_nat_entry_mask(
_In_ const sai_nat_entry_mask_t& nat_entry_mask)
{
SWSS_LOG_ENTER();
json j;
j["src_ip"] = sai_serialize_ipv4(nat_entry_mask.src_ip);
j["dst_ip"] = sai_serialize_ipv4(nat_entry_mask.dst_ip);
j["proto"] = sai_serialize_number(nat_entry_mask.proto);
j["l4_src_port"] = sai_serialize_number(nat_entry_mask.l4_src_port);
j["l4_dst_port"] = sai_serialize_number(nat_entry_mask.l4_dst_port);
return j;
}
json sai_serialize_nat_entry_data(
_In_ const sai_nat_entry_data_t& nat_entry_data)
{
SWSS_LOG_ENTER();
json j;
j["key"] = sai_serialize_nat_entry_key(nat_entry_data.key);
j["mask"] = sai_serialize_nat_entry_mask(nat_entry_data.mask);
return j;
}
std::string sai_serialize_nat_entry_type(
_In_ const sai_nat_type_t type)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(type, &sai_metadata_enum_sai_nat_type_t);
}
std::string sai_serialize_nat_entry(
_In_ const sai_nat_entry_t& nat_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(nat_entry.switch_id);
j["vr"] = sai_serialize_object_id(nat_entry.vr_id);
j["nat_type"] = sai_serialize_nat_entry_type(nat_entry.nat_type);
j["nat_data"] = sai_serialize_nat_entry_data(nat_entry.data);
return j.dump();
}
std::string sai_serialize_my_sid_entry(
_In_ const sai_my_sid_entry_t& my_sid_entry)
{
SWSS_LOG_ENTER();
json j;
j["switch_id"] = sai_serialize_object_id(my_sid_entry.switch_id);
j["vr_id"] = sai_serialize_object_id(my_sid_entry.vr_id);
j["locator_block_len"] = sai_serialize_number(my_sid_entry.locator_block_len);
j["locator_node_len"] = sai_serialize_number(my_sid_entry.locator_node_len);
j["function_len"] = sai_serialize_number(my_sid_entry.function_len);
j["args_len"] = sai_serialize_number(my_sid_entry.args_len);
j["sid"] = sai_serialize_ipv6(my_sid_entry.sid);
return j.dump();
}
static bool sai_serialize_object_entry(
_In_ const sai_object_type_t objecttype,
_In_ const sai_object_key_entry_t& key_entry,
_Out_ std::string& key)
{
SWSS_LOG_ENTER();
switch (objecttype)
{
case SAI_OBJECT_TYPE_FDB_ENTRY:
key = sai_serialize_fdb_entry(key_entry.fdb_entry);
return true;
case SAI_OBJECT_TYPE_ROUTE_ENTRY:
key = sai_serialize_route_entry(key_entry.route_entry);
return true;
case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
key = sai_serialize_neighbor_entry(key_entry.neighbor_entry);
return true;
case SAI_OBJECT_TYPE_NAT_ENTRY:
key = sai_serialize_nat_entry(key_entry.nat_entry);
return true;
case SAI_OBJECT_TYPE_INSEG_ENTRY:
key = sai_serialize_inseg_entry(key_entry.inseg_entry);
return true;
case SAI_OBJECT_TYPE_MY_SID_ENTRY:
key = sai_serialize_my_sid_entry(key_entry.my_sid_entry);
return true;
case SAI_OBJECT_TYPE_L2MC_ENTRY:
key = sai_serialize_l2mc_entry(key_entry.l2mc_entry);
return true;
case SAI_OBJECT_TYPE_IPMC_ENTRY:
key = sai_serialize_ipmc_entry(key_entry.ipmc_entry);
return true;
case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY:
key = sai_serialize_mcast_fdb_entry(key_entry.mcast_fdb_entry);
return true;
default:
return false;
}
}
static bool sai_serialize_object_extension_entry(
_In_ const sai_object_type_extensions_t objecttype,
_In_ const sai_object_key_entry_t& key_entry,
_Out_ std::string& key)
{
SWSS_LOG_ENTER();
switch (objecttype)
{
case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
key = sai_serialize_direction_lookup_entry(key_entry.direction_lookup_entry);
return true;
case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
key = sai_serialize_eni_ether_address_map_entry(key_entry.eni_ether_address_map_entry);
return true;
case SAI_OBJECT_TYPE_VIP_ENTRY:
key = sai_serialize_vip_entry(key_entry.vip_entry);
return true;
case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
key = sai_serialize_inbound_routing_entry(key_entry.inbound_routing_entry);
return true;
case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
key = sai_serialize_pa_validation_entry(key_entry.pa_validation_entry);
return true;
case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
key = sai_serialize_outbound_routing_entry(key_entry.outbound_routing_entry);
return true;
case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
key = sai_serialize_outbound_ca_to_pa_entry(key_entry.outbound_ca_to_pa_entry);
return true;
case SAI_OBJECT_TYPE_FLOW_ENTRY:
key = sai_serialize_flow_entry(key_entry.flow_entry);
return true;
case SAI_OBJECT_TYPE_METER_BUCKET_ENTRY:
key = sai_serialize_meter_bucket_entry(key_entry.meter_bucket_entry);
return true;
default:
return false;
}
}
std::string sai_serialize_object_meta_key(
_In_ const sai_object_meta_key_t& meta_key)
{
SWSS_LOG_ENTER();
std::string key;
if (!sai_metadata_is_object_type_valid(meta_key.objecttype))
{
SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str());
}
if (!sai_serialize_object_entry(meta_key.objecttype, meta_key.objectkey.key, key) &&
!sai_serialize_object_extension_entry((sai_object_type_extensions_t)meta_key.objecttype, meta_key.objectkey.key, key))
{
const auto& meta = sai_metadata_get_object_type_info(meta_key.objecttype);
if (meta->isnonobjectid)
{
SWSS_LOG_THROW("object %s is non object id, not supported yet, FIXME",
sai_serialize_object_type(meta->objecttype).c_str());
}
key = sai_serialize_object_id(meta_key.objectkey.key.object_id);
}
key = sai_serialize_object_type(meta_key.objecttype) + ":" + key;
SWSS_LOG_DEBUG("%s", key.c_str());
return key;
}
std::string sai_serialize(
_In_ const sai_redis_notify_syncd_t& value)
{
SWSS_LOG_ENTER();
switch (value)
{
case SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW:
return SYNCD_INIT_VIEW;
case SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW:
return SYNCD_APPLY_VIEW;
case SAI_REDIS_NOTIFY_SYNCD_INSPECT_ASIC:
return SYNCD_INSPECT_ASIC;
case SAI_REDIS_NOTIFY_SYNCD_INVOKE_DUMP:
return SYNCD_INVOKE_DUMP;
default:
SWSS_LOG_THROW("unknown value on sai_redis_notify_syncd_t: %d", value);
}
}
std::string sai_serialize_redis_communication_mode(
_In_ sai_redis_communication_mode_t value)
{
SWSS_LOG_ENTER();
switch (value)
{
case SAI_REDIS_COMMUNICATION_MODE_REDIS_ASYNC:
return REDIS_COMMUNICATION_MODE_REDIS_ASYNC_STRING;
case SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC:
return REDIS_COMMUNICATION_MODE_REDIS_SYNC_STRING;
case SAI_REDIS_COMMUNICATION_MODE_ZMQ_SYNC:
return REDIS_COMMUNICATION_MODE_ZMQ_SYNC_STRING;
default:
SWSS_LOG_THROW("unknown value on sai_redis_communication_mode_t: %d", value);
}
}
std::string sai_serialize_redis_port_attr_id(
_In_ const sai_redis_port_attr_t value)
{
SWSS_LOG_ENTER();
auto it = sai_redis_port_attr_to_name_map.find(value);
if (it != sai_redis_port_attr_to_name_map.end())
{
return it->second;
}
SWSS_LOG_WARN("enum value %d not found in enum sai_redis_port_attr_t.", value);
return sai_serialize_number(value, false);
}
std::string sai_serialize_redis_link_event_damping_algorithm(
_In_ const sai_redis_link_event_damping_algorithm_t value)
{
SWSS_LOG_ENTER();
auto it = sai_redis_link_event_damping_algorithm_to_name_map.find(value);
if (it != sai_redis_link_event_damping_algorithm_to_name_map.end())
{
return it->second;
}
SWSS_LOG_WARN("enum value %d not found in enum sai_redis_link_event_damping_algorithm_t.", value);
return sai_serialize_number(value, false);
}
std::string sai_serialize_redis_link_event_damping_aied_config(
_In_ const sai_redis_link_event_damping_algo_aied_config_t& value)
{
SWSS_LOG_ENTER();
json j;
j["max_suppress_time"] = sai_serialize_number(value.max_suppress_time, false);
j["suppress_threshold"] = sai_serialize_number(value.suppress_threshold, false);
j["reuse_threshold"] = sai_serialize_number(value.reuse_threshold, false);
j["decay_half_life"] = sai_serialize_number(value.decay_half_life, false);
j["flap_penalty"] = sai_serialize_number(value.flap_penalty, false);
return j.dump();
}
json sai_serialize_stat_capability(
_In_ const sai_stat_capability_t& stat_capability,
_In_ const sai_enum_metadata_t* meta)
{
SWSS_LOG_ENTER();
json j;
j["stat_enum"] = sai_serialize_enum(stat_capability.stat_enum, meta);
json arr = json::array();
for (uint32_t i = 0; i < sai_metadata_enum_sai_stats_mode_t.valuescount; ++i)
{
if (stat_capability.stat_modes & sai_metadata_enum_sai_stats_mode_t.values[i])
{
json item = sai_serialize_enum(sai_metadata_enum_sai_stats_mode_t.values[i],
&sai_metadata_enum_sai_stats_mode_t);
arr.push_back(item);
}
}
j["stat_modes"] = arr;
return j;
}
std::string sai_serialize_stats_capability_list(
_In_ const sai_stat_capability_list_t& stat_capability_list,
_In_ const sai_enum_metadata_t* meta,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j;
j["count"] = stat_capability_list.count;
if (stat_capability_list.list == NULL || countOnly)
{
j["list"] = nullptr;
return j.dump();
}
json arr = json::array();
for (uint32_t i = 0; i < stat_capability_list.count; ++i)
{
json item = sai_serialize_stat_capability(stat_capability_list.list[i], meta);
arr.push_back(item);
}
j["list"] = arr;
return j.dump();
}
std::string sai_serialize_poe_port_active_channel_type(
_In_ const sai_poe_port_active_channel_type_t value)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(value, &sai_metadata_enum_sai_poe_port_active_channel_type_t);
}
std::string sai_serialize_poe_port_class_method_type(
_In_ const sai_poe_port_class_method_type_t value)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(value, &sai_metadata_enum_sai_poe_port_class_method_type_t);
}
std::string sai_serialzie_poe_port_signature_type(
_In_ const sai_poe_port_signature_type_t value)
{
SWSS_LOG_ENTER();
return sai_serialize_enum(value, &sai_metadata_enum_sai_poe_port_signature_type_t);
}
std::string sai_serialize_poe_port_power_consumption(
_In_ const sai_poe_port_power_consumption_t& value)
{
SWSS_LOG_ENTER();
json j;
j["active_channel"] = sai_serialize_poe_port_active_channel_type(value.active_channel);
j["voltage"] = sai_serialize_number(value.voltage, false);
j["current"] = sai_serialize_number(value.current, false);
j["consumption"] = sai_serialize_number(value.consumption, false);
j["signature_type"] = sai_serialzie_poe_port_signature_type(value.signature_type);
j["class_method"] = sai_serialize_poe_port_class_method_type(value.class_method);
j["measured_class_a"] = sai_serialize_number(value.measured_class_a, false);
j["assigned_class_a"] = sai_serialize_number(value.assigned_class_a, false);
j["measured_class_b"] = sai_serialize_number(value.measured_class_b, false);
j["assigned_class_b"] = sai_serialize_number(value.assigned_class_b, false);
return j.dump();
}
// deserialize
void sai_deserialize_bool(
_In_ const std::string& s,
_Out_ bool& b)
{
SWSS_LOG_ENTER();
if (s == "true")
{
b = true;
return;
}
if (s == "false")
{
b = false;
return;
}
SWSS_LOG_THROW("failed to deserialize '%s' as bool", s.c_str());
}
void sai_deserialize_chardata(
_In_ const std::string& s,
_Out_ char chardata[CHAR_LEN])
{
SWSS_LOG_ENTER();
memset(chardata, 0, CHAR_LEN);
std::string deserialized;
size_t len = s.length();
for (size_t i = 0; i < len; ++i)
{
unsigned char c = (unsigned char)s[i];
if (c == '\\')
{
if (i+1 >= len || ((s[i+1] != '\\') && (s[i+1] != 'x')))
{
SWSS_LOG_THROW("invalid chardata %s", s.c_str());
}
if (s[i+1] == '\\')
{
deserialized += "\\";
i++;
continue;
}
i++;
if (i + 2 >= len)
{
SWSS_LOG_THROW("invalid chardata %s", s.c_str());
}
int h = char_to_int(s[i+1]);
int l = char_to_int(s[i+2]);
int r = (h << 4) | l;
c = (unsigned char)r;
i += 2;
}
deserialized += c;
}
len = deserialized.length();
if (len > CHAR_LEN)
{
SWSS_LOG_THROW("invalid chardata %s", s.c_str());
}
memcpy(chardata, deserialized.data(), len);
}
template<typename T>
void sai_deserialize_number(
_In_ const std::string& s,
_Out_ T& number,
_In_ bool hex = false)
{
SWSS_LOG_ENTER();
errno = 0;
char *endptr = NULL;
number = (T)strtoull(s.c_str(), &endptr, hex ? 16 : 10);
if (errno != 0 || endptr != s.c_str() + s.length())
{
SWSS_LOG_THROW("invalid number %s", s.c_str());
}
}
void sai_deserialize_number(
_In_ const std::string& s,
_Out_ uint32_t& number,
_In_ bool hex)
{
SWSS_LOG_ENTER();
sai_deserialize_number<uint32_t>(s, number, hex);
}
void sai_deserialize_enum(
_In_ const std::string& s,
_In_ const sai_enum_metadata_t *meta,
_Out_ int32_t& value)
{
SWSS_LOG_ENTER();
if (meta == NULL)
{
return sai_deserialize_number(s, value);
}
for (size_t i = 0; i < meta->valuescount; ++i)
{
if (strcmp(s.c_str(), meta->valuesnames[i]) == 0)
{
value = meta->values[i];
return;
}
}
// check depreacated values if present
if (meta->ignorevaluesnames)
{
// this can happen when we deserialize older SAI values
for (size_t i = 0; meta->ignorevaluesnames[i] != NULL; i++)
{
if (strcmp(s.c_str(), meta->ignorevaluesnames[i]) == 0)
{
SWSS_LOG_NOTICE("translating depreacated/ignored enum value: %s", s.c_str());
value = meta->ignorevalues[i];
return;
}
}
}
SWSS_LOG_WARN("enum %s not found in enum %s", s.c_str(), meta->name);
sai_deserialize_number(s, value);
}
void sai_deserialize_mac(
_In_ const std::string& s,
_Out_ sai_mac_t& mac)
{
SWSS_LOG_ENTER();
if (s.length() != (6*2+5))
{
SWSS_LOG_THROW("invalid mac address %s", s.c_str());
}
int i = 0;
for (int j = 0; j < 6 ; j++, i += 3)
{
int h = char_to_int(s[i+0]);
int l = char_to_int(s[i+1]);
int r = (h << 4) | l;
mac[j] = (unsigned char)r;
}
}
void sai_deserialize_object_id(
_In_ const std::string& s,
_Out_ sai_object_id_t& oid)
{
SWSS_LOG_ENTER();
if (s.find("oid:0x") != 0)
{
SWSS_LOG_THROW("invalid oid %s", s.c_str());
}
errno = 0;
char *endptr = NULL;
oid = (sai_object_id_t)strtoull(s.c_str()+4, &endptr, 16);
if (errno != 0 || endptr != s.c_str() + s.length())
{
SWSS_LOG_THROW("invalid oid %s", s.c_str());
}
}
template<typename T, typename F>
void sai_deserialize_list(
_In_ const std::string& s,
_Out_ T& list,
_In_ bool countOnly,
F deserialize_item)
{
SWSS_LOG_ENTER();
if (countOnly)
{
sai_deserialize_number(s, list.count);
return;
}
auto pos = s.find(":");
if (pos == std::string::npos)
{
SWSS_LOG_THROW("invalid list %s", s.c_str());
}
std::string scount = s.substr(0, pos);
sai_deserialize_number(scount, list.count);
std::string slist = s.substr(pos + 1);
if (slist == "null")
{
list.list = NULL;
return;
}
auto tokens = swss::tokenize(slist, ',');
if (tokens.size() != list.count)
{
SWSS_LOG_THROW("invalid list count %lu != %u", tokens.size(), list.count);
}
// list.list = sai_alloc_list(list.count, list);
list.list = sai_alloc_n_of_ptr_type(list.count, list.list);
for (uint32_t i = 0; i < list.count; ++i)
{
deserialize_item(tokens[i], list.list[i]);
}
}
void sai_deserialize_oid_list(
_In_ const std::string& s,
_Out_ sai_object_list_t& objlist,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
sai_deserialize_list(s, objlist, countOnly, [&](const std::string sitem, sai_object_id_t& item) { sai_deserialize_object_id(sitem, item);} );
}
void sai_deserialize_enum_list(
_In_ const std::string& s,
_In_ const sai_enum_metadata_t* meta,
_Out_ sai_s32_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
sai_deserialize_list(s, list, countOnly, [&](const std::string sitem, int32_t& item) { sai_deserialize_enum(sitem, meta, item);} );
}
template <typename T>
void sai_deserialize_number_list(
_In_ const std::string& s,
_Out_ T& list,
_In_ bool countOnly,
_In_ bool hex = false)
{
SWSS_LOG_ENTER();
sai_deserialize_list(s, list, countOnly, [&](const std::string sitem, decltype(*list.list)& item) { sai_deserialize_number(sitem, item, hex);} );
}
void sai_deserialize_packet_color(
_In_ const std::string& s,
_Out_ sai_packet_color_t& color)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_packet_color_t, (int32_t&)color);
}
static void sai_deserialize_qos_map_params(
_In_ const json& j,
_Out_ sai_qos_map_params_t& params)
{
SWSS_LOG_ENTER();
params.tc = j["tc"];
params.dscp = j["dscp"];
params.dot1p = j["dot1p"];
params.prio = j["prio"];
params.pg = j["pg"];
params.queue_index = j["qidx"];
if (j.find("mpls_exp") == j.end())
{
// for backward compatibility
params.mpls_exp = 0;
}
else
{
params.mpls_exp = j["mpls_exp"];
}
if (j.find("fc") == j.end())
{
// for backward compatibility
params.fc = 0;
}
else
{
params.fc = j["fc"];
}
sai_deserialize_packet_color(j["color"], params.color);
}
static void sai_deserialize_qos_map(
_In_ const json& j,
_Out_ sai_qos_map_t& qosmap)
{
SWSS_LOG_ENTER();
sai_deserialize_qos_map_params(j["key"], qosmap.key);
sai_deserialize_qos_map_params(j["value"], qosmap.value);
}
void sai_deserialize_map(
_In_ const json &j,
_Out_ sai_map_t &map)
{
SWSS_LOG_ENTER();
map.key = j["key"];
map.value = j["value"];
}
void sai_deserialize_qos_map_list(
_In_ const std::string& s,
_Out_ sai_qos_map_list_t& qosmap,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
qosmap.count = j["count"];
if (countOnly)
{
return;
}
if (j["list"] == nullptr)
{
qosmap.list = NULL;
return;
}
json arr = j["list"];
if (arr.size() != (size_t)qosmap.count)
{
SWSS_LOG_THROW("qos map count mismatch %lu vs %u", arr.size(), qosmap.count);
}
qosmap.list = sai_alloc_n_of_ptr_type(qosmap.count, qosmap.list);
for (uint32_t i = 0; i < qosmap.count; ++i)
{
const json& item = arr[i];
sai_deserialize_qos_map(item, qosmap.list[i]);
}
}
void sai_deserialize_map_list(
_In_ const std::string &s,
_Out_ sai_map_list_t &maplist,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
maplist.count = j["count"];
if (countOnly)
{
return;
}
if (j["list"] == nullptr)
{
maplist.list = NULL;
return;
}
json arr = j["list"];
if (arr.size() != (size_t)maplist.count)
{
SWSS_LOG_THROW("map list count mismatch %lu vs %u", arr.size(), maplist.count);
}
maplist.list = sai_alloc_n_of_ptr_type(maplist.count, maplist.list);
for (uint32_t i = 0; i < maplist.count; ++i)
{
const json &item = arr[i];
sai_deserialize_map(item, maplist.list[i]);
}
}
void sai_deserialize_acl_stage(
_In_ const std::string& s,
_Out_ sai_acl_stage_t& stage)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_acl_stage_t, (int32_t&)stage);
}
void sai_deserialize_acl_bind_point(
_In_ const std::string& s,
_Out_ sai_acl_bind_point_type_t& bind_point)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_acl_bind_point_type_t, (int32_t&)bind_point);
}
static void sai_deserialize_acl_resource(
_In_ const json& j,
_Out_ sai_acl_resource_t& aclresource)
{
SWSS_LOG_ENTER();
sai_deserialize_acl_stage(j["stage"], aclresource.stage);
sai_deserialize_acl_bind_point(j["bind_point"], aclresource.bind_point);
sai_deserialize_number(j["avail_num"], aclresource.avail_num);
}
void sai_deserialize_acl_resource_list(
_In_ const std::string& s,
_Out_ sai_acl_resource_list_t& aclresource,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
aclresource.count = j["count"];
if (countOnly)
{
return;
}
if (j["list"] == nullptr)
{
aclresource.list = NULL;
return;
}
json arr = j["list"];
if (arr.size() != (size_t)aclresource.count)
{
SWSS_LOG_THROW("acl resource count mismatch %lu vs %u", arr.size(), aclresource.count);
}
aclresource.list = sai_alloc_n_of_ptr_type(aclresource.count, aclresource.list);
for (uint32_t i = 0; i < aclresource.count; ++i)
{
const json& item = arr[i];
sai_deserialize_acl_resource(item, aclresource.list[i]);
}
}
void sai_deserialize_ipv6(
_In_ const std::string& s,
_Out_ sai_ip6_t& ipaddr)
{
SWSS_LOG_ENTER();
if (inet_pton(AF_INET6, s.c_str(), ipaddr) != 1)
{
SWSS_LOG_THROW("invalid ip address %s", s.c_str());
}
}
void sai_deserialize_ipv4(
_In_ const std::string& s,
_Out_ sai_ip4_t& ipaddr)
{
SWSS_LOG_ENTER();
if (inet_pton(AF_INET, s.c_str(), &ipaddr) != 1)
{
SWSS_LOG_THROW("invalid ip address %s", s.c_str());
}
}
void sai_deserialize_pointer(
_In_ const std::string& s,
_Out_ sai_pointer_t& ptr)
{
SWSS_LOG_ENTER();
sai_deserialize_number(s, (uintptr_t &)ptr, true);
}
void sai_deserialize_ip_address(
_In_ const std::string& s,
_Out_ sai_ip_address_t& ipaddr)
{
SWSS_LOG_ENTER();
if (inet_pton(AF_INET, s.c_str(), &ipaddr.addr.ip4) == 1)
{
ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
return;
}
if (inet_pton(AF_INET6, s.c_str(), ipaddr.addr.ip6) == 1)
{
ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6;
return;
}
SWSS_LOG_THROW("invalid ip address %s", s.c_str());
}
void sai_deserialize_ip_prefix(
_In_ const std::string &s,
_Out_ sai_ip_prefix_t &ip_prefix)
{
SWSS_LOG_ENTER();
auto tokens = swss::tokenize(s, '/');
if (tokens.size() != 2)
{
SWSS_LOG_THROW("invalid ip prefix %s", s.c_str());
}
uint8_t mask;
sai_deserialize_number(tokens[1], mask);
const std::string &ip = tokens[0];
if (inet_pton(AF_INET, ip.c_str(), &ip_prefix.addr.ip4) == 1)
{
ip_prefix.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
sai_populate_ip_mask(mask, (uint8_t*)&ip_prefix.mask.ip4, false);
}
else if (inet_pton(AF_INET6, ip.c_str(), ip_prefix.addr.ip6) == 1)
{
ip_prefix.addr_family = SAI_IP_ADDR_FAMILY_IPV6;
sai_populate_ip_mask(mask, ip_prefix.mask.ip6, true);
}
else
{
SWSS_LOG_THROW("invalid ip prefix %s", s.c_str());
}
}
void sai_deserialize_ip_address_list(
_In_ const std::string& s,
_Out_ sai_ip_address_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
sai_deserialize_list(s, list, countOnly, [&](const std::string sitem, sai_ip_address_t& item) { sai_deserialize_ip_address(sitem, item);} );
}
void sai_deserialize_ip_prefix_list(
_In_ const std::string& s,
_Out_ sai_ip_prefix_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
sai_deserialize_list(s, list, countOnly, [&](const std::string sitem, sai_ip_prefix_t& item) { sai_deserialize_ip_prefix(sitem, item);} );
}
void sai_deserialize_segment_list(
_In_ const std::string& s,
_Out_ sai_segment_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (countOnly)
{
sai_deserialize_number(s, list.count);
return;
}
auto pos = s.find(":");
if (pos == std::string::npos)
{
SWSS_LOG_THROW("invalid list %s", s.c_str());
}
std::string scount = s.substr(0, pos);
sai_deserialize_number(scount, list.count);
std::string slist = s.substr(pos + 1);
if (slist == "null")
{
list.list = NULL;
return;
}
auto tokens = swss::tokenize(slist, ',');
if (tokens.size() != list.count)
{
SWSS_LOG_THROW("invalid list count %lu != %u", tokens.size(), list.count);
}
list.list = sai_alloc_n_of_ptr_type(list.count, list.list);
for (uint32_t i = 0; i < list.count; ++i)
{
sai_deserialize_ipv6(tokens[i], list.list[i]);
}
}
template <typename T>
void sai_deserialize_range(
_In_ const std::string& s,
_Out_ T& range)
{
SWSS_LOG_ENTER();
auto tokens = swss::tokenize(s, ',');
if (tokens.size() != 2)
{
SWSS_LOG_THROW("invalid range %s", s.c_str());
}
sai_deserialize_number(tokens[0], range.min);
sai_deserialize_number(tokens[1], range.max);
}
void sai_deserialize_u16_range_list(
_In_ const std::string& s,
_Out_ sai_u16_range_list_t& list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (countOnly)
{
sai_deserialize_number(s, list.count);
return;
}
auto pos = s.find(":");
if (pos == std::string::npos)
{
SWSS_LOG_THROW("invalid list %s", s.c_str());
}
std::string scount = s.substr(0, pos);
sai_deserialize_number(scount, list.count);
std::string slist = s.substr(pos + 1);
if (slist == "null")
{
list.list = NULL;
return;
}
auto tokens = swss::tokenize(slist, ',');
if (tokens.size() != list.count * 2)
{
SWSS_LOG_THROW("invalid u16_range_list count %lu != %u", tokens.size(), list.count * 2);
}
list.list = sai_alloc_n_of_ptr_type(list.count, list.list);
for (uint32_t i = 0; i < list.count * 2; i+=2)
{
std::ostringstream range;
range << tokens[i] << "," << tokens[i+1];
sai_deserialize_range(range.str(), list.list[i/2]);
}
}
void sai_deserialize_acl_field(
_In_ const std::string& s,
_In_ const sai_attr_metadata_t& meta,
_In_ sai_acl_field_data_t& field,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (s == "disabled")
{
field.enable = false;
return;
}
field.enable = true;
auto pos = s.find("&mask:");
std::string sfield;
std::string smask;
if (pos == std::string::npos)
{
sfield = s;
}
else
{
sfield = s.substr(0, pos);
smask = s.substr(pos + 6); // 6 = "&mask:" length
}
switch (meta.attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
return sai_deserialize_bool(sfield, field.data.booldata);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
sai_deserialize_number(sfield, field.data.u8);
sai_deserialize_number(smask, field.mask.u8, true);
return;
// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
// sai_deserialize_number(sfield, field.data.s8);
// sai_deserialize_number(smask, field.mask.s8, true);
// return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
sai_deserialize_number(sfield, field.data.u16);
sai_deserialize_number(smask, field.mask.u16, true);
return;
// case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
// sai_deserialize_number(sfield, field.data.s16);
// sai_deserialize_number(smask, field.mask.s16, true);
// return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
sai_deserialize_number(sfield, field.data.u32);
sai_deserialize_number(smask, field.mask.u32, true);
return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
sai_deserialize_enum(sfield, meta.enummetadata, field.data.s32);
sai_deserialize_number(smask, field.mask.s32, true);
return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
sai_deserialize_number(sfield, field.data.u64);
sai_deserialize_number(smask, field.mask.u64, true);
return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
sai_deserialize_mac(sfield, field.data.mac);
sai_deserialize_mac(smask, field.mask.mac);
return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
sai_deserialize_ipv4(sfield, field.data.ip4);
sai_deserialize_ipv4(smask, field.mask.ip4);
return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
sai_deserialize_ipv6(sfield, field.data.ip6);
sai_deserialize_ipv6(smask, field.mask.ip6);
return;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
return sai_deserialize_object_id(sfield, field.data.oid);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
return sai_deserialize_oid_list(sfield, field.data.objlist, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:
sai_deserialize_number_list(sfield, field.data.u8list, countOnly);
sai_deserialize_number_list(smask, field.mask.u8list, countOnly, true);
return;
default:
SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
}
}
void sai_deserialize_acl_action(
_In_ const std::string& s,
_In_ const sai_attr_metadata_t& meta,
_In_ sai_acl_action_data_t& action,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
if (s == "disabled")
{
action.enable = false;
return;
}
action.enable = true;
switch (meta.attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
return sai_deserialize_bool(s, action.parameter.booldata);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
return sai_deserialize_number(s, action.parameter.u8);
// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
// return sai_deserialize_number(s, action.parameter.s8);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
return sai_deserialize_number(s, action.parameter.u16);
// case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
// return sai_deserialize_number(s, action.parameter.s16);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
return sai_deserialize_number(s, action.parameter.u32);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
return sai_deserialize_enum(s, meta.enummetadata, action.parameter.s32);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
return sai_deserialize_mac(s, action.parameter.mac);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
return sai_deserialize_ipv4(s, action.parameter.ip4);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
return sai_deserialize_ipv6(s, action.parameter.ip6);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
return sai_deserialize_object_id(s, action.parameter.oid);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
return sai_deserialize_oid_list(s, action.parameter.objlist, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS:
sai_deserialize_ip_address(s, action.parameter.ipaddr);
return;
default:
SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
}
}
void sai_deserialize_acl_capability(
_In_ const std::string& s,
_Out_ sai_acl_capability_t& cap)
{
SWSS_LOG_ENTER();
auto pos = s.find(":");
if (pos == std::string::npos)
{
SWSS_LOG_THROW("Invalid acl capability %s", s.c_str());
}
auto mandatory_on_create_str = s.substr(0, pos);
auto list = s.substr(pos + 1);
sai_deserialize_bool(mandatory_on_create_str, cap.is_action_list_mandatory);
sai_deserialize_enum_list(list, &sai_metadata_enum_sai_acl_action_type_t, cap.action_list, false);
}
void sai_deserialize_hex_binary(
_In_ const std::string &s,
_Out_ void *buffer,
_In_ size_t length)
{
SWSS_LOG_ENTER();
if (s.length() % 2 != 0)
{
SWSS_LOG_THROW("Invalid hex string %s", s.c_str());
}
if (s.length() > (length * 2))
{
SWSS_LOG_THROW("Buffer length isn't sufficient");
}
size_t buffer_cur = 0;
size_t hex_cur = 0;
unsigned char *output = static_cast<unsigned char *>(buffer);
while (hex_cur < s.length())
{
const char temp_buffer[] = { s[hex_cur], s[hex_cur + 1], 0 };
unsigned int value = -1;
if (sscanf(temp_buffer, "%X", &value) <= 0 || value > 0xff)
{
SWSS_LOG_THROW("Invalid hex string %s", temp_buffer);
}
output[buffer_cur] = static_cast<unsigned char>(value);
hex_cur += 2;
buffer_cur += 1;
}
}
template<typename T>
void sai_deserialize_hex_binary(
_In_ const std::string &s,
_Out_ T &value)
{
SWSS_LOG_ENTER();
return sai_deserialize_hex_binary(s, &value, sizeof(T));
}
void sai_deserialize_system_port_config(
_In_ const std::string& s,
_Out_ sai_system_port_config_t& sysportconfig)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_number(j["port_id"], sysportconfig.port_id, false);
sai_deserialize_number(j["attached_switch_id"], sysportconfig.attached_switch_id, false);
sai_deserialize_number(j["attached_core_index"], sysportconfig.attached_core_index, false);
sai_deserialize_number(j["attached_core_port_index"], sysportconfig.attached_core_port_index, false);
sai_deserialize_number(j["speed"], sysportconfig.speed, false);
sai_deserialize_number(j["num_voq"], sysportconfig.num_voq, false);
}
void sai_deserialize_json(
_In_ const std::string& s,
_Out_ sai_json_t& js)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_number_list(j["json"], js.json, false);
}
void sai_deserialize_latch_status(
_In_ const std::string& s,
_Out_ sai_latch_status_t& latch_status)
{
SWSS_LOG_ENTER();
auto pos = s.find(":");
if (pos == std::string::npos)
{
SWSS_LOG_THROW("Invalid latch status %s", s.c_str());
}
std::string changed = s.substr(0, pos);
std::string current_status = s.substr(pos + 1);
sai_deserialize_bool(changed, latch_status.changed);
sai_deserialize_bool(current_status, latch_status.current_status);
}
void sai_deserialize_port_lane_latch_status(
_In_ const json& j,
_Out_ sai_port_lane_latch_status_t& lane_latch_status)
{
SWSS_LOG_ENTER();
sai_deserialize_latch_status(j["value"], lane_latch_status.value);
}
void sai_deserialize_port_lane_latch_status_list(
_In_ const std::string& s,
_Out_ sai_port_lane_latch_status_list_t& status_list,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
status_list.count = j["count"];
if (countOnly)
{
return;
}
if (j["list"] == nullptr)
{
status_list.list = NULL;
return;
}
json arr = j["list"];
if (arr.size() != (size_t)status_list.count)
{
SWSS_LOG_THROW("port lane latch status count mismatch %lu vs %u", arr.size(),status_list.count);
}
status_list.list = sai_alloc_n_of_ptr_type(status_list.count, status_list.list);
for (uint32_t i = 0; i < status_list.count; ++i)
{
const json &item = arr[i];
sai_deserialize_port_lane_latch_status(item, status_list.list[i]);
}
}
static void sai_deserialize_system_port_cfg_list_item(
_In_ const json& j,
_Out_ sai_system_port_config_t& sysportconfig)
{
SWSS_LOG_ENTER();
sai_deserialize_number(j["port_id"], sysportconfig.port_id, false);
sai_deserialize_number(j["attached_switch_id"], sysportconfig.attached_switch_id, false);
sai_deserialize_number(j["attached_core_index"], sysportconfig.attached_core_index, false);
sai_deserialize_number(j["attached_core_port_index"], sysportconfig.attached_core_port_index, false);
sai_deserialize_number(j["speed"], sysportconfig.speed, false);
sai_deserialize_number(j["num_voq"], sysportconfig.num_voq, false);
}
void sai_deserialize_system_port_config_list(
_In_ const std::string& s,
_Out_ sai_system_port_config_list_t& sysportconfiglist,
_In_ bool countOnly)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sysportconfiglist.count = j["count"];
if (countOnly)
{
return;
}
if (j["list"] == nullptr)
{
sysportconfiglist.list = NULL;
return;
}
json arr = j["list"];
if (arr.size() != (size_t)sysportconfiglist.count)
{
SWSS_LOG_THROW("system port config list count mismatch %lu vs %u", arr.size(), sysportconfiglist.count);
}
sysportconfiglist.list = sai_alloc_n_of_ptr_type(sysportconfiglist.count, sysportconfiglist.list);
for (uint32_t i = 0; i < sysportconfiglist.count; ++i)
{
const json& item = arr[i];
sai_deserialize_system_port_cfg_list_item(item, sysportconfiglist.list[i]);
}
}
void sai_deserialize_attr_value(
_In_ const std::string& s,
_In_ const sai_attr_metadata_t& meta,
_Out_ sai_attribute_t &attr,
_In_ const bool countOnly)
{
SWSS_LOG_ENTER();
memset(&attr.value, 0, sizeof(attr.value));
switch (meta.attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_BOOL:
return sai_deserialize_bool(s, attr.value.booldata);
case SAI_ATTR_VALUE_TYPE_CHARDATA:
return sai_deserialize_chardata(s, attr.value.chardata);
case SAI_ATTR_VALUE_TYPE_UINT8:
return sai_deserialize_number(s, attr.value.u8);
case SAI_ATTR_VALUE_TYPE_INT8:
return sai_deserialize_number(s, attr.value.s8);
case SAI_ATTR_VALUE_TYPE_UINT16:
return sai_deserialize_number(s, attr.value.u16);
case SAI_ATTR_VALUE_TYPE_JSON:
return sai_deserialize_json(s, attr.value.json);
case SAI_ATTR_VALUE_TYPE_INT16:
return sai_deserialize_number(s, attr.value.s16);
case SAI_ATTR_VALUE_TYPE_UINT32:
return sai_deserialize_number(s, attr.value.u32);
case SAI_ATTR_VALUE_TYPE_INT32:
return sai_deserialize_enum(s, meta.enummetadata, attr.value.s32);
case SAI_ATTR_VALUE_TYPE_UINT64:
return sai_deserialize_number(s, attr.value.u64);
// case SAI_ATTR_VALUE_TYPE_INT64:
// return sai_deserialize_number(s, attr.value.s64);
case SAI_ATTR_VALUE_TYPE_MAC:
return sai_deserialize_mac(s, attr.value.mac);
case SAI_ATTR_VALUE_TYPE_IPV4:
return sai_deserialize_ipv4(s, attr.value.ip4);
case SAI_ATTR_VALUE_TYPE_IPV6:
return sai_deserialize_ipv6(s, attr.value.ip6);
case SAI_ATTR_VALUE_TYPE_POINTER:
return sai_deserialize_pointer(s, attr.value.ptr);
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS:
return sai_deserialize_ip_address(s, attr.value.ipaddr);
case SAI_ATTR_VALUE_TYPE_IP_PREFIX:
return sai_deserialize_ip_prefix(s, attr.value.ipprefix);
case SAI_ATTR_VALUE_TYPE_OBJECT_ID:
return sai_deserialize_object_id(s, attr.value.oid);
case SAI_ATTR_VALUE_TYPE_OBJECT_LIST:
return sai_deserialize_oid_list(s, attr.value.objlist, countOnly);
case SAI_ATTR_VALUE_TYPE_UINT8_LIST:
return sai_deserialize_number_list(s, attr.value.u8list, countOnly);
case SAI_ATTR_VALUE_TYPE_INT8_LIST:
return sai_deserialize_number_list(s, attr.value.s8list, countOnly);
case SAI_ATTR_VALUE_TYPE_LATCH_STATUS:
return sai_deserialize_latch_status(s, attr.value.latchstatus);
case SAI_ATTR_VALUE_TYPE_PORT_LANE_LATCH_STATUS_LIST:
return sai_deserialize_port_lane_latch_status_list(s, attr.value.portlanelatchstatuslist, countOnly);
// case SAI_ATTR_VALUE_TYPE_UINT16_LIST:
// return sai_deserialize_number_list(s, attr.value.u16list, countOnly);
//
// case SAI_ATTR_VALUE_TYPE_INT16_LIST:
// return sai_deserialize_number_list(s, attr.value.s16list, countOnly);
case SAI_ATTR_VALUE_TYPE_UINT32_LIST:
return sai_deserialize_number_list(s, attr.value.u32list, countOnly);
case SAI_ATTR_VALUE_TYPE_INT32_LIST:
return sai_deserialize_enum_list(s, meta.enummetadata, attr.value.s32list, countOnly);
case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
return sai_deserialize_range(s, attr.value.u32range);
// case SAI_ATTR_VALUE_TYPE_INT32_RANGE:
// return sai_deserialize_range(s, attr.value.s32range);
case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST:
return sai_deserialize_u16_range_list(s, attr.value.u16rangelist, countOnly);
case SAI_ATTR_VALUE_TYPE_VLAN_LIST:
return sai_deserialize_number_list(s, attr.value.vlanlist, countOnly);
case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST:
return sai_deserialize_qos_map_list(s, attr.value.qosmap, countOnly);
case SAI_ATTR_VALUE_TYPE_MAP_LIST:
return sai_deserialize_map_list(s, attr.value.maplist, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST:
return sai_deserialize_acl_resource_list(s, attr.value.aclresource, countOnly);
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST:
return sai_deserialize_ip_address_list(s, attr.value.ipaddrlist, countOnly);
case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST:
return sai_deserialize_segment_list(s, attr.value.segmentlist, countOnly);
// ACL FIELD DATA
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:
return sai_deserialize_acl_field(s, meta, attr.value.aclfield, countOnly);
// ACL ACTION DATA
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS:
return sai_deserialize_acl_action(s, meta, attr.value.aclaction, countOnly);
case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY:
return sai_deserialize_acl_capability(s, attr.value.aclcapability);
case SAI_ATTR_VALUE_TYPE_AUTH_KEY:
return sai_deserialize_hex_binary(s, attr.value.authkey);
case SAI_ATTR_VALUE_TYPE_ENCRYPT_KEY:
return sai_deserialize_hex_binary(s, attr.value.encrypt_key);
case SAI_ATTR_VALUE_TYPE_MACSEC_SAK:
return sai_deserialize_hex_binary(s, attr.value.macsecsak);
case SAI_ATTR_VALUE_TYPE_MACSEC_AUTH_KEY:
return sai_deserialize_hex_binary(s, attr.value.macsecauthkey);
case SAI_ATTR_VALUE_TYPE_MACSEC_SALT:
return sai_deserialize_hex_binary(s, attr.value.macsecsalt);
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG:
return sai_deserialize_system_port_config(s, attr.value.sysportconfig);
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST:
return sai_deserialize_system_port_config_list(s, attr.value.sysportconfiglist, countOnly);
case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST:
return sai_deserialize_ip_prefix_list(s, attr.value.ipprefixlist, countOnly);
case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION:
return sai_deserialize_poe_port_power_consumption(s, attr.value.portpowerconsumption);
default:
SWSS_LOG_THROW("deserialize type %s is not supported yet FIXME",
sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
}
}
void sai_deserialize_status(
_In_ const std::string& s,
_Out_ sai_status_t& status)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_status_t, status);
}
void sai_deserialize_port_oper_status(
_In_ const std::string& s,
_Out_ sai_port_oper_status_t& status)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_port_oper_status_t, (int32_t&)status);
}
void sai_deserialize_port_error_status(
_In_ const std::string& s,
_Out_ sai_port_error_status_t& status)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_port_error_status_t, (int32_t&)status);
}
void sai_deserialize_port_host_tx_ready_status(
_In_ const std::string& s,
_Out_ sai_port_host_tx_ready_status_t& status)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_port_host_tx_ready_status_t, (int32_t&)status);
}
void sai_deserialize_queue_deadlock(
_In_ const std::string& s,
_Out_ sai_queue_pfc_deadlock_event_type_t& event)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_queue_pfc_deadlock_event_type_t, (int32_t&)event);
}
void sai_deserialize_ipmc_entry_type(
_In_ const std::string& s,
_Out_ sai_ipmc_entry_type_t& type)
{
SWSS_LOG_ENTER();
return sai_deserialize_enum(s, &sai_metadata_enum_sai_ipmc_entry_type_t, (int32_t&)type);
}
void sai_deserialize_l2mc_entry_type(
_In_ const std::string& s,
_Out_ sai_l2mc_entry_type_t& type)
{
SWSS_LOG_ENTER();
return sai_deserialize_enum(s, &sai_metadata_enum_sai_l2mc_entry_type_t, (int32_t&)type);
}
void sai_deserialize_fdb_event(
_In_ const std::string& s,
_Out_ sai_fdb_event_t& event)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_fdb_event_t, (int32_t&)event);
}
void sai_deserialize_nat_event(
_In_ const std::string& s,
_Out_ sai_nat_event_t& event)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_nat_event_t, (int32_t&)event);
}
void sai_deserialize_bfd_session_state(
_In_ const std::string& s,
_Out_ sai_bfd_session_state_t& state)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_bfd_session_state_t, (int32_t&)state);
}
void sai_deserialize_twamp_session_state(
_In_ const std::string& s,
_Out_ sai_twamp_session_state_t& state)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_twamp_session_state_t, (int32_t&)state);
}
void sai_deserialize_twamp_session_stat(
_In_ const std::string& s,
_Out_ sai_twamp_session_stat_t& stat)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_twamp_session_stat_t, (int32_t&)stat);
}
void sai_deserialize_switch_oper_status(
_In_ const std::string& s,
_Out_ sai_object_id_t &switch_id,
_Out_ sai_switch_oper_status_t& status)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], switch_id);
sai_deserialize_enum(j["status"], &sai_metadata_enum_sai_switch_oper_status_t, (int32_t&)status);
}
void sai_deserialize_timespec(
_In_ const std::string& s,
_Out_ sai_timespec_t ×tamp)
{
SWSS_LOG_ENTER();
json j;
try
{
j = json::parse(s);
}
catch (const std::exception&)
{
SWSS_LOG_THROW("Received an exception after trying to parse timespec_t from %s", s.c_str());
}
sai_deserialize_number<uint64_t>(j["tv_sec"], timestamp.tv_sec);
sai_deserialize_number<uint32_t>(j["tv_nsec"], timestamp.tv_nsec);
}
void sai_deserialize_switch_asic_sdk_health_event(
_In_ const std::string& s,
_Out_ sai_object_id_t &switch_id,
_Out_ sai_switch_asic_sdk_health_severity_t &severity,
_Out_ sai_timespec_t ×tamp,
_Out_ sai_switch_asic_sdk_health_category_t &category,
_Out_ sai_switch_health_data_t &data,
_Out_ sai_u8_list_t &description)
{
SWSS_LOG_ENTER();
json j;
try
{
j = json::parse(s);
}
catch (const std::exception&)
{
SWSS_LOG_THROW("Received an exception after trying to parse switch_asic_sdk_health_event from %s", s.c_str());
}
sai_deserialize_object_id(j["switch_id"], switch_id);
sai_deserialize_enum(j["severity"], &sai_metadata_enum_sai_switch_asic_sdk_health_severity_t, (int32_t&)severity);
sai_deserialize_timespec(j["timestamp"], timestamp);
sai_deserialize_enum(j["category"], &sai_metadata_enum_sai_switch_asic_sdk_health_category_t, (int32_t&)category);
int32_t data_type;
sai_deserialize_enum(j["data.data_type"], &sai_metadata_enum_sai_health_data_type_t, data_type);
data.data_type = (sai_health_data_type_t)data_type;
data.data_type = SAI_HEALTH_DATA_TYPE_GENERAL;
sai_deserialize_number_list(j["description"], description, false, false);
}
void sai_deserialize_free_switch_asic_sdk_health_event(
_In_ sai_u8_list_t &description)
{
SWSS_LOG_ENTER();
sai_free_list(description);
}
void sai_deserialize_switch_shutdown_request(
_In_ const std::string& s,
_Out_ sai_object_id_t &switch_id)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], switch_id);
}
void sai_deserialize_object_type(
_In_ const std::string& s,
_Out_ sai_object_type_t& object_type)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_object_type_t, (int32_t&)object_type);
}
void sai_deserialize_log_level(
_In_ const std::string& s,
_Out_ sai_log_level_t& log_level)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_log_level_t, (int32_t&)log_level);
}
void sai_deserialize_api(
_In_ const std::string& s,
_Out_ sai_api_t& api)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_api_t, (int32_t&)api);
}
void sai_deserialize_vlan_id(
_In_ const std::string& s,
_In_ sai_vlan_id_t& vlan_id)
{
SWSS_LOG_ENTER();
sai_deserialize_number(s, vlan_id);
}
void sai_deserialize_fdb_entry(
_In_ const std::string &s,
_Out_ sai_fdb_entry_t &fdb_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], fdb_entry.switch_id);
sai_deserialize_mac(j["mac"], fdb_entry.mac_address);
sai_deserialize_object_id(j["bvid"], fdb_entry.bv_id);
}
void sai_deserialize_neighbor_entry(
_In_ const std::string& s,
_In_ sai_neighbor_entry_t &ne)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], ne.switch_id);
sai_deserialize_object_id(j["rif"], ne.rif_id);
sai_deserialize_ip_address(j["ip"], ne.ip_address);
}
void sai_deserialize_meter_bucket_entry(
_In_ const std::string& s,
_Out_ sai_meter_bucket_entry_t& meter_bucket_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], meter_bucket_entry.switch_id);
sai_deserialize_object_id(j["eni_id"], meter_bucket_entry.eni_id);
sai_deserialize_number(j["meter_class"], meter_bucket_entry.meter_class);
}
void sai_deserialize_flow_entry(
_In_ const std::string& s,
_Out_ sai_flow_entry_t &flow_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], flow_entry.switch_id);
sai_deserialize_mac(j["eni_mac"], flow_entry.eni_mac);
sai_deserialize_number(j["vnet_id"], flow_entry.vnet_id);
sai_deserialize_number(j["ip_proto"], flow_entry.ip_proto);
sai_deserialize_ip_address(j["src_ip"], flow_entry.src_ip);
sai_deserialize_ip_address(j["dst_ip"], flow_entry.dst_ip);
sai_deserialize_number(j["src_port"], flow_entry.src_port);
sai_deserialize_number(j["dst_port"], flow_entry.dst_port);
}
void sai_deserialize_twamp_session_stats_data(
_In_ const std::string& s,
_Out_ sai_twamp_session_stats_data_t &twamp_session_stats_data)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_number(j["index"], twamp_session_stats_data.index);
json arr = j["list"];
twamp_session_stats_data.number_of_counters = (uint32_t)arr.size();
twamp_session_stats_data.counters_ids = new sai_twamp_session_stat_t[twamp_session_stats_data.number_of_counters];
twamp_session_stats_data.counters = new uint64_t[twamp_session_stats_data.number_of_counters];
for (uint32_t i = 0; i < twamp_session_stats_data.number_of_counters; ++i)
{
const json &item = arr[i];
sai_deserialize_twamp_session_stat(item["counters_ids"], twamp_session_stats_data.counters_ids[i]);
sai_deserialize_number(item["counters"], twamp_session_stats_data.counters[i]);
}
}
void sai_deserialize_json_twamp_session_event_notification_data(
_In_ const json& j,
_Out_ sai_twamp_session_event_notification_data_t& twamp_session_data)
{
SWSS_LOG_ENTER();
sai_deserialize_object_id(j["twamp_session_id"], twamp_session_data.twamp_session_id);
sai_deserialize_twamp_session_state(j["session_state"], twamp_session_data.session_state);
sai_deserialize_number(j["index"], twamp_session_data.session_stats.index);
json arr = j["list"];
twamp_session_data.session_stats.number_of_counters = (uint32_t)arr.size();
twamp_session_data.session_stats.counters_ids = new sai_twamp_session_stat_t[twamp_session_data.session_stats.number_of_counters];
twamp_session_data.session_stats.counters = new uint64_t[twamp_session_data.session_stats.number_of_counters];
for (uint32_t i = 0; i < twamp_session_data.session_stats.number_of_counters; ++i)
{
const json &item = arr[i];
sai_deserialize_twamp_session_stat(item["counters_ids"], twamp_session_data.session_stats.counters_ids[i]);
sai_deserialize_number(item["counters"], twamp_session_data.session_stats.counters[i]);
}
}
#define EXPECT(x) { \
if (strncmp(buf, x, sizeof(x) - 1) == 0) { buf += sizeof(x) - 1; } \
else { \
SWSS_LOG_THROW("failed to expect %s on %s", x, buf); } }
#define EXPECT_QUOTE EXPECT("\"")
#define EXPECT_KEY(k) EXPECT("\"" k "\":")
#define EXPECT_NEXT_KEY(k) { EXPECT(","); EXPECT_KEY(k); }
#define EXPECT_CHECK(expr, suffix) { \
ret = (expr); \
if (ret < 0) { \
SWSS_LOG_THROW("failed to deserialize " #suffix ""); } \
buf += ret; }
#define EXPECT_QUOTE_CHECK(expr, suffix) {\
EXPECT_QUOTE; EXPECT_CHECK(expr, suffix); EXPECT_QUOTE; }
static int sai_deserialize_object_id_buf(
_In_ const char* buf,
_Out_ sai_object_id_t* oid)
{
SWSS_LOG_ENTER();
if (strncmp(buf, "oid:0x", 6) != 0)
{
SWSS_LOG_THROW("invalid oid %s", buf);
}
errno = 0;
char *endptr = NULL;
*oid = (sai_object_id_t)strtoull(buf+4, &endptr, 16);
if (errno != 0 || !sai_serialize_is_char_allowed(*endptr))
{
SWSS_LOG_THROW("invalid oid %s", buf);
}
return (int)(endptr - buf);
}
void sai_deserialize_route_entry(
_In_ const std::string &s,
_Out_ sai_route_entry_t& route_entry)
{
SWSS_LOG_ENTER();
// NOTE: this serialize is copy from SAI/meta auto generated serialization
// but since previously we used json.hpp, then order of serialized item is
// different, so we copy actual serialize method and reorder names
// {"dest":"0.0.0.0/0","switch_id":"oid:0x21000000000000","vr":"oid:0x3000000000022"}
const char* buf = s.c_str();
int ret;
EXPECT("{");
EXPECT_KEY("dest");
EXPECT_QUOTE_CHECK(sai_deserialize_ip_prefix(buf, &route_entry.destination), ip_prefix);
EXPECT_NEXT_KEY("switch_id");
EXPECT_QUOTE_CHECK(sai_deserialize_object_id_buf(buf, &route_entry.switch_id), object_id);
EXPECT_NEXT_KEY("vr");
EXPECT_QUOTE_CHECK(sai_deserialize_object_id_buf(buf, &route_entry.vr_id), object_id);
EXPECT("}");
}
void sai_deserialize_inseg_entry(
_In_ const std::string &s,
_Out_ sai_inseg_entry_t& inseg_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], inseg_entry.switch_id);
sai_deserialize_number(j["label"], inseg_entry.label);
}
void sai_deserialize_my_sid_entry(
_In_ const std::string& s,
_Out_ sai_my_sid_entry_t &ne)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], ne.switch_id);
sai_deserialize_object_id(j["vr_id"], ne.vr_id);
sai_deserialize_number(j["locator_block_len"], ne.locator_block_len);
sai_deserialize_number(j["locator_node_len"], ne.locator_node_len);
sai_deserialize_number(j["function_len"], ne.function_len);
sai_deserialize_number(j["args_len"], ne.args_len);
sai_deserialize_ipv6(j["sid"], ne.sid);
}
static void sai_deserialize_nat_entry_key(
_In_ const json& j,
_Out_ sai_nat_entry_key_t& nat_entry_key)
{
SWSS_LOG_ENTER();
sai_deserialize_ipv4(j["src_ip"], nat_entry_key.src_ip);
sai_deserialize_ipv4(j["dst_ip"], nat_entry_key.dst_ip);
sai_deserialize_number(j["proto"], nat_entry_key.proto);
sai_deserialize_number(j["l4_src_port"], nat_entry_key.l4_src_port);
sai_deserialize_number(j["l4_dst_port"], nat_entry_key.l4_dst_port);
}
static void sai_deserialize_nat_entry_mask(
_In_ const json& j,
_Out_ sai_nat_entry_mask_t& nat_entry_mask)
{
SWSS_LOG_ENTER();
sai_deserialize_ipv4(j["src_ip"], nat_entry_mask.src_ip);
sai_deserialize_ipv4(j["dst_ip"], nat_entry_mask.dst_ip);
sai_deserialize_number(j["proto"], nat_entry_mask.proto);
sai_deserialize_number(j["l4_src_port"], nat_entry_mask.l4_src_port);
sai_deserialize_number(j["l4_dst_port"], nat_entry_mask.l4_dst_port);
}
static void sai_deserialize_nat_entry_data(
_In_ const json& j,
_Out_ sai_nat_entry_data_t& nat_entry_data)
{
SWSS_LOG_ENTER();
sai_deserialize_nat_entry_key(j["key"], nat_entry_data.key);
sai_deserialize_nat_entry_mask(j["mask"], nat_entry_data.mask);
}
void sai_deserialize_nat_entry_type(
_In_ const std::string& s,
_Out_ sai_nat_type_t& type)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_nat_type_t, (int32_t&)type);
}
void sai_deserialize_nat_entry(
_In_ const std::string &s,
_Out_ sai_nat_entry_t& nat_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], nat_entry.switch_id);
sai_deserialize_object_id(j["vr"], nat_entry.vr_id);
sai_deserialize_nat_entry_type(j["nat_type"], nat_entry.nat_type);
sai_deserialize_nat_entry_data(j["nat_data"], nat_entry.data);
}
void sai_deserialize_ipmc_entry(
_In_ const std::string &s,
_Out_ sai_ipmc_entry_t& ipmc_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], ipmc_entry.switch_id);
sai_deserialize_object_id(j["vr_id"], ipmc_entry.vr_id);
sai_deserialize_ipmc_entry_type(j["type"], ipmc_entry.type);
sai_deserialize_ip_address(j["destination"], ipmc_entry.destination);
sai_deserialize_ip_address(j["source"], ipmc_entry.source);
}
void sai_deserialize_l2mc_entry(
_In_ const std::string &s,
_Out_ sai_l2mc_entry_t& l2mc_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], l2mc_entry.switch_id);
sai_deserialize_object_id(j["bv_id"], l2mc_entry.bv_id);
sai_deserialize_l2mc_entry_type(j["type"], l2mc_entry.type);
sai_deserialize_ip_address(j["destination"], l2mc_entry.destination);
sai_deserialize_ip_address(j["source"], l2mc_entry.source);
}
void sai_deserialize_mcast_fdb_entry(
_In_ const std::string &s,
_Out_ sai_mcast_fdb_entry_t& mcast_fdb_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], mcast_fdb_entry.switch_id);
sai_deserialize_object_id(j["bv_id"], mcast_fdb_entry.bv_id);
sai_deserialize_mac(j["mac_address"], mcast_fdb_entry.mac_address);
}
void sai_deserialize_direction_lookup_entry(
_In_ const std::string &s,
_Out_ sai_direction_lookup_entry_t& direction_lookup_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], direction_lookup_entry.switch_id);
sai_deserialize_number(j["vni"], direction_lookup_entry.vni);
}
void sai_deserialize_eni_ether_address_map_entry(
_In_ const std::string &s,
_Out_ sai_eni_ether_address_map_entry_t& eni_ether_address_map_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], eni_ether_address_map_entry.switch_id);
sai_deserialize_mac(j["address"], eni_ether_address_map_entry.address);
}
void sai_deserialize_vip_entry(
_In_ const std::string &s,
_Out_ sai_vip_entry_t& vip_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], vip_entry.switch_id);
sai_deserialize_ip_address(j["vip"], vip_entry.vip);
}
void sai_deserialize_inbound_routing_entry(
_In_ const std::string &s,
_Out_ sai_inbound_routing_entry_t& inbound_routing_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], inbound_routing_entry.switch_id);
sai_deserialize_object_id(j["eni_id"], inbound_routing_entry.eni_id);
sai_deserialize_number(j["vni"], inbound_routing_entry.vni);
sai_deserialize_ip_address(j["sip"], inbound_routing_entry.sip);
sai_deserialize_ip_address(j["sip_mask"], inbound_routing_entry.sip_mask);
sai_deserialize_number(j["priority"], inbound_routing_entry.priority);
}
void sai_deserialize_pa_validation_entry(
_In_ const std::string &s,
_Out_ sai_pa_validation_entry_t& pa_validation_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], pa_validation_entry.switch_id);
sai_deserialize_object_id(j["vnet_id"], pa_validation_entry.vnet_id);
sai_deserialize_ip_address(j["sip"], pa_validation_entry.sip);
}
void sai_deserialize_outbound_routing_entry(
_In_ const std::string &s,
_Out_ sai_outbound_routing_entry_t& outbound_routing_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], outbound_routing_entry.switch_id);
sai_deserialize_ip_prefix(j["destination"], outbound_routing_entry.destination);
sai_deserialize_object_id(j["outbound_routing_group_id"], outbound_routing_entry.outbound_routing_group_id);
}
void sai_deserialize_outbound_ca_to_pa_entry(
_In_ const std::string &s,
_Out_ sai_outbound_ca_to_pa_entry_t& outbound_ca_to_pa_entry)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j["switch_id"], outbound_ca_to_pa_entry.switch_id);
sai_deserialize_object_id(j["dst_vnet_id"], outbound_ca_to_pa_entry.dst_vnet_id);
sai_deserialize_ip_address(j["dip"], outbound_ca_to_pa_entry.dip);
}
void sai_deserialize_attr_id(
_In_ const std::string& s,
_Out_ const sai_attr_metadata_t** meta)
{
SWSS_LOG_ENTER();
if (meta == NULL)
{
SWSS_LOG_THROW("meta pointer is null");
}
auto m = sai_metadata_get_attr_metadata_by_attr_id_name(s.c_str());
if (m == NULL)
{
// check ignored attributes names for backward compatibility
m = sai_metadata_get_ignored_attr_metadata_by_attr_id_name(s.c_str());
}
if (m == NULL)
{
SWSS_LOG_THROW("invalid attr id: %s", s.c_str());
}
*meta = m;
}
void sai_deserialize_attr_id(
_In_ const std::string& s,
_Out_ sai_attr_id_t& attrid)
{
SWSS_LOG_ENTER();
const sai_attr_metadata_t *meta = NULL;
sai_deserialize_attr_id(s, &meta);
attrid = meta->attrid;
}
bool sai_deserialize_object_entry(
_In_ const std::string object_id,
_Inout_ sai_object_meta_key_t& meta_key)
{
SWSS_LOG_ENTER();
switch (meta_key.objecttype)
{
case SAI_OBJECT_TYPE_FDB_ENTRY:
sai_deserialize_fdb_entry(object_id, meta_key.objectkey.key.fdb_entry);
return true;
case SAI_OBJECT_TYPE_ROUTE_ENTRY:
sai_deserialize_route_entry(object_id, meta_key.objectkey.key.route_entry);
return true;
case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
sai_deserialize_neighbor_entry(object_id, meta_key.objectkey.key.neighbor_entry);
return true;
case SAI_OBJECT_TYPE_NAT_ENTRY:
sai_deserialize_nat_entry(object_id, meta_key.objectkey.key.nat_entry);
return true;
case SAI_OBJECT_TYPE_INSEG_ENTRY:
sai_deserialize_inseg_entry(object_id, meta_key.objectkey.key.inseg_entry);
return true;
case SAI_OBJECT_TYPE_MY_SID_ENTRY:
sai_deserialize_my_sid_entry(object_id, meta_key.objectkey.key.my_sid_entry);
return true;
case SAI_OBJECT_TYPE_L2MC_ENTRY:
sai_deserialize_l2mc_entry(object_id, meta_key.objectkey.key.l2mc_entry);
return true;
case SAI_OBJECT_TYPE_IPMC_ENTRY:
sai_deserialize_ipmc_entry(object_id, meta_key.objectkey.key.ipmc_entry);
return true;
case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY:
sai_deserialize_mcast_fdb_entry(object_id, meta_key.objectkey.key.mcast_fdb_entry);
return true;
default:
return false;
}
}
bool sai_deserialize_object_extension_entry(
_In_ const std::string object_id,
_Inout_ sai_object_meta_key_t& meta_key)
{
SWSS_LOG_ENTER();
switch ((sai_object_type_extensions_t)meta_key.objecttype)
{
case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
sai_deserialize_direction_lookup_entry(object_id, meta_key.objectkey.key.direction_lookup_entry);
return true;
case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
sai_deserialize_eni_ether_address_map_entry(object_id, meta_key.objectkey.key.eni_ether_address_map_entry);
return true;
case SAI_OBJECT_TYPE_VIP_ENTRY:
sai_deserialize_vip_entry(object_id, meta_key.objectkey.key.vip_entry);
return true;
case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
sai_deserialize_inbound_routing_entry(object_id, meta_key.objectkey.key.inbound_routing_entry);
return true;
case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
sai_deserialize_pa_validation_entry(object_id, meta_key.objectkey.key.pa_validation_entry);
return true;
case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
sai_deserialize_outbound_routing_entry(object_id, meta_key.objectkey.key.outbound_routing_entry);
return true;
case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
sai_deserialize_outbound_ca_to_pa_entry(object_id, meta_key.objectkey.key.outbound_ca_to_pa_entry);
return true;
case SAI_OBJECT_TYPE_FLOW_ENTRY:
sai_deserialize_flow_entry(object_id, meta_key.objectkey.key.flow_entry);
return true;
case SAI_OBJECT_TYPE_METER_BUCKET_ENTRY:
sai_deserialize_meter_bucket_entry(object_id, meta_key.objectkey.key.meter_bucket_entry);
return true;
default:
return false;
}
}
void sai_deserialize_object_meta_key(
_In_ const std::string &s,
_Out_ sai_object_meta_key_t& meta_key)
{
SWSS_LOG_ENTER();
SWSS_LOG_DEBUG("%s", s.c_str());
const std::string &str_object_type = s.substr(0, s.find(":"));
const std::string &str_object_id = s.substr(s.find(":") + 1);
sai_deserialize_object_type(str_object_type, meta_key.objecttype);
if (!sai_metadata_is_object_type_valid(meta_key.objecttype))
{
SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str());
}
if (!sai_deserialize_object_entry(str_object_id, meta_key) &&
!sai_deserialize_object_extension_entry(str_object_id, meta_key))
{
const auto& meta = sai_metadata_get_object_type_info(meta_key.objecttype);
if (meta->isnonobjectid)
{
SWSS_LOG_THROW("object %s is non object id, not supported yet, FIXME",
sai_serialize_object_type(meta->objecttype).c_str());
}
sai_deserialize_object_id(str_object_id, meta_key.objectkey.key.object_id);
}
}
// deserialize notifications
static void sai_deserialize_json_fdb_event_notification_data(
_In_ const json& j,
_Out_ sai_fdb_event_notification_data_t& fdb)
{
SWSS_LOG_ENTER();
sai_deserialize_fdb_event(j["fdb_event"], fdb.event_type);
sai_deserialize_fdb_entry(j["fdb_entry"], fdb.fdb_entry);
json arr = j["list"];
fdb.attr_count = (uint32_t)arr.size();
fdb.attr = new sai_attribute_t[fdb.attr_count];
for (uint32_t i = 0; i < fdb.attr_count; ++i)
{
const json &item = arr[i];
const sai_attr_metadata_t *meta = NULL;
sai_deserialize_attr_id(item["id"], &meta);
fdb.attr[i].id = meta->attrid;
sai_deserialize_attr_value(item["value"], *meta, fdb.attr[i]);
}
}
void sai_deserialize_fdb_event_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_fdb_event_notification_data_t** fdb_event)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
count = (uint32_t)j.size();
auto data = new sai_fdb_event_notification_data_t[count];
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_json_fdb_event_notification_data(j[i], data[i]);
}
*fdb_event = data;
}
static void sai_deserialize_json_nat_event_notification_data(
_In_ const json& j,
_Out_ sai_nat_event_notification_data_t& nat)
{
SWSS_LOG_ENTER();
sai_deserialize_nat_event(j["nat_event"], nat.event_type);
sai_deserialize_nat_entry(j["nat_entry"], nat.nat_entry);
}
void sai_deserialize_nat_event_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_nat_event_notification_data_t** nat_event)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
count = (uint32_t)j.size();
auto data = new sai_nat_event_notification_data_t[count];
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_json_nat_event_notification_data(j[i], data[i]);
}
*nat_event = data;
}
void sai_deserialize_port_oper_status_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_port_oper_status_notification_t** port_oper_status)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
count = (uint32_t)j.size();
auto data = new sai_port_oper_status_notification_t[count];
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_object_id(j[i]["port_id"], data[i].port_id);
sai_deserialize_port_oper_status(j[i]["port_state"], data[i].port_state);
sai_deserialize_port_error_status(j[i]["port_error_status"], data[i].port_error_status);
}
*port_oper_status = data;
}
void sai_deserialize_port_host_tx_ready_ntf(
_In_ const std::string& s,
_Out_ sai_object_id_t& switch_id,
_Out_ sai_object_id_t& port_id,
_Out_ sai_port_host_tx_ready_status_t& host_tx_ready_status)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_object_id(j[0]["port_id"], port_id);
sai_deserialize_object_id(j[0]["switch_id"], switch_id);
sai_deserialize_port_host_tx_ready_status(j[0]["host_tx_ready_status"], host_tx_ready_status);
}
void sai_deserialize_queue_deadlock_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_queue_deadlock_notification_data_t** deadlock_data)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
count = (uint32_t)j.size();
auto data = new sai_queue_deadlock_notification_data_t[count];
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_object_id(j[i]["queue_id"], data[i].queue_id);
sai_deserialize_queue_deadlock(j[i]["event"], data[i].event);
}
*deadlock_data = data;
}
void sai_deserialize_bfd_session_state_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_bfd_session_state_notification_t** bfd_session_state)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
count = (uint32_t)j.size();
auto data = new sai_bfd_session_state_notification_t[count];
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_object_id(j[i]["bfd_session_id"], data[i].bfd_session_id);
sai_deserialize_bfd_session_state(j[i]["session_state"], data[i].session_state);
}
*bfd_session_state = data;
}
void sai_deserialize_twamp_session_event_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_twamp_session_event_notification_data_t** twamp_session_event)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
count = (uint32_t)j.size();
auto data = new sai_twamp_session_event_notification_data_t[count];
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_json_twamp_session_event_notification_data(j[i], data[i]);
}
*twamp_session_event = data;
}
// deserialize free
void sai_deserialize_free_attribute_value(
_In_ const sai_attr_value_type_t type,
_In_ sai_attribute_t &attr)
{
SWSS_LOG_ENTER();
// if we allocated list, then we need to free it
switch (type)
{
case SAI_ATTR_VALUE_TYPE_BOOL:
case SAI_ATTR_VALUE_TYPE_CHARDATA:
case SAI_ATTR_VALUE_TYPE_UINT8:
case SAI_ATTR_VALUE_TYPE_INT8:
case SAI_ATTR_VALUE_TYPE_UINT16:
case SAI_ATTR_VALUE_TYPE_INT16:
case SAI_ATTR_VALUE_TYPE_UINT32:
case SAI_ATTR_VALUE_TYPE_INT32:
case SAI_ATTR_VALUE_TYPE_UINT64:
case SAI_ATTR_VALUE_TYPE_INT64:
case SAI_ATTR_VALUE_TYPE_MAC:
case SAI_ATTR_VALUE_TYPE_IPV4:
case SAI_ATTR_VALUE_TYPE_IPV6:
case SAI_ATTR_VALUE_TYPE_POINTER:
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS:
case SAI_ATTR_VALUE_TYPE_IP_PREFIX:
case SAI_ATTR_VALUE_TYPE_OBJECT_ID:
case SAI_ATTR_VALUE_TYPE_LATCH_STATUS:
break;
case SAI_ATTR_VALUE_TYPE_JSON:
sai_free_list(attr.value.json.json);
break;
case SAI_ATTR_VALUE_TYPE_OBJECT_LIST:
sai_free_list(attr.value.objlist);
break;
case SAI_ATTR_VALUE_TYPE_UINT8_LIST:
sai_free_list(attr.value.u8list);
break;
case SAI_ATTR_VALUE_TYPE_INT8_LIST:
sai_free_list(attr.value.s8list);
break;
// case SAI_ATTR_VALUE_TYPE_UINT16_LIST:
// sai_free_list(attr.value.u16list);
// break;
//
// case SAI_ATTR_VALUE_TYPE_INT16_LIST:
// sai_free_list(attr.value.s16list);
// break;
case SAI_ATTR_VALUE_TYPE_UINT32_LIST:
sai_free_list(attr.value.u32list);
break;
case SAI_ATTR_VALUE_TYPE_INT32_LIST:
sai_free_list(attr.value.s32list);
break;
case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
case SAI_ATTR_VALUE_TYPE_INT32_RANGE:
break;
case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST:
sai_free_list(attr.value.u16rangelist);
break;
case SAI_ATTR_VALUE_TYPE_VLAN_LIST:
sai_free_list(attr.value.vlanlist);
break;
case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST:
sai_free_list(attr.value.qosmap);
break;
case SAI_ATTR_VALUE_TYPE_MAP_LIST:
sai_free_list(attr.value.maplist);
break;
case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST:
sai_free_list(attr.value.aclresource);
break;
case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST:
sai_free_list(attr.value.ipaddrlist);
break;
case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST:
sai_free_list(attr.value.segmentlist);
break;
case SAI_ATTR_VALUE_TYPE_PORT_LANE_LATCH_STATUS_LIST:
sai_free_list(attr.value.portlanelatchstatuslist);
break;
/* ACL FIELD DATA */
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
sai_free_list(attr.value.aclfield.data.objlist);
break;
case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:
sai_free_list(attr.value.aclfield.mask.u8list);
sai_free_list(attr.value.aclfield.data.u8list);
break;
/* ACL ACTION DATA */
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IP_ADDRESS:
break;
case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
sai_free_list(attr.value.aclaction.parameter.objlist);
break;
case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY:
sai_free_list(attr.value.aclcapability.action_list);
break;
case SAI_ATTR_VALUE_TYPE_AUTH_KEY:
break;
case SAI_ATTR_VALUE_TYPE_ENCRYPT_KEY:
break;
case SAI_ATTR_VALUE_TYPE_MACSEC_SAK:
case SAI_ATTR_VALUE_TYPE_MACSEC_AUTH_KEY:
case SAI_ATTR_VALUE_TYPE_MACSEC_SALT:
case SAI_ATTR_VALUE_TYPE_MACSEC_SCI:
case SAI_ATTR_VALUE_TYPE_MACSEC_SSCI:
break;
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG:
break;
case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST:
sai_free_list(attr.value.sysportconfiglist);
break;
case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST:
sai_free_list(attr.value.ipprefixlist);
break;
case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION:
break;
default:
SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(type).c_str());
}
}
void sai_deserialize_poe_port_active_channel_type(
_In_ const std::string& s,
_Out_ sai_poe_port_active_channel_type_t& value)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_poe_port_active_channel_type_t, (int32_t&)value);
}
void sai_deserialize_poe_port_class_method_type(
_In_ const std::string& s,
_Out_ sai_poe_port_class_method_type_t& value)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_poe_port_class_method_type_t, (int32_t&)value);
}
void sai_deserialzie_poe_port_signature_type(
_In_ const std::string& s,
_Out_ sai_poe_port_signature_type_t& value)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_poe_port_signature_type_t, (int32_t&)value);
}
void sai_deserialize_poe_port_power_consumption(
_In_ const std::string& s,
_Out_ sai_poe_port_power_consumption_t& value)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_poe_port_active_channel_type(j["active_channel"], value.active_channel);
sai_deserialize_number(j["voltage"], value.voltage);
sai_deserialize_number(j["current"], value.current);
sai_deserialize_number(j["consumption"], value.consumption);
sai_deserialize_poe_port_class_method_type(j["class_method"], value.class_method);
sai_deserialzie_poe_port_signature_type(j["signature_type"],value.signature_type);
sai_deserialize_number(j["measured_class_a"], value.measured_class_a);
sai_deserialize_number(j["assigned_class_a"], value.assigned_class_a);
sai_deserialize_number(j["measured_class_b"], value.measured_class_b);
sai_deserialize_number(j["assigned_class_b"], value.assigned_class_b);
}
// deserialize free notifications
void sai_deserialize_free_fdb_event(
_In_ sai_fdb_event_notification_data_t& fdb_event)
{
SWSS_LOG_ENTER();
for (uint32_t i = 0; i < fdb_event.attr_count; ++i)
{
auto meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_FDB_ENTRY, fdb_event.attr[i].id);
if (meta == NULL)
{
SWSS_LOG_THROW("unable to get metadata for object type %s, attribute %d",
sai_serialize_object_type(SAI_OBJECT_TYPE_FDB_ENTRY).c_str(),
fdb_event.attr[i].id);
}
sai_deserialize_free_attribute_value(meta->attrvaluetype, fdb_event.attr[i]);
}
delete[] fdb_event.attr;
}
void sai_deserialize_free_fdb_event_ntf(
_In_ uint32_t count,
_In_ sai_fdb_event_notification_data_t* fdb_event)
{
SWSS_LOG_ENTER();
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_free_fdb_event(fdb_event[i]);
}
delete[] fdb_event;
}
void sai_deserialize_free_nat_event(
_In_ sai_nat_event_notification_data_t& nat_event)
{
SWSS_LOG_ENTER();
}
void sai_deserialize_free_nat_event_ntf(
_In_ uint32_t count,
_In_ sai_nat_event_notification_data_t* nat_event)
{
SWSS_LOG_ENTER();
for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_free_nat_event(nat_event[i]);
}
delete[] nat_event;
}
void sai_deserialize_free_port_oper_status_ntf(
_In_ uint32_t count,
_In_ sai_port_oper_status_notification_t* port_oper_status)
{
SWSS_LOG_ENTER();
delete[] port_oper_status;
}
void sai_deserialize_free_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ sai_queue_deadlock_notification_data_t* queue_deadlock)
{
SWSS_LOG_ENTER();
delete[] queue_deadlock;
}
void sai_deserialize_free_bfd_session_state_ntf(
_In_ uint32_t count,
_In_ sai_bfd_session_state_notification_t* bfd_session_state)
{
SWSS_LOG_ENTER();
delete[] bfd_session_state;
}
void sai_deserialize_free_twamp_session_event_ntf(
_In_ uint32_t count,
_In_ sai_twamp_session_event_notification_data_t* twamp_session_event)
{
SWSS_LOG_ENTER();
delete[] twamp_session_event;
}
void sai_deserialize_ingress_priority_group_attr(
_In_ const std::string& s,
_Out_ sai_ingress_priority_group_attr_t& attr)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_ingress_priority_group_attr_t, (int32_t&)attr);
}
void sai_deserialize_queue_attr(
_In_ const std::string& s,
_Out_ sai_queue_attr_t& attr)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_queue_attr_t, (int32_t&)attr);
}
void sai_deserialize_macsec_sa_attr(
_In_ const std::string& s,
_Out_ sai_macsec_sa_attr_t& attr)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_macsec_sa_attr_t, (int32_t&)attr);
}
void sai_deserialize_acl_counter_attr(
_In_ const std::string& s,
_Out_ sai_acl_counter_attr_t& attr)
{
SWSS_LOG_ENTER();
sai_deserialize_enum(s, &sai_metadata_enum_sai_acl_counter_attr_t, (int32_t&)attr);
}
// sairedis
void sai_deserialize(
_In_ const std::string& s,
_Out_ sai_redis_notify_syncd_t& value)
{
SWSS_LOG_ENTER();
if (s == SYNCD_INIT_VIEW)
{
value = SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW;
}
else if (s == SYNCD_APPLY_VIEW)
{
value = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW;
}
else if (s == SYNCD_INSPECT_ASIC)
{
value = SAI_REDIS_NOTIFY_SYNCD_INSPECT_ASIC;
}
else if (s == SYNCD_INVOKE_DUMP)
{
value = SAI_REDIS_NOTIFY_SYNCD_INVOKE_DUMP;
}
else
{
SWSS_LOG_THROW("enum %s not found in sai_redis_notify_syncd_t", s.c_str());
}
}
sai_redis_notify_syncd_t sai_deserialize_redis_notify_syncd(
_In_ const std::string& s)
{
SWSS_LOG_ENTER();
sai_redis_notify_syncd_t value;
sai_deserialize(s, value);
return value;
}
void sai_deserialize_redis_communication_mode(
_In_ const std::string& s,
_Out_ sai_redis_communication_mode_t& value)
{
SWSS_LOG_ENTER();
if (s == REDIS_COMMUNICATION_MODE_REDIS_ASYNC_STRING)
{
value = SAI_REDIS_COMMUNICATION_MODE_REDIS_ASYNC;
}
else if (s == REDIS_COMMUNICATION_MODE_REDIS_SYNC_STRING)
{
value = SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC;
}
else if (s == REDIS_COMMUNICATION_MODE_ZMQ_SYNC_STRING)
{
value = SAI_REDIS_COMMUNICATION_MODE_ZMQ_SYNC;
}
else
{
SWSS_LOG_THROW("enum '%s' not found in sai_redis_communication_mode_t", s.c_str());
}
}
void sai_deserialize_redis_port_attr_id(
_In_ const std::string& s,
_Out_ sai_redis_port_attr_t& value)
{
SWSS_LOG_ENTER();
for (const auto& entry : sai_redis_port_attr_to_name_map)
{
if (s == entry.second)
{
value = entry.first;
return;
}
}
SWSS_LOG_WARN("%s is not found in sai_redis_port_attr_to_name_map.", s.c_str());
sai_deserialize_number(s, value, false);
}
// Link event damping.
void sai_deserialize_redis_link_event_damping_algorithm(
_In_ const std::string& s,
_Out_ sai_redis_link_event_damping_algorithm_t& value)
{
SWSS_LOG_ENTER();
for (const auto& entry : sai_redis_link_event_damping_algorithm_to_name_map)
{
if (s == entry.second)
{
value = entry.first;
return;
}
}
SWSS_LOG_WARN("%s is not found in sai_redis_link_event_damping_algorithm_to_name_map.", s.c_str());
sai_deserialize_number(s, value, false);
}
void sai_deserialize_redis_link_event_damping_aied_config(
_In_ const std::string& s,
_Out_ sai_redis_link_event_damping_algo_aied_config_t& value)
{
SWSS_LOG_ENTER();
json j = json::parse(s);
sai_deserialize_number(j["max_suppress_time"], value.max_suppress_time, false);
sai_deserialize_number(j["suppress_threshold"], value.suppress_threshold, false);
sai_deserialize_number(j["reuse_threshold"], value.reuse_threshold, false);
sai_deserialize_number(j["decay_half_life"], value.decay_half_life, false);
sai_deserialize_number(j["flap_penalty"], value.flap_penalty, false);
}
/**
* @brief deserialize the stats capability list
*
* Iterates thru stat_enum_str and populate
* the stats_capability with respective
* stat_enum (String to Enum conversion).
* Also iterates thru stat_modes_str and populate
* the stats_capability with respective
* stat_modes (String to Enum conversion)
*
* @param stats_capability stats capability enum list
* @param stat_enum_str SAI stat enum list as string
* @param stat_modes_str SAI stat mode list as string
* @return Void
*/
void sai_deserialize_stats_capability_list(
_Inout_ sai_stat_capability_list_t *stats_capability,
_In_ const std::string& stat_enum_str,
_In_ const std::string& stat_modes_str)
{
SWSS_LOG_ENTER();
if (stats_capability == NULL)
{
SWSS_LOG_THROW("Stats capability pointer in deserialize is NULL");
}
uint32_t num_capabilities = stats_capability->count;
size_t stat_enum_position = 0;
size_t stat_modes_position = 0;
for (uint32_t i = 0; i < num_capabilities; i++)
{
/* 1. Populate stat_enum */
size_t old_stat_enum_position = stat_enum_position;
stat_enum_position = stat_enum_str.find(",", old_stat_enum_position);
std::string stat_enum = stat_enum_str.substr(old_stat_enum_position,
stat_enum_position - old_stat_enum_position);
stats_capability->list[i].stat_enum = std::stoi(stat_enum);
/* We have run out of values to add to our list */
if (stat_enum_position == std::string::npos)
{
if (num_capabilities != i + 1)
{
SWSS_LOG_THROW("Lesser stat_enums than expected: expected %d, received %d",
num_capabilities, i+1);
}
break;
}
/* 2. Populate stat_modes */
size_t old_stat_modes_position = stat_modes_position;
stat_modes_position = stat_modes_str.find(",", old_stat_modes_position);
std::string stat_modes = stat_modes_str.substr(old_stat_modes_position,
stat_modes_position - old_stat_modes_position);
stats_capability->list[i].stat_modes = std::stoi(stat_modes);
/* We have run out of values to add to our list */
if (stat_modes_position == std::string::npos)
{
if (num_capabilities != i + 1)
{
SWSS_LOG_THROW("Lesser stat_modes than expected: expected %d, received %d",
num_capabilities, i+1);
}
break;
}
/* Skip the commas */
stat_enum_position++;
stat_modes_position++;
}
}