diff --git a/common/redisclient.cpp b/common/redisclient.cpp index 0821d0549b06..c996356a3570 100644 --- a/common/redisclient.cpp +++ b/common/redisclient.cpp @@ -13,10 +13,10 @@ int64_t RedisClient::del(std::string key) { char *temp; int len = redisFormatCommand(&temp, "DEL %s", key.c_str()); - std::string del(temp, len); + std::string sdel(temp, len); free(temp); - RedisReply r(m_db, del, REDIS_REPLY_INTEGER, true); + RedisReply r(m_db, sdel, REDIS_REPLY_INTEGER, true); if (r.getContext()->type != REDIS_REPLY_INTEGER) throw std::runtime_error("DEL operation failed"); @@ -28,10 +28,10 @@ int64_t RedisClient::hdel(std::string key, std::string field) { char *temp; int len = redisFormatCommand(&temp, "HDEL %s %s", key.c_str(), field.c_str()); - std::string hdel(temp, len); + std::string shdel(temp, len); free(temp); - RedisReply r(m_db, hdel, REDIS_REPLY_INTEGER, true); + RedisReply r(m_db, shdel, REDIS_REPLY_INTEGER, true); if (r.getContext()->type != REDIS_REPLY_INTEGER) throw std::runtime_error("HDEL operation failed"); @@ -43,10 +43,10 @@ void RedisClient::hset(std::string key, std::string field, std::string value) { char *temp; int len = redisFormatCommand(&temp, "HSET %s %s %s", key.c_str(), field.c_str(), value.c_str()); - std::string hset(temp, len); + std::string shset(temp, len); free(temp); - RedisReply r(m_db, hset, REDIS_REPLY_INTEGER, true); + RedisReply r(m_db, shset, REDIS_REPLY_INTEGER, true); if (r.getContext()->type != REDIS_REPLY_INTEGER) throw std::runtime_error("HSET operation failed"); @@ -56,10 +56,10 @@ void RedisClient::set(std::string key, std::string value) { char *temp; int len = redisFormatCommand(&temp, "SET %s %s", key.c_str(), value.c_str()); - std::string set(temp, len); + std::string sset(temp, len); free(temp); - RedisReply r(m_db, set, REDIS_REPLY_STATUS, true); + RedisReply r(m_db, sset, REDIS_REPLY_STATUS, true); if (r.getContext()->type != REDIS_REPLY_STATUS) throw std::runtime_error("SET operation failed"); @@ -72,10 +72,10 @@ std::unordered_map RedisClient::hgetall(std::string ke char *temp; int len = redisFormatCommand(&temp, "HGETALL %s", key.c_str()); - std::string incr(temp, len); + std::string sincr(temp, len); free(temp); - RedisReply r(m_db, incr, REDIS_REPLY_ARRAY, true); + RedisReply r(m_db, sincr, REDIS_REPLY_ARRAY, true); if (r.getContext()->type != REDIS_REPLY_ARRAY) throw std::runtime_error("HGETALL operation failed"); @@ -95,10 +95,10 @@ std::vector RedisClient::keys(std::string key) char *temp; int len = redisFormatCommand(&temp, "KEYS %s", key.c_str()); - std::string keys(temp, len); + std::string skeys(temp, len); free(temp); - RedisReply r(m_db, keys, REDIS_REPLY_ARRAY, true); + RedisReply r(m_db, skeys, REDIS_REPLY_ARRAY, true); if (r.getContext()->type != REDIS_REPLY_ARRAY) throw std::runtime_error("KEYS operation failed"); @@ -116,10 +116,10 @@ int64_t RedisClient::incr(std::string key) char *temp; int len = redisFormatCommand(&temp, "INCR %s", key.c_str()); - std::string incr(temp, len); + std::string sincr(temp, len); free(temp); - RedisReply r(m_db, incr, REDIS_REPLY_INTEGER, true); + RedisReply r(m_db, sincr, REDIS_REPLY_INTEGER, true); if (r.getContext()->type != REDIS_REPLY_INTEGER) throw std::runtime_error("INCR command failed"); @@ -132,10 +132,10 @@ int64_t RedisClient::decr(std::string key) char *temp; int len = redisFormatCommand(&temp, "DECR %s", key.c_str()); - std::string decr(temp, len); + std::string sdecr(temp, len); free(temp); - RedisReply r(m_db, decr, REDIS_REPLY_INTEGER, true); + RedisReply r(m_db, sdecr, REDIS_REPLY_INTEGER, true); if (r.getContext()->type != REDIS_REPLY_INTEGER) throw std::runtime_error("DECR command failed"); @@ -148,12 +148,12 @@ std::shared_ptr RedisClient::get(std::string key) char *temp; int len = redisFormatCommand(&temp, "GET %s", key.c_str()); - std::string get(temp, len); + std::string sget(temp, len); free(temp); redisReply *reply; - redisAppendFormattedCommand(m_db->getContext(), get.c_str(), get.length()); + redisAppendFormattedCommand(m_db->getContext(), sget.c_str(), sget.length()); redisGetReply(m_db->getContext(), (void**)&reply); if (!reply) @@ -182,12 +182,12 @@ std::shared_ptr RedisClient::hget(std::string key, std::string fiel char *temp; int len = redisFormatCommand(&temp, "HGET %s %s", key.c_str(), field.c_str()); - std::string hget(temp, len); + std::string shget(temp, len); free(temp); redisReply *reply; - redisAppendFormattedCommand(m_db->getContext(), hget.c_str(), hget.length()); + redisAppendFormattedCommand(m_db->getContext(), shget.c_str(), shget.length()); redisGetReply(m_db->getContext(), (void**)&reply); if (!reply) @@ -222,10 +222,10 @@ int64_t RedisClient::rpush(std::string list, std::string item) char *temp; int len = redisFormatCommand(&temp, "RPUSH %s %s", list.c_str(), item.c_str()); - std::string rpush(temp, len); + std::string srpush(temp, len); free(temp); - RedisReply r(m_db, rpush, REDIS_REPLY_INTEGER, true); + RedisReply r(m_db, srpush, REDIS_REPLY_INTEGER, true); if (r.getContext()->type != REDIS_REPLY_INTEGER) throw std::runtime_error("RPUSH command failed"); @@ -238,12 +238,12 @@ std::shared_ptr RedisClient::blpop(std::string list, int timeout) char *temp; int len = redisFormatCommand(&temp, "BLPOP %s %d", list.c_str(), timeout); - std::string blpop(temp, len); + std::string sblpop(temp, len); free(temp); redisReply *reply; - redisAppendFormattedCommand(m_db->getContext(), blpop.c_str(), blpop.length()); + redisAppendFormattedCommand(m_db->getContext(), sblpop.c_str(), sblpop.length()); redisGetReply(m_db->getContext(), (void**)&reply); if (!reply) diff --git a/common/saiattributelist.cpp b/common/saiattributelist.cpp index 4709ff814bbb..4d112ae75598 100644 --- a/common/saiattributelist.cpp +++ b/common/saiattributelist.cpp @@ -5,9 +5,9 @@ SaiAttributeList::SaiAttributeList( _In_ const std::vector &values, _In_ bool onlyCount) { - uint32_t attr_count = values.size(); + size_t attr_count = values.size(); - for (uint32_t i = 0; i < attr_count; ++i) + for (size_t i = 0; i < attr_count; ++i) { const std::string &str_attr_id = fvField(values[i]); const std::string &str_attr_value = fvValue(values[i]); @@ -44,9 +44,9 @@ SaiAttributeList::SaiAttributeList( SaiAttributeList::~SaiAttributeList() { - uint32_t attr_count = m_attr_list.size(); + size_t attr_count = m_attr_list.size(); - for (uint32_t i = 0; i < attr_count; ++i) + for (size_t i = 0; i < attr_count; ++i) { sai_attribute_t &attr = m_attr_list[i]; @@ -118,5 +118,5 @@ sai_attribute_t* SaiAttributeList::get_attr_list() uint32_t SaiAttributeList::get_attr_count() { - return m_attr_list.size(); + return (uint32_t)m_attr_list.size(); } diff --git a/common/saiserialize.cpp b/common/saiserialize.cpp index fb04a4c599cb..447cd3672ef5 100644 --- a/common/saiserialize.cpp +++ b/common/saiserialize.cpp @@ -168,6 +168,33 @@ sai_serialization_map_t sai_get_serialization_map() map[SAI_OBJECT_TYPE_TRAP_GROUP][SAI_HOSTIF_TRAP_GROUP_ATTR_ADMIN_STATE] = SAI_SERIALIZATION_TYPE_BOOL; map[SAI_OBJECT_TYPE_TRAP_GROUP][SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE] = SAI_SERIALIZATION_TYPE_UINT32; map[SAI_OBJECT_TYPE_TRAP_GROUP][SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER] = SAI_SERIALIZATION_TYPE_OBJECT_ID; + + map[SAI_OBJECT_TYPE_TUNNEL_MAP][SAI_TUNNEL_MAP_ATTR_TYPE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL_MAP][SAI_TUNNEL_MAP_ATTR_MAP_TO_VALUE_LIST] = SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST; + + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_TYPE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE] = SAI_SERIALIZATION_TYPE_OBJECT_ID; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_OVERLAY_INTERFACE] = SAI_SERIALIZATION_TYPE_OBJECT_ID; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_SRC_IP] = SAI_SERIALIZATION_TYPE_IP_ADDRESS; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_TTL_MODE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_TTL_VAL] = SAI_SERIALIZATION_TYPE_UINT8; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_DSCP_MODE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_DSCP_VAL] = SAI_SERIALIZATION_TYPE_UINT8; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_GRE_KEY_VALID] = SAI_SERIALIZATION_TYPE_BOOL; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_GRE_KEY] = SAI_SERIALIZATION_TYPE_UINT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_ECN_MODE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_ENCAP_MAPPERS] = SAI_SERIALIZATION_TYPE_OBJECT_LIST; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_DECAP_ECN_MODE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_DECAP_MAPPERS] = SAI_SERIALIZATION_TYPE_OBJECT_LIST; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_DECAP_TTL_MODE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL][SAI_TUNNEL_ATTR_DECAP_DSCP_MODE] = SAI_SERIALIZATION_TYPE_INT32; + + map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY][SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_VR_ID] = SAI_SERIALIZATION_TYPE_OBJECT_ID; + map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY][SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TYPE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY][SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP] = SAI_SERIALIZATION_TYPE_IP_ADDRESS; + map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY][SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_SRC_IP] = SAI_SERIALIZATION_TYPE_IP_ADDRESS; + map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY][SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TUNNEL_TYPE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY][SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID] = SAI_SERIALIZATION_TYPE_OBJECT_ID; return map; } @@ -398,12 +425,12 @@ void sai_deserialize_buffer( int u = char_to_int(ptr[2 * i]); int l = char_to_int(ptr[2 * i + 1]); - unsigned char c = (u << 4) | l; + int c = (u << 4) | l; - mem[i] = c; + mem[i] = (unsigned char) c; } - index += buffer_size * 2; + index += (int)(buffer_size * 2); } void sai_free_buffer(void *buffer) @@ -554,8 +581,17 @@ sai_status_t sai_serialize_attr_value( sai_serialize_list(attr.value.qosmap, s, countOnly); break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + sai_serialize_list(attr.value.tunnelmap, s, countOnly); + break; + /* ACL FIELD DATA */ + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + sai_serialize_primitive(attr.value.aclfield.enable, s); + sai_serialize_primitive(attr.value.aclfield.data.booldata, s); + break; + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: sai_serialize_primitive(attr.value.aclfield.enable, s); sai_serialize_primitive(attr.value.aclfield.mask.u8, s); @@ -836,8 +872,17 @@ sai_status_t sai_deserialize_attr_value( sai_deserialize_list(s, index, attr.value.qosmap, countOnly); break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + sai_deserialize_list(s, index, attr.value.tunnelmap, countOnly); + break; + /* ACL FIELD DATA */ + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + sai_deserialize_primitive(s, index, attr.value.aclfield.enable); + sai_deserialize_primitive(s, index, attr.value.aclfield.data.booldata); + break; + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: sai_deserialize_primitive(s, index, attr.value.aclfield.enable); sai_deserialize_primitive(s, index, attr.value.aclfield.mask.u8); @@ -1071,8 +1116,15 @@ sai_status_t sai_deserialize_free_attribute_value( sai_free_list(attr.value.qosmap); break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + sai_free_list(attr.value.tunnelmap); + break; + /* ACL FIELD DATA */ + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + break; + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: break; @@ -1409,8 +1461,17 @@ sai_status_t transfer_attribute( transfer_list(src_attr.value.qosmap, dst_attr.value.qosmap, countOnly); break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + transfer_list(src_attr.value.tunnelmap, dst_attr.value.tunnelmap, countOnly); + break; + /* ACL FIELD DATA */ + case SAI_SERIALIZATION_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_SERIALIZATION_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); diff --git a/common/saiserialize.h b/common/saiserialize.h index 809864c4ef2f..b45c2da0afe5 100644 --- a/common/saiserialize.h +++ b/common/saiserialize.h @@ -1,7 +1,9 @@ #ifndef __SAI_SERIALIZE__ #define __SAI_SERIALIZE__ +extern "C" { #include "sai.h" +} #include #include @@ -43,8 +45,8 @@ typedef enum _sai_attr_serialization_type_t SAI_SERIALIZATION_TYPE_UINT32_RANGE, SAI_SERIALIZATION_TYPE_INT32_RANGE, SAI_SERIALIZATION_TYPE_VLAN_LIST, - SAI_SERIALIZATION_TYPE_VLAN_PORT_LIST, + SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL, SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8, SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, @@ -71,7 +73,8 @@ typedef enum _sai_attr_serialization_type_t SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST, SAI_SERIALIZATION_TYPE_PORT_BREAKOUT, - SAI_SERIALIZATION_TYPE_QOS_MAP_LIST + SAI_SERIALIZATION_TYPE_QOS_MAP_LIST, + SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST } sai_attr_serialization_type_t; @@ -184,12 +187,12 @@ void sai_deserialize_primitive( int u = char_to_int(ptr[2 * i]); int l = char_to_int(ptr[2 * i + 1]); - unsigned char c = (u << 4) | l; + int c = (u << 4) | l; - mem[i] = c; + mem[i] = (unsigned char)c; } - index += count * 2; + index += (int)(count * 2); } template diff --git a/lib/inc/sai_redis.h b/lib/inc/sai_redis.h index acd02c84c839..f5017a12f02d 100644 --- a/lib/inc/sai_redis.h +++ b/lib/inc/sai_redis.h @@ -2,6 +2,8 @@ #define __SAI_REDIS__ #include +#include +#include #include "stdint.h" #include "stdio.h" @@ -22,6 +24,10 @@ extern "C" { #include "swss/select.h" #include "swss/logger.h" +#include "sai_meta.h" + +// other global declarations + extern service_method_table_t g_services; extern swss::DBConnector *g_db; extern swss::ProducerTable *g_asicState; @@ -38,6 +44,7 @@ extern swss::Table *g_ridToVid; extern swss::RedisClient *g_redisClient; extern std::mutex g_mutex; +extern std::mutex g_apimutex; extern const sai_acl_api_t redis_acl_api; extern const sai_buffer_api_t redis_buffer_api; @@ -70,6 +77,16 @@ extern sai_switch_notification_t redis_switch_notifications; #define UNREFERENCED_PARAMETER(X) +bool redis_validate_contains_attribute( + _In_ sai_attr_id_t required_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + +const sai_attribute_t* redis_get_attribute_by_id( + _In_ sai_attr_id_t id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + sai_object_id_t redis_create_virtual_object_id( _In_ sai_object_type_t object_type); @@ -80,81 +97,81 @@ void translate_rid_to_vid( // separate methods are needed for vlan to not confuse with object_id +// CREATE + sai_status_t redis_generic_create( _In_ sai_object_type_t object_type, _Out_ sai_object_id_t* object_id, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list); -sai_status_t redis_generic_create( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_create_fdb_entry( _In_ const sai_fdb_entry_t *fdb_entry, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list); -sai_status_t redis_generic_create( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_create_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list); -sai_status_t redis_generic_create( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_create_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list); sai_status_t redis_generic_create_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id); +// REMOVE sai_status_t redis_generic_remove( _In_ sai_object_type_t object_type, _In_ sai_object_id_t object_id); -sai_status_t redis_generic_remove( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_remove_fdb_entry( _In_ const sai_fdb_entry_t* fdb_entry); -sai_status_t redis_generic_remove( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_remove_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry); -sai_status_t redis_generic_remove( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_remove_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry); sai_status_t redis_generic_remove_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id); +// SET sai_status_t redis_generic_set( _In_ sai_object_type_t object_type, _In_ sai_object_id_t object_id, _In_ const sai_attribute_t *attr); -sai_status_t redis_generic_set( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_set_fdb_entry( _In_ const sai_fdb_entry_t *fdb_entry, _In_ const sai_attribute_t *attr); -sai_status_t redis_generic_set( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_set_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, _In_ const sai_attribute_t *attr); -sai_status_t redis_generic_set( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_set_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry, _In_ const sai_attribute_t *attr); sai_status_t redis_generic_set_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id, _In_ const sai_attribute_t *attr); +sai_status_t redis_generic_set_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr); + +sai_status_t redis_generic_set_switch( + _In_ const sai_attribute_t *attr); + +// GET sai_status_t redis_generic_get( _In_ sai_object_type_t object_type, @@ -162,30 +179,35 @@ sai_status_t redis_generic_get( _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list); -sai_status_t redis_generic_get( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_get_fdb_entry( _In_ const sai_fdb_entry_t *fdb_entry, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list); -sai_status_t redis_generic_get( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_get_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list); -sai_status_t redis_generic_get( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_get_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list); sai_status_t redis_generic_get_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list); +sai_status_t redis_generic_get_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list); + +sai_status_t redis_generic_get_switch( + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list); + // notifications void handle_notification( diff --git a/lib/src/Makefile.am b/lib/src/Makefile.am index e51c9eb6c214..d6bde7e72138 100644 --- a/lib/src/Makefile.am +++ b/lib/src/Makefile.am @@ -1,8 +1,42 @@ -# Makefile.am -- Process this file with automake to produce Makefile.in - AM_CPPFLAGS = AM_CPPFLAGS += -I/usr/include/sai -I/usr/include/swss -I$(top_srcdir)/common -AM_CPPFLAGS += -I../inc +AM_CPPFLAGS += -I../inc -I../../meta +AM_CPPFLAGS += \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wdisabled-optimization \ + -Werror \ + -Wextra \ + -Wfloat-equal \ + -Wformat=2 \ + -Wformat-nonliteral \ + -Wformat-security \ + -Wformat-y2k \ + -Wimport \ + -Winit-self \ + -Winline \ + -Winvalid-pch \ + -Wlong-long \ + -Wmissing-field-initializers \ + -Wmissing-format-attribute \ + -Wmissing-include-dirs \ + -Wmissing-noreturn \ + -Wno-aggregate-return \ + -Wno-padded \ + -Wno-switch-enum \ + -Wno-unused-parameter \ + -Wpacked \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wstack-protector \ + -Wstrict-aliasing=2 \ + -Wswitch \ + -Wswitch-default \ + -Wunreachable-code \ + -Wunused \ + -Wvariadic-macros \ + -Wwrite-strings if DEBUG DBGFLAGS = -ggdb -D_DEBUG_ @@ -12,7 +46,8 @@ endif lib_LTLIBRARIES = libsairedis.la -libsairedis_la_SOURCES = sai_redis_acl.cpp \ +libsairedis_la_SOURCES = \ + sai_redis_acl.cpp \ sai_redis_buffer.cpp \ sai_redis_fdb.cpp \ sai_redis_hash.cpp \ @@ -46,8 +81,35 @@ libsairedis_la_SOURCES = sai_redis_acl.cpp \ sai_redis_notifications.cpp \ ../../common/redisclient.cpp \ ../../common/saiserialize.cpp \ - ../../common/saiattributelist.cpp - + ../../common/saiattributelist.cpp \ + ../../meta/sai_meta.cpp \ + ../../meta/sai_meta_sanity.cpp \ + ../../meta/sai_meta_acl.cpp \ + ../../meta/sai_meta_buffer.cpp \ + ../../meta/sai_meta_fdb.cpp \ + ../../meta/sai_meta_hash.cpp \ + ../../meta/sai_meta_hostintf.cpp \ + ../../meta/sai_meta_lag.cpp \ + ../../meta/sai_meta_mirror.cpp \ + ../../meta/sai_meta_neighbor.cpp \ + ../../meta/sai_meta_nexthop.cpp \ + ../../meta/sai_meta_nexthopgroup.cpp \ + ../../meta/sai_meta_policer.cpp \ + ../../meta/sai_meta_port.cpp \ + ../../meta/sai_meta_qosmaps.cpp \ + ../../meta/sai_meta_queue.cpp \ + ../../meta/sai_meta_route.cpp \ + ../../meta/sai_meta_router.cpp \ + ../../meta/sai_meta_routerintf.cpp \ + ../../meta/sai_meta_samplepacket.cpp \ + ../../meta/sai_meta_scheduler.cpp \ + ../../meta/sai_meta_schedulergroup.cpp \ + ../../meta/sai_meta_stp.cpp \ + ../../meta/sai_meta_switch.cpp \ + ../../meta/sai_meta_tunnel.cpp \ + ../../meta/sai_meta_udf.cpp \ + ../../meta/sai_meta_vlan.cpp \ + ../../meta/sai_meta_wred.cpp libsairedis_la_CPPFLAGS = $(DBGFLAGS) $(AM_CPPFLAGS) $(CFLAGS_COMMON) diff --git a/lib/src/sai_redis_acl.cpp b/lib/src/sai_redis_acl.cpp index 2c31fa8b2789..f15ed349da0c 100644 --- a/lib/src/sai_redis_acl.cpp +++ b/lib/src/sai_redis_acl.cpp @@ -1,55 +1,57 @@ #include "sai_redis.h" /** - * Routine Description: - * @brief Create an ACL table + * Routine Description: + * @brief Create an ACL table * - * Arguments: - * @param[out] acl_table_id - the the acl table id - * @param[in] attr_count - number of attributes - * @param[in] attr_list - array of attributes + * Arguments: + * @param[out] acl_table_id - the the acl table id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes * - * Return Values: - * @return SAI_STATUS_SUCCESS on success + * Return Values: + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_create_acl_table( - _Out_ sai_object_id_t* acl_table_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* acl_table_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_ACL_TABLE, - acl_table_id, - attr_count, - attr_list); + SWSS_LOG_ENTER(); - return status; + return meta_sai_create_oid( + SAI_OBJECT_TYPE_ACL_TABLE, + acl_table_id, + attr_count, + attr_list, + &redis_generic_create); } /** - * Routine Description: + * Routine Description: * @brief Delete an ACL table * - * Arguments: + * Arguments: * @param[in] acl_table_id - the acl table id * - * Return Values: - * @return SAI_STATUS_SUCCESS on success + * Return Values: + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_delete_acl_table( - _In_ sai_object_id_t acl_table_id) +sai_status_t redis_remove_acl_table( + _In_ sai_object_id_t acl_table_id) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove( - SAI_OBJECT_TYPE_ACL_TABLE, - acl_table_id); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_oid( + SAI_OBJECT_TYPE_ACL_TABLE, + acl_table_id, + &redis_generic_remove); } /** @@ -61,21 +63,22 @@ sai_status_t redis_delete_acl_table( * @param[in] attr - attribute * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_set_acl_table_attribute( - _In_ sai_object_id_t acl_table_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t acl_table_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_ACL_TABLE, acl_table_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -88,23 +91,24 @@ sai_status_t redis_set_acl_table_attribute( * @param[out] attr_list - array of attributes * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_get_acl_table_attribute( - _In_ sai_object_id_t acl_table_id, - _In_ uint32_t attr_count, - _Out_ sai_attribute_t *attr_list) + _In_ sai_object_id_t acl_table_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_ACL_TABLE, - acl_table_id, - attr_count, - attr_list); + SWSS_LOG_ENTER(); - return status; + return meta_sai_get_oid( + SAI_OBJECT_TYPE_ACL_TABLE, + acl_table_id, + attr_count, + attr_list, + &redis_generic_get); } /** @@ -117,23 +121,24 @@ sai_status_t redis_get_acl_table_attribute( * @param[in] attr_list - array of attributes * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_create_acl_entry( - _Out_ sai_object_id_t *acl_entry_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t *acl_entry_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_ACL_ENTRY, - acl_entry_id, - attr_count, - attr_list); + SWSS_LOG_ENTER(); - return status; + return meta_sai_create_oid( + SAI_OBJECT_TYPE_ACL_ENTRY, + acl_entry_id, + attr_count, + attr_list, + &redis_generic_create); } /** @@ -141,22 +146,23 @@ sai_status_t redis_create_acl_entry( * @brief Delete an ACL entry * * Arguments: - * @param[in] acl_entry_id - the acl entry id + * @param[in] acl_entry_id - the acl entry id * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_delete_acl_entry( - _In_ sai_object_id_t acl_entry_id) +sai_status_t redis_remove_acl_entry( + _In_ sai_object_id_t acl_entry_id) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove( - SAI_OBJECT_TYPE_ACL_ENTRY, - acl_entry_id); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_oid( + SAI_OBJECT_TYPE_ACL_ENTRY, + acl_entry_id, + &redis_generic_remove); } /** @@ -168,21 +174,22 @@ sai_status_t redis_delete_acl_entry( * @param[in] attr - attribute * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_set_acl_entry_attribute( - _In_ sai_object_id_t acl_entry_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t acl_entry_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_ACL_ENTRY, acl_entry_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -195,23 +202,24 @@ sai_status_t redis_set_acl_entry_attribute( * @param[out] attr_list - array of attributes * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_get_acl_entry_attribute( - _In_ sai_object_id_t acl_entry_id, - _In_ uint32_t attr_count, - _Out_ sai_attribute_t *attr_list) + _In_ sai_object_id_t acl_entry_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_ACL_ENTRY, - acl_entry_id, - attr_count, - attr_list); + SWSS_LOG_ENTER(); - return status; + return meta_sai_get_oid( + SAI_OBJECT_TYPE_ACL_ENTRY, + acl_entry_id, + attr_count, + attr_list, + &redis_generic_get); } /** @@ -224,23 +232,24 @@ sai_status_t redis_get_acl_entry_attribute( * @param[in] attr_list - array of attributes * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_create_acl_counter( - _Out_ sai_object_id_t *acl_counter_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t *acl_counter_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_ACL_COUNTER, - acl_counter_id, - attr_count, - attr_list); + SWSS_LOG_ENTER(); - return status; + return meta_sai_create_oid( + SAI_OBJECT_TYPE_ACL_COUNTER, + acl_counter_id, + attr_count, + attr_list, + &redis_generic_create); } /** @@ -248,22 +257,23 @@ sai_status_t redis_create_acl_counter( * @brief Delete an ACL counter * * Arguments: - * @param[in] acl_counter_id - the acl counter id + * @param[in] acl_counter_id - the acl counter id * * Return Values: - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_delete_acl_counter( - _In_ sai_object_id_t acl_counter_id) +sai_status_t redis_remove_acl_counter( + _In_ sai_object_id_t acl_counter_id) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove( - SAI_OBJECT_TYPE_ACL_COUNTER, - acl_counter_id); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_oid( + SAI_OBJECT_TYPE_ACL_COUNTER, + acl_counter_id, + &redis_generic_remove); } /** @@ -279,17 +289,18 @@ sai_status_t redis_delete_acl_counter( * Failure status code on error */ sai_status_t redis_set_acl_counter_attribute( - _In_ sai_object_id_t acl_counter_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t acl_counter_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_ACL_COUNTER, acl_counter_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -306,37 +317,154 @@ sai_status_t redis_set_acl_counter_attribute( * Failure status code on error */ sai_status_t redis_get_acl_counter_attribute( - _In_ sai_object_id_t acl_counter_id, - _In_ uint32_t attr_count, - _Out_ sai_attribute_t *attr_list) + _In_ sai_object_id_t acl_counter_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_ACL_COUNTER, acl_counter_id, attr_count, - attr_list); + attr_list, + &redis_generic_get); +} + +/** + * Routine Description: + * @brief Create an ACL Range + * + * Arguments: + * @param[out] acl_range_id - the acl range id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_create_acl_range( + _Out_ sai_object_id_t* acl_range_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + std::lock_guard lock(g_apimutex); + + SWSS_LOG_ENTER(); + + return meta_sai_create_oid( + SAI_OBJECT_TYPE_ACL_RANGE, + acl_range_id, + attr_count, + attr_list, + &redis_generic_create); +} + +/** + * Routine Description: + * @brief Remove an ACL Range + * + * Arguments: + * @param[in] acl_range_id - the acl range id + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_remove_acl_range( + _In_ sai_object_id_t acl_range_id) +{ + std::lock_guard lock(g_apimutex); + + SWSS_LOG_ENTER(); + + return meta_sai_remove_oid( + SAI_OBJECT_TYPE_ACL_RANGE, + acl_range_id, + &redis_generic_remove); +} + +/** + * Routine Description: + * @brief Set ACL range attribute + * + * Arguments: + * @param[in] acl_range_id - the acl range id + * @param[in] attr - attribute + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_set_acl_range_attribute( + _In_ sai_object_id_t acl_range_id, + _In_ const sai_attribute_t *attr) +{ + std::lock_guard lock(g_apimutex); + + SWSS_LOG_ENTER(); + + return meta_sai_set_oid( + SAI_OBJECT_TYPE_ACL_RANGE, + acl_range_id, + attr, + &redis_generic_set); +} + +/** + * Routine Description: + * @brief Get ACL range attribute + * + * Arguments: + * @param[in] acl_range_id - acl range id + * @param[in] attr_count - number of attributes + * @param[out] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_get_acl_range_attribute( + _In_ sai_object_id_t acl_range_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + std::lock_guard lock(g_apimutex); - return status; + SWSS_LOG_ENTER(); + + return meta_sai_get_oid( + SAI_OBJECT_TYPE_ACL_RANGE, + acl_range_id, + attr_count, + attr_list, + &redis_generic_get); } /** - * @brief acl methods table retrieved with sai_api_query() + * @brief acl methods table retrieved with sai_api_query() */ const sai_acl_api_t redis_acl_api = { redis_create_acl_table, - redis_delete_acl_table, + redis_remove_acl_table, redis_set_acl_table_attribute, redis_get_acl_table_attribute, redis_create_acl_entry, - redis_delete_acl_entry, + redis_remove_acl_entry, redis_set_acl_entry_attribute, redis_get_acl_entry_attribute, redis_create_acl_counter, - redis_delete_acl_counter, + redis_remove_acl_counter, redis_set_acl_counter_attribute, redis_get_acl_counter_attribute, + + redis_create_acl_range, + redis_remove_acl_range, + redis_set_acl_range_attribute, + redis_get_acl_range_attribute, }; diff --git a/lib/src/sai_redis_buffer.cpp b/lib/src/sai_redis_buffer.cpp index 747fb285ecab..97bb818c374a 100644 --- a/lib/src/sai_redis_buffer.cpp +++ b/lib/src/sai_redis_buffer.cpp @@ -9,17 +9,18 @@ * Failure status code on error */ sai_status_t redis_set_ingress_priority_group_attr( - _In_ sai_object_id_t ingress_pg_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t ingress_pg_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_PRIORITY_GROUP, ingress_pg_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -32,60 +33,69 @@ sai_status_t redis_set_ingress_priority_group_attr( * Failure status code on error */ sai_status_t redis_get_ingress_priority_group_attr( - _In_ sai_object_id_t ingress_pg_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_object_id_t ingress_pg_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_PRIORITY_GROUP, ingress_pg_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** -* @brief Get ingress priority group statistics counters. -* -* @param[in] ingress_pg_id ingress priority group id -* @param[in] counter_ids specifies the array of counter ids -* @param[in] number_of_counters number of counters in the array -* @param[out] counters array of resulting counter values. -* -* @return SAI_STATUS_SUCCESS on success -* Failure status code on error -*/ + * @brief Get ingress priority group statistics counters. + * + * @param[in] ingress_pg_id ingress priority group id + * @param[in] counter_ids specifies the array of counter ids + * @param[in] number_of_counters number of counters in the array + * @param[out] counters array of resulting counter values. + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_get_ingress_priority_group_stats( - _In_ sai_object_id_t ingress_pg_id, - _In_ const sai_ingress_priority_group_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) + _In_ sai_object_id_t ingress_pg_id, + _In_ const sai_ingress_priority_group_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t* counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } /** -* @brief Clear ingress priority group statistics counters. -* -* @param[in] ingress_pg_id ingress priority group id -* @param[in] counter_ids specifies the array of counter ids -* @param[in] number_of_counters number of counters in the array -* -* @return SAI_STATUS_SUCCESS on success -* Failure status code on error -*/ + * @brief Clear ingress priority group statistics counters. + * + * @param[in] ingress_pg_id ingress priority group id + * @param[in] counter_ids specifies the array of counter ids + * @param[in] number_of_counters number of counters in the array + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_clear_ingress_priority_group_stats( - _In_ sai_object_id_t ingress_pg_id, - _In_ const sai_ingress_priority_group_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters) + _In_ sai_object_id_t ingress_pg_id, + _In_ const sai_ingress_priority_group_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } @@ -98,19 +108,20 @@ sai_status_t redis_clear_ingress_priority_group_stats( * Failure status code on error */ sai_status_t redis_create_buffer_pool( - _Out_ sai_object_id_t* pool_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* pool_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_BUFFER_POOL, - pool_id, - attr_count, - attr_list); + SWSS_LOG_ENTER(); - return status; + return meta_sai_create_oid( + SAI_OBJECT_TYPE_BUFFER_POOL, + pool_id, + attr_count, + attr_list, + &redis_generic_create); } /** @@ -120,15 +131,16 @@ sai_status_t redis_create_buffer_pool( * Failure status code on error */ sai_status_t redis_remove_buffer_pool( - _In_ sai_object_id_t pool_id) + _In_ sai_object_id_t pool_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_BUFFER_POOL, - pool_id); - - return status; + pool_id, + &redis_generic_remove); } /** @@ -139,17 +151,18 @@ sai_status_t redis_remove_buffer_pool( * Failure status code on error */ sai_status_t redis_set_buffer_pool_attr( - _In_ sai_object_id_t pool_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t pool_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_BUFFER_POOL, pool_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -161,40 +174,45 @@ sai_status_t redis_set_buffer_pool_attr( * Failure status code on error */ sai_status_t redis_get_buffer_pool_attr( - _In_ sai_object_id_t pool_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_object_id_t pool_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_BUFFER_POOL, pool_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** -* @brief Get buffer pool statistics counters. -* -* @param[in] pool_id buffer pool id -* @param[in] counter_ids specifies the array of counter ids -* @param[in] number_of_counters number of counters in the array -* @param[out] counters array of resulting counter values. -* -* @return SAI_STATUS_SUCCESS on success -* Failure status code on error -*/ + * @brief Get buffer pool statistics counters. + * + * @param[in] pool_id buffer pool id + * @param[in] counter_ids specifies the array of counter ids + * @param[in] number_of_counters number of counters in the array + * @param[out] counters array of resulting counter values. + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_get_buffer_pool_stats( - _In_ sai_object_id_t pool_id, - _In_ const sai_buffer_pool_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) + _In_ sai_object_id_t pool_id, + _In_ const sai_buffer_pool_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t* counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } @@ -207,19 +225,20 @@ sai_status_t redis_get_buffer_pool_stats( * Failure status code on error */ sai_status_t redis_create_buffer_profile( - _Out_ sai_object_id_t* buffer_profile_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* buffer_profile_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_BUFFER_PROFILE, buffer_profile_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -229,15 +248,16 @@ sai_status_t redis_create_buffer_profile( * Failure status code on error */ sai_status_t redis_remove_buffer_profile( - _In_ sai_object_id_t buffer_profile_id) + _In_ sai_object_id_t buffer_profile_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_BUFFER_PROFILE, - buffer_profile_id); - - return status; + buffer_profile_id, + &redis_generic_remove); } /** @@ -248,17 +268,18 @@ sai_status_t redis_remove_buffer_profile( * Failure status code on error */ sai_status_t redis_set_buffer_profile_attr( - _In_ sai_object_id_t buffer_profile_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t buffer_profile_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_BUFFER_PROFILE, buffer_profile_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -270,19 +291,20 @@ sai_status_t redis_set_buffer_profile_attr( * Failure status code on error */ sai_status_t redis_get_buffer_profile_attr( - _In_ sai_object_id_t buffer_profile_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_object_id_t buffer_profile_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_BUFFER_PROFILE, buffer_profile_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** diff --git a/lib/src/sai_redis_fdb.cpp b/lib/src/sai_redis_fdb.cpp index 38d21ff232c9..5a828ec80274 100644 --- a/lib/src/sai_redis_fdb.cpp +++ b/lib/src/sai_redis_fdb.cpp @@ -13,20 +13,20 @@ * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_create_fdb_entry( - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_fdb_entry( + _In_ const sai_fdb_entry_t *fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_FDB, + return meta_sai_create_fdb_entry( fdb_entry, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create_fdb_entry); } /** @@ -40,16 +40,16 @@ sai_status_t redis_create_fdb_entry( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_fdb_entry( - _In_ const sai_fdb_entry_t* fdb_entry) +sai_status_t redis_remove_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove( - SAI_OBJECT_TYPE_FDB, - fdb_entry); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_fdb_entry( + fdb_entry, + &redis_generic_remove_fdb_entry); } /** @@ -62,18 +62,18 @@ sai_status_t redis_remove_fdb_entry( * * Return Values: * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_fdb_entry_attribute( - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_fdb_entry_attribute( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_FDB, + return meta_sai_set_fdb_entry( fdb_entry, - attr); - - return status; + attr, + &redis_generic_set_fdb_entry); } /** @@ -89,20 +89,20 @@ sai_status_t redis_set_fdb_entry_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_fdb_entry_attribute( - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_fdb_entry_attribute( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_FDB, + return meta_sai_get_fdb_entry( fdb_entry, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get_fdb_entry); } /** @@ -117,31 +117,17 @@ sai_status_t redis_get_fdb_entry_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_flush_fdb_entries( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_flush_fdb_entries( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - return SAI_STATUS_NOT_IMPLEMENTED; -} + SWSS_LOG_ERROR("not implemented"); -/** - * Routine Description: - * @brief FDB notifications - * - * Arguments: - * @param[in] count - number of notifications - * @param[in] data - pointer to fdb event notification data array - * - * Return Values: - * None - */ -void redis_fdb_event_notification( - _In_ uint32_t count, - _In_ sai_fdb_event_notification_data_t *data) -{ - SWSS_LOG_ENTER(); + return SAI_STATUS_NOT_IMPLEMENTED; } /** diff --git a/lib/src/sai_redis_generic_create.cpp b/lib/src/sai_redis_generic_create.cpp index 2217574d4abd..56905422ddca 100644 --- a/lib/src/sai_redis_generic_create.cpp +++ b/lib/src/sai_redis_generic_create.cpp @@ -26,6 +26,22 @@ sai_object_id_t redis_create_virtual_object_id( return objectId; } +/** + * Routine Description: + * @brief Query sai object type. + * + * Arguments: + * @param[in] sai_object_id + * + * Return Values: + * @return Return SAI_OBJECT_TYPE_NULL when sai_object_id is not valid. + * Otherwise, return a valid sai object type SAI_OBJECT_TYPE_XXX + */ +sai_object_type_t sai_object_type_query(_In_ sai_object_id_t sai_object_id) +{ + return (sai_object_type_t)(sai_object_id >> 48); +} + /** * Routine Description: * @brief Generic create method @@ -49,9 +65,38 @@ sai_status_t internal_redis_generic_create( SWSS_LOG_ENTER(); + if (attr_count > 0 && attr_list == NULL) + { + SWSS_LOG_ERROR("attribute list is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check for duplicated id entries on attribute list + // this needs to be checked only on create API + // since set always use one attribute, and get api + // is not making any changes so attributes can be + // duplicated + + std::set attr_ids; + + for (uint32_t i = 0; i < attr_count; ++i) + { + sai_attr_id_t id = attr_list[i].id; + + if (attr_ids.find(id) != attr_ids.end()) + { + SWSS_LOG_ERROR("duplicated attribute id %d on attribute list for object type %d", id, object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + + attr_ids.insert(id); + } + std::vector entry = SaiAttributeList::serialize_attr_list( - object_type, - attr_count, + object_type, + attr_count, attr_list, false); @@ -100,6 +145,21 @@ sai_status_t redis_generic_create( { SWSS_LOG_ENTER(); + if (object_id == NULL) + { + SWSS_LOG_ERROR("object id pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (object_type <= SAI_OBJECT_TYPE_NULL || object_type >= SAI_OBJECT_TYPE_MAX) + { + // this is sanity check for code bugs + SWSS_LOG_ERROR("trying to create invalid object type: %d", object_type); + + return SAI_STATUS_FAILURE; + } + // on create vid is put in db by syncd *object_id = redis_create_virtual_object_id(object_type); @@ -115,8 +175,7 @@ sai_status_t redis_generic_create( return status; } -sai_status_t redis_generic_create( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_create_fdb_entry( _In_ const sai_fdb_entry_t *fdb_entry, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) @@ -127,7 +186,7 @@ sai_status_t redis_generic_create( sai_serialize_primitive(*fdb_entry, str_fdb_entry); sai_status_t status = internal_redis_generic_create( - object_type, + SAI_OBJECT_TYPE_FDB, str_fdb_entry, attr_count, attr_list); @@ -135,20 +194,18 @@ sai_status_t redis_generic_create( return status; } -sai_status_t redis_generic_create( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_create_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - // rif_id must be valid virtual id std::string str_neighbor_entry; sai_serialize_neighbor_entry(*neighbor_entry, str_neighbor_entry); sai_status_t status = internal_redis_generic_create( - object_type, + SAI_OBJECT_TYPE_NEIGHBOR, str_neighbor_entry, attr_count, attr_list); @@ -156,8 +213,7 @@ sai_status_t redis_generic_create( return status; } -sai_status_t redis_generic_create( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_create_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) @@ -169,7 +225,7 @@ sai_status_t redis_generic_create( sai_serialize_route_entry(*unicast_route_entry, str_route_entry); sai_status_t status = internal_redis_generic_create( - object_type, + SAI_OBJECT_TYPE_ROUTE, str_route_entry, attr_count, attr_list); @@ -178,7 +234,6 @@ sai_status_t redis_generic_create( } sai_status_t redis_generic_create_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id) { SWSS_LOG_ENTER(); @@ -191,7 +246,7 @@ sai_status_t redis_generic_create_vlan( sai_attribute_t dummy_attribute; sai_status_t status = internal_redis_generic_create( - object_type, + SAI_OBJECT_TYPE_VLAN, str_vlan_id, 0, &dummy_attribute); diff --git a/lib/src/sai_redis_generic_get.cpp b/lib/src/sai_redis_generic_get.cpp index 2b4b2117f50b..aad0d587dbb0 100644 --- a/lib/src/sai_redis_generic_get.cpp +++ b/lib/src/sai_redis_generic_get.cpp @@ -66,7 +66,7 @@ sai_status_t internal_redis_generic_get( SWSS_LOG_ENTER(); std::vector entry = SaiAttributeList::serialize_attr_list( - object_type, + object_type, attr_count, attr_list, false); @@ -83,7 +83,7 @@ sai_status_t internal_redis_generic_get( g_redisGetProducer->del(key, "delget"); // wait for response - + swss::Select s; s.addSelectable(g_redisGetConsumer); @@ -104,18 +104,18 @@ sai_status_t internal_redis_generic_get( g_redisGetConsumer->pop(kco); - const std::string &op = kfvOp(kco); - const std::string &key = kfvKey(kco); + const std::string &op = kfvOp(kco); + const std::string &opkey = kfvKey(kco); - SWSS_LOG_DEBUG("response: op = %s, key = %s", key.c_str(), op.c_str()); + SWSS_LOG_DEBUG("response: op = %s, key = %s", opkey.c_str(), op.c_str()); if (op != "getresponse") // ignore non response messages continue; sai_status_t status = internal_redis_get_process( - object_type, - attr_count, - attr_list, + object_type, + attr_count, + attr_list, kco); SWSS_LOG_DEBUG("generic get status: %d", status); @@ -154,6 +154,13 @@ sai_status_t redis_generic_get( { SWSS_LOG_ENTER(); + if (object_id == SAI_NULL_OBJECT_ID && object_type != SAI_OBJECT_TYPE_SWITCH) + { + SWSS_LOG_ERROR("object id is zero on object type %d", object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + std::string str_object_id; sai_serialize_primitive(object_id, str_object_id); @@ -166,8 +173,7 @@ sai_status_t redis_generic_get( return status; } -sai_status_t redis_generic_get( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_get_fdb_entry( _In_ const sai_fdb_entry_t *fdb_entry, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list) @@ -178,7 +184,7 @@ sai_status_t redis_generic_get( sai_serialize_primitive(*fdb_entry, str_fdb_entry); sai_status_t status = internal_redis_generic_get( - object_type, + SAI_OBJECT_TYPE_FDB, str_fdb_entry, attr_count, attr_list); @@ -186,8 +192,7 @@ sai_status_t redis_generic_get( return status; } -sai_status_t redis_generic_get( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_get_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list) @@ -198,7 +203,7 @@ sai_status_t redis_generic_get( sai_serialize_neighbor_entry(*neighbor_entry, str_neighbor_entry); sai_status_t status = internal_redis_generic_get( - object_type, + SAI_OBJECT_TYPE_NEIGHBOR, str_neighbor_entry, attr_count, attr_list); @@ -206,8 +211,7 @@ sai_status_t redis_generic_get( return status; } -sai_status_t redis_generic_get( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_get_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list) @@ -218,7 +222,7 @@ sai_status_t redis_generic_get( sai_serialize_route_entry(*unicast_route_entry, str_route_entry); sai_status_t status = internal_redis_generic_get( - object_type, + SAI_OBJECT_TYPE_ROUTE, str_route_entry, attr_count, attr_list); @@ -227,7 +231,6 @@ sai_status_t redis_generic_get( } sai_status_t redis_generic_get_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list) @@ -238,10 +241,45 @@ sai_status_t redis_generic_get_vlan( sai_serialize_primitive(vlan_id, str_vlan_id); sai_status_t status = internal_redis_generic_get( - object_type, + SAI_OBJECT_TYPE_VLAN, str_vlan_id, attr_count, attr_list); return status; } + +sai_status_t redis_generic_get_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return redis_generic_get( + SAI_OBJECT_TYPE_TRAP, + hostif_trapid, + attr_count, + attr_list); +} + +sai_status_t redis_generic_get_switch( + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t object_id = 0; + + std::string str_object_id; + sai_serialize_primitive(object_id, str_object_id); + + sai_status_t status = internal_redis_generic_get( + SAI_OBJECT_TYPE_SWITCH, + str_object_id, + attr_count, + attr_list); + + return status; +} + diff --git a/lib/src/sai_redis_generic_remove.cpp b/lib/src/sai_redis_generic_remove.cpp index b219400ea138..abb5645df181 100644 --- a/lib/src/sai_redis_generic_remove.cpp +++ b/lib/src/sai_redis_generic_remove.cpp @@ -39,6 +39,13 @@ sai_status_t redis_generic_remove( { SWSS_LOG_ENTER(); + if (object_id == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("object id is zero on object type %d", object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + std::string str_object_id; sai_serialize_primitive(object_id, str_object_id); @@ -49,8 +56,7 @@ sai_status_t redis_generic_remove( return status; } -sai_status_t redis_generic_remove( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_remove_fdb_entry( _In_ const sai_fdb_entry_t* fdb_entry) { SWSS_LOG_ENTER(); @@ -59,31 +65,28 @@ sai_status_t redis_generic_remove( sai_serialize_primitive(*fdb_entry, str_fdb_entry); sai_status_t status = internal_redis_generic_remove( - object_type, + SAI_OBJECT_TYPE_FDB, str_fdb_entry); return status; } -sai_status_t redis_generic_remove( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_remove_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry) { SWSS_LOG_ENTER(); - // rif_id must be valid virtual id std::string str_neighbor_entry; sai_serialize_neighbor_entry(*neighbor_entry, str_neighbor_entry); sai_status_t status = internal_redis_generic_remove( - object_type, + SAI_OBJECT_TYPE_NEIGHBOR, str_neighbor_entry); return status; } -sai_status_t redis_generic_remove( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_remove_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry) { SWSS_LOG_ENTER(); @@ -93,14 +96,13 @@ sai_status_t redis_generic_remove( sai_serialize_route_entry(*unicast_route_entry, str_route_entry); sai_status_t status = internal_redis_generic_remove( - object_type, + SAI_OBJECT_TYPE_ROUTE, str_route_entry); return status; } sai_status_t redis_generic_remove_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id) { SWSS_LOG_ENTER(); @@ -109,7 +111,7 @@ sai_status_t redis_generic_remove_vlan( sai_serialize_primitive(vlan_id, str_vlan_id); sai_status_t status = internal_redis_generic_remove( - object_type, + SAI_OBJECT_TYPE_VLAN, str_vlan_id); return status; diff --git a/lib/src/sai_redis_generic_set.cpp b/lib/src/sai_redis_generic_set.cpp index 908ca70d2a81..c1481c0c7595 100644 --- a/lib/src/sai_redis_generic_set.cpp +++ b/lib/src/sai_redis_generic_set.cpp @@ -23,7 +23,7 @@ sai_status_t internal_redis_generic_set( SWSS_LOG_ENTER(); std::vector entry = SaiAttributeList::serialize_attr_list( - object_type, + object_type, 1, attr, false); @@ -48,6 +48,13 @@ sai_status_t redis_generic_set( { SWSS_LOG_ENTER(); + if (object_id == SAI_NULL_OBJECT_ID && object_type != SAI_OBJECT_TYPE_SWITCH) + { + SWSS_LOG_ERROR("object id is zero on object type %d", object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + std::string str_object_id; sai_serialize_primitive(object_id, str_object_id); @@ -59,8 +66,7 @@ sai_status_t redis_generic_set( return status; } -sai_status_t redis_generic_set( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_set_fdb_entry( _In_ const sai_fdb_entry_t *fdb_entry, _In_ const sai_attribute_t *attr) { @@ -70,15 +76,14 @@ sai_status_t redis_generic_set( sai_serialize_primitive(*fdb_entry, str_fdb_entry); sai_status_t status = internal_redis_generic_set( - object_type, + SAI_OBJECT_TYPE_FDB, str_fdb_entry, attr); return status; } -sai_status_t redis_generic_set( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_set_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, _In_ const sai_attribute_t *attr) { @@ -88,15 +93,14 @@ sai_status_t redis_generic_set( sai_serialize_neighbor_entry(*neighbor_entry, str_neighbor_entry); sai_status_t status = internal_redis_generic_set( - object_type, + SAI_OBJECT_TYPE_NEIGHBOR, str_neighbor_entry, attr); return status; } -sai_status_t redis_generic_set( - _In_ sai_object_type_t object_type, +sai_status_t redis_generic_set_route_entry( _In_ const sai_unicast_route_entry_t* unicast_route_entry, _In_ const sai_attribute_t *attr) { @@ -106,7 +110,7 @@ sai_status_t redis_generic_set( sai_serialize_route_entry(*unicast_route_entry, str_route_entry); sai_status_t status = internal_redis_generic_set( - object_type, + SAI_OBJECT_TYPE_ROUTE, str_route_entry, attr); @@ -114,7 +118,6 @@ sai_status_t redis_generic_set( } sai_status_t redis_generic_set_vlan( - _In_ sai_object_type_t object_type, _In_ sai_vlan_id_t vlan_id, _In_ const sai_attribute_t *attr) { @@ -124,9 +127,39 @@ sai_status_t redis_generic_set_vlan( sai_serialize_primitive(vlan_id, str_vlan_id); sai_status_t status = internal_redis_generic_set( - object_type, + SAI_OBJECT_TYPE_VLAN, str_vlan_id, attr); return status; } + +sai_status_t redis_generic_set_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return redis_generic_set( + SAI_OBJECT_TYPE_TRAP, + hostif_trapid, + attr); +} + +sai_status_t redis_generic_set_switch( + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t object_id = 0; + + std::string str_object_id; + sai_serialize_primitive(object_id, str_object_id); + + sai_status_t status = internal_redis_generic_set( + SAI_OBJECT_TYPE_SWITCH, + str_object_id, + attr); + + return status; +} diff --git a/lib/src/sai_redis_hash.cpp b/lib/src/sai_redis_hash.cpp index 315a615ab0af..b449efe13c49 100644 --- a/lib/src/sai_redis_hash.cpp +++ b/lib/src/sai_redis_hash.cpp @@ -15,19 +15,20 @@ * */ sai_status_t redis_create_hash( - _Out_ sai_object_id_t* hash_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* hash_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_HASH, hash_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -42,15 +43,16 @@ sai_status_t redis_create_hash( * Failure status code on error */ sai_status_t redis_remove_hash( - _In_ sai_object_id_t hash_id) + _In_ sai_object_id_t hash_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_HASH, - hash_id); - - return status; + hash_id, + &redis_generic_remove); } /** @@ -65,18 +67,19 @@ sai_status_t redis_remove_hash( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_hash_attribute( - _In_ sai_object_id_t hash_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_hash_attribute( + _In_ sai_object_id_t hash_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_HASH, hash_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -92,24 +95,25 @@ sai_status_t redis_set_hash_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_hash_attribute( - _In_ sai_object_id_t hash_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_hash_attribute( + _In_ sai_object_id_t hash_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_HASH, hash_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief hash methods, retrieved via sai_api_query() + * @brief hash methods, retrieved via sai_api_query() */ const sai_hash_api_t redis_hash_api = { redis_create_hash, @@ -117,4 +121,3 @@ const sai_hash_api_t redis_hash_api = { redis_set_hash_attribute, redis_get_hash_attribute, }; - diff --git a/lib/src/sai_redis_hostintf.cpp b/lib/src/sai_redis_hostintf.cpp index 26c205b831d2..170479946be9 100644 --- a/lib/src/sai_redis_hostintf.cpp +++ b/lib/src/sai_redis_hostintf.cpp @@ -1,11 +1,12 @@ #include "sai_redis.h" +#include /** * Routine Description: * @brief hostif receive function * * Arguments: - * @param[in] hif_id - host interface id + * @param[in] hif_id - host interface id * @param[out] buffer - packet buffer * @param[in,out] buffer_size - @param[in] allocated buffer size. @param[out] actual packet size in bytes * @param[in,out] attr_count - @param[in] allocated list size. @param[out] number of attributes @@ -20,14 +21,18 @@ * Failure status code on error */ sai_status_t redis_recv_packet( - _In_ sai_object_id_t hif_id, + _In_ sai_object_id_t hif_id, _Out_ void *buffer, _Inout_ sai_size_t *buffer_size, _Inout_ uint32_t *attr_count, _Out_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } @@ -36,7 +41,7 @@ sai_status_t redis_recv_packet( * @brief hostif send function * * Arguments: - * @param[in] hif_id - host interface id. only valid for send through FD channel. Use SAI_NULL_OBJECT_ID for send through CB channel. + * @param[in] hif_id - host interface id. only valid for send through FD channel. Use SAI_NULL_OBJECT_ID for send through CB channel. * @param[in] buffer - packet buffer * @param[in] buffer size - packet size in bytes * @param[in] attr_count - number of attributes @@ -47,70 +52,71 @@ sai_status_t redis_recv_packet( * Failure status code on error */ sai_status_t redis_send_packet( - _In_ sai_object_id_t hif_id, + _In_ sai_object_id_t hif_id, _In_ void *buffer, _In_ sai_size_t buffer_size, _In_ uint32_t attr_count, _In_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } /** -* Routine Description: -* @brief Set user defined trap attribute value. -* -* Arguments: -* @param[in] hostif_user_defined_trap_id - host interface user defined trap id -* @param[in] attr - attribute -* -* Return Values: -* @return SAI_STATUS_SUCCESS on success -* Failure status code on error -*/ + * Routine Description: + * @brief Set user defined trap attribute value. + * + * Arguments: + * @param[in] hostif_user_defined_trap_id - host interface user defined trap id + * @param[in] attr - attribute + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_set_user_defined_trap_attribute( - _In_ sai_hostif_user_defined_trap_id_t hostif_user_defined_trapid, - _In_ const sai_attribute_t *attr) + _In_ sai_hostif_user_defined_trap_id_t hostif_user_defined_trapid, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_TRAP_USER_DEF, - hostif_user_defined_trapid, - attr); + SWSS_LOG_ERROR("not implemented"); - return status; + return SAI_STATUS_NOT_IMPLEMENTED; } /** -* Routine Description: -* @brief Get user defined trap attribute value. -* -* Arguments: -* @param[in] hostif_user_defined_trap_id - host interface user defined trap id -* @param[in] attr_count - number of attributes -* @param[in,out] attr_list - array of attributes -* -* Return Values: -* @return SAI_STATUS_SUCCESS on success -* Failure status code on error -*/ + * Routine Description: + * @brief Get user defined trap attribute value. + * + * Arguments: + * @param[in] hostif_user_defined_trap_id - host interface user defined trap id + * @param[in] attr_count - number of attributes + * @param[in,out] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_get_user_defined_trap_attribute( - _In_ sai_hostif_user_defined_trap_id_t hostif_user_defined_trapid, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_hostif_user_defined_trap_id_t hostif_user_defined_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_TRAP_USER_DEF, - hostif_user_defined_trapid, - attr_count, - attr_list); + SWSS_LOG_ERROR("not implemented"); - return status; + return SAI_STATUS_NOT_IMPLEMENTED; } /** @@ -118,28 +124,29 @@ sai_status_t redis_get_user_defined_trap_attribute( * @brief Create host interface trap group * * Arguments: - * @param[out] hostif_trap_group_id - host interface trap group id - * @param[in] attr_count - number of attributes - * @param[in] attr_list - array of attributes + * @param[out] hostif_trap_group_id - host interface trap group id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes * * Return Values: * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_create_hostif_trap_group( - _Out_ sai_object_id_t *hostif_trap_group_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t *hostif_trap_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_TRAP_GROUP, hostif_trap_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -147,7 +154,7 @@ sai_status_t redis_create_hostif_trap_group( * @brief Remove host interface trap group * * Arguments: - * @param[in] hostif_trap_group_id - host interface trap group id + * @param[in] hostif_trap_group_id - host interface trap group id * * * Return Values: @@ -155,15 +162,16 @@ sai_status_t redis_create_hostif_trap_group( * Failure status code on error */ sai_status_t redis_remove_hostif_trap_group( - _In_ sai_object_id_t hostif_trap_group_id) + _In_ sai_object_id_t hostif_trap_group_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_TRAP_GROUP, - hostif_trap_group_id); - - return status; + hostif_trap_group_id, + &redis_generic_remove); } /** @@ -178,19 +186,19 @@ sai_status_t redis_remove_hostif_trap_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_trap_group_attribute -( - _In_ sai_object_id_t hostif_trap_group_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_trap_group_attribute( + _In_ sai_object_id_t hostif_trap_group_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_TRAP_GROUP, hostif_trap_group_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -208,19 +216,20 @@ sai_status_t redis_set_trap_group_attribute * Failure status code on error */ sai_status_t redis_get_trap_group_attribute( - _In_ sai_object_id_t hostif_trap_group_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_object_id_t hostif_trap_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_TRAP_GROUP, hostif_trap_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -236,17 +245,17 @@ sai_status_t redis_get_trap_group_attribute( * Failure status code on error */ sai_status_t redis_set_trap_attribute( - _In_ sai_hostif_trap_id_t hostif_trapid, - _In_ const sai_attribute_t *attr) + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_TRAP, + return meta_sai_set_trap( hostif_trapid, - attr); - - return status; + attr, + &redis_generic_set_trap); } /** @@ -263,19 +272,19 @@ sai_status_t redis_set_trap_attribute( * Failure status code on error */ sai_status_t redis_get_trap_attribute( - _In_ sai_hostif_trap_id_t hostif_trapid, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_TRAP, + return meta_sai_get_trap( hostif_trapid, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get_trap); } /** @@ -292,19 +301,20 @@ sai_status_t redis_get_trap_attribute( * Failure status code on error */ sai_status_t redis_create_hostif( - _Out_ sai_object_id_t * hif_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t * hif_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_HOST_INTERFACE, hif_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -319,15 +329,16 @@ sai_status_t redis_create_hostif( * Failure status code on error */ sai_status_t redis_remove_hostif( - _In_ sai_object_id_t hif_id) + _In_ sai_object_id_t hif_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_HOST_INTERFACE, - hif_id); - - return status; + hif_id, + &redis_generic_remove); } /** @@ -343,17 +354,18 @@ sai_status_t redis_remove_hostif( * Failure status code on error */ sai_status_t redis_set_hostif_attribute( - _In_ sai_object_id_t hif_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t hif_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_HOST_INTERFACE, hif_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -370,41 +382,20 @@ sai_status_t redis_set_hostif_attribute( * Failure status code on error */ sai_status_t redis_get_hostif_attribute( - _In_ sai_object_id_t hif_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_object_id_t hif_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_HOST_INTERFACE, hif_id, attr_count, - attr_list); - - return status; -} - -/** - * Routine Description: - * @brief hostif receive callback - * - * Arguments: - * @param[in] buffer - packet buffer - * @param[in] buffer_size - actual packet size in bytes - * @param[in] attr_count - number of attributes - * @param[in] attr_list - array of attributes - * - * Return Values: - * None - */ -void redis_packet_event_notification( - _In_ const void *buffer, - _In_ sai_size_t buffer_size, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); + attr_list, + &redis_generic_get); } /** @@ -420,11 +411,13 @@ const sai_hostif_api_t redis_host_interface_api = { redis_remove_hostif_trap_group, redis_set_trap_group_attribute, redis_get_trap_group_attribute, + redis_set_trap_attribute, redis_get_trap_attribute, + redis_set_user_defined_trap_attribute, redis_get_user_defined_trap_attribute, + redis_recv_packet, redis_send_packet, }; - diff --git a/lib/src/sai_redis_interfacequery.cpp b/lib/src/sai_redis_interfacequery.cpp index 7b1749fa0aca..938b252e5cad 100644 --- a/lib/src/sai_redis_interfacequery.cpp +++ b/lib/src/sai_redis_interfacequery.cpp @@ -3,6 +3,7 @@ #include std::mutex g_mutex; +std::mutex g_apimutex; service_method_table_t g_services; bool g_apiInitialized = false; diff --git a/lib/src/sai_redis_lag.cpp b/lib/src/sai_redis_lag.cpp index a00ce6f6de61..4b88928b38cf 100644 --- a/lib/src/sai_redis_lag.cpp +++ b/lib/src/sai_redis_lag.cpp @@ -1,192 +1,237 @@ #include "sai_redis.h" - -/* - \brief Create LAG - \param[out] lag_id LAG id - \param[in] attr_count number of attributes - \param[in] attr_list array of attributes - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ +/** + * Routine Description: + * @brief Create LAG + * + * Arguments: + * @param[out] lag_id - LAG id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_create_lag( - _Out_ sai_object_id_t* lag_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* lag_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_LAG, lag_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } -/* - \brief Remove LAG - \param[in] lag_id LAG id - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ +/** + * Routine Description: + * @brief Remove LAG + * + * Arguments: + * @param[in] lag_id - LAG id + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_remove_lag( - _In_ sai_object_id_t lag_id) + _In_ sai_object_id_t lag_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_LAG, - lag_id); - - return status; + lag_id, + &redis_generic_remove); } -/* - \brief Set LAG Attribute - \param[in] lag_id LAG id - \param[in] attr Structure containing ID and value to be set - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ -sai_status_t redis_set_lag_attribute( - _In_ sai_object_id_t lag_id, - _In_ const sai_attribute_t *attr) +/** + * Routine Description: + * @brief Set LAG attribute + * + * Arguments: + * @param[in] lag_id - LAG id + * @param[in] attr - Structure containing ID and value to be set + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_set_lag_attribute( + _In_ sai_object_id_t lag_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_LAG, lag_id, - attr); - - return status; + attr, + &redis_generic_set); } -/* - \brief Get LAG Attribute - \param[in] lag_id LAG id - \param[in] attr_count Number of attributes to be get - \param[in,out] attr_list List of structures containing ID and value to be get - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ - -sai_status_t redis_get_lag_attribute( - _In_ sai_object_id_t lag_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +/** + * Routine Description: + * @brief Get LAG attribute + * + * Arguments: + * @param[in] lag_id - LAG id + * @param[in] attr_count - number of attributes + * @param[inout] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_get_lag_attribute( + _In_ sai_object_id_t lag_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_LAG, lag_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } -/* - \brief Create LAG Member - \param[out] lag_member_id LAG Member id - \param[in] attr_count number of attributes - \param[in] attr_list array of attributes - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ +/** + * Routine Description: + * @brief Create LAG member + * + * Arguments: + * @param[out] lag_member_id - LAG member id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_create_lag_member( - _Out_ sai_object_id_t* lag_member_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* lag_member_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_LAG_MEMBER, lag_member_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } -/* - \brief Remove LAG Member - \param[in] lag_member_id LAG Member id - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ +/** + * Routine Description: + * @brief Remove LAG member + * + * Arguments: + * @param[in] lag_member_id - lag member id + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_remove_lag_member( - _In_ sai_object_id_t lag_member_id) + _In_ sai_object_id_t lag_member_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_LAG_MEMBER, - lag_member_id); - - return status; + lag_member_id, + &redis_generic_remove); } -/* - \brief Set LAG Member Attribute - \param[in] lag_member_id LAG Member id - \param[in] attr Structure containing ID and value to be set - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ -sai_status_t redis_set_lag_member_attribute( - _In_ sai_object_id_t lag_member_id, - _In_ const sai_attribute_t *attr) +/** + * Routine Description: + * @brief Set LAG member attribute + * + * Arguments: + * @param[in] lag_member_id - LAG member id + * @param[in] attr - attribute + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_set_lag_member_attribute( + _In_ sai_object_id_t lag_member_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_LAG_MEMBER, lag_member_id, - attr); - - return status; + attr, + &redis_generic_set); } -/* - \brief Get LAG Member Attribute - \param[in] lag_member_id LAG Member id - \param[in] attr_count Number of attributes to be get - \param[in,out] attr_list List of structures containing ID and value to be get - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ - -sai_status_t redis_get_lag_member_attribute( - _In_ sai_object_id_t lag_member_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +/** + * Routine Description: + * @brief Get LAG attribute + * + * Arguments: + * @param[in] lag_member_id - LAG member id + * @param[in] attr_count - number of attributes + * @param[inout] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_get_lag_member_attribute( + _In_ sai_object_id_t lag_member_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_LAG_MEMBER, lag_member_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** * @brief LAG methods table retrieved with sai_api_query() */ const sai_lag_api_t redis_lag_api = { - redis_create_lag, - redis_remove_lag, - redis_set_lag_attribute, - redis_get_lag_attribute, - redis_create_lag_member, - redis_remove_lag_member, - redis_set_lag_member_attribute, - redis_get_lag_member_attribute, + redis_create_lag, + redis_remove_lag, + redis_set_lag_attribute, + redis_get_lag_attribute, + redis_create_lag_member, + redis_remove_lag_member, + redis_set_lag_member_attribute, + redis_get_lag_member_attribute, }; diff --git a/lib/src/sai_redis_mirror.cpp b/lib/src/sai_redis_mirror.cpp index 4a328d6468c9..3c546e031b08 100644 --- a/lib/src/sai_redis_mirror.cpp +++ b/lib/src/sai_redis_mirror.cpp @@ -7,22 +7,23 @@ * @param[in] attr_count Number of attributes * @param[in] attr_list Value of attributes * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_create_mirror_session( +sai_status_t redis_create_mirror_session( _Out_ sai_object_id_t *session_id, - _In_ uint32_t attr_count, + _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_MIRROR, session_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -30,18 +31,19 @@ sai_status_t redis_create_mirror_session( * * @param[in] session_id Port mirror session id * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_remove_mirror_session( +sai_status_t redis_remove_mirror_session( _In_ sai_object_id_t session_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_MIRROR, - session_id); - - return status; + session_id, + &redis_generic_remove); } /** @@ -50,20 +52,21 @@ sai_status_t redis_remove_mirror_session( * @param[in] session_id Port mirror session id * @param[in] attr Value of attribute * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_set_mirror_session_attribute( - _In_ sai_object_id_t session_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_mirror_session_attribute( + _In_ sai_object_id_t session_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_MIRROR, session_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -73,22 +76,23 @@ sai_status_t redis_set_mirror_session_attribute( * @param[in] attr_count Number of attributes * @param[inout] attr_list Value of attribute * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_get_mirror_session_attribute( +sai_status_t redis_get_mirror_session_attribute( _In_ sai_object_id_t session_id, - _In_ uint32_t attr_count, + _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_MIRROR, session_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** diff --git a/lib/src/sai_redis_neighbor.cpp b/lib/src/sai_redis_neighbor.cpp index 1b3901d72dfd..d113d65e70ea 100644 --- a/lib/src/sai_redis_neighbor.cpp +++ b/lib/src/sai_redis_neighbor.cpp @@ -15,20 +15,20 @@ * * Note: IP address expected in Network Byte Order. */ -sai_status_t redis_create_neighbor_entry( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_NEIGHBOR, + return meta_sai_create_neighbor_entry( neighbor_entry, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create_neighbor_entry); } /** @@ -44,16 +44,16 @@ sai_status_t redis_create_neighbor_entry( * * Note: IP address expected in Network Byte Order. */ -sai_status_t redis_remove_neighbor_entry( - _In_ const sai_neighbor_entry_t* neighbor_entry) +sai_status_t redis_remove_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove( - SAI_OBJECT_TYPE_NEIGHBOR, - neighbor_entry); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_neighbor_entry( + neighbor_entry, + &redis_generic_remove_neighbor_entry); } /** @@ -68,18 +68,18 @@ sai_status_t redis_remove_neighbor_entry( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_neighbor_attribute( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_neighbor_attribute( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_NEIGHBOR, + return meta_sai_set_neighbor_entry( neighbor_entry, - attr); - - return status; + attr, + &redis_generic_set_neighbor_entry); } /** @@ -95,20 +95,20 @@ sai_status_t redis_set_neighbor_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_neighbor_attribute( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_neighbor_attribute( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_NEIGHBOR, + return meta_sai_get_neighbor_entry( neighbor_entry, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get_neighbor_entry); } /** @@ -130,7 +130,7 @@ sai_status_t redis_remove_all_neighbor_entries(void) } /** - * @brief neighbor table methods, retrieved via sai_api_query() + * @brief neighbor table methods, retrieved via sai_api_query() */ const sai_neighbor_api_t redis_neighbor_api = { redis_create_neighbor_entry, diff --git a/lib/src/sai_redis_nexthop.cpp b/lib/src/sai_redis_nexthop.cpp index 45339305b708..10d38d00203d 100644 --- a/lib/src/sai_redis_nexthop.cpp +++ b/lib/src/sai_redis_nexthop.cpp @@ -15,20 +15,21 @@ * * Note: IP address expected in Network Byte Order. */ -sai_status_t redis_create_next_hop( - _Out_ sai_object_id_t* next_hop_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_next_hop( + _Out_ sai_object_id_t* next_hop_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_NEXT_HOP, next_hop_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -42,16 +43,17 @@ sai_status_t redis_create_next_hop( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_next_hop( - _In_ sai_object_id_t next_hop_id) +sai_status_t redis_remove_next_hop( + _In_ sai_object_id_t next_hop_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_NEXT_HOP, - next_hop_id); - - return status; + next_hop_id, + &redis_generic_remove); } /** @@ -66,18 +68,19 @@ sai_status_t redis_remove_next_hop( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_next_hop_attribute( - _In_ sai_object_id_t next_hop_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_next_hop_attribute( + _In_ sai_object_id_t next_hop_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_NEXT_HOP, next_hop_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -93,24 +96,25 @@ sai_status_t redis_set_next_hop_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_next_hop_attribute( - _In_ sai_object_id_t next_hop_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_next_hop_attribute( + _In_ sai_object_id_t next_hop_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_NEXT_HOP, next_hop_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief Next Hop methods table retrieved with sai_api_query() + * @brief Next Hop methods table retrieved with sai_api_query() */ const sai_next_hop_api_t redis_next_hop_api = { redis_create_next_hop, diff --git a/lib/src/sai_redis_nexthopgroup.cpp b/lib/src/sai_redis_nexthopgroup.cpp index 8eee934e0561..64b2214bbc5e 100644 --- a/lib/src/sai_redis_nexthopgroup.cpp +++ b/lib/src/sai_redis_nexthopgroup.cpp @@ -13,25 +13,26 @@ * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_create_next_hop_group( - _Out_ sai_object_id_t* next_hop_group_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_next_hop_group( + _Out_ sai_object_id_t* next_hop_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_NEXT_HOP_GROUP, next_hop_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** * Routine Description: - * @brief Remove next hop group + * @brief Remove next hop group * * Arguments: * @param[in] next_hop_group_id - next hop group id @@ -40,16 +41,17 @@ sai_status_t redis_create_next_hop_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_next_hop_group( - _In_ sai_object_id_t next_hop_group_id) +sai_status_t redis_remove_next_hop_group( + _In_ sai_object_id_t next_hop_group_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_NEXT_HOP_GROUP, - next_hop_group_id); - - return status; + next_hop_group_id, + &redis_generic_remove); } /** @@ -64,18 +66,19 @@ sai_status_t redis_remove_next_hop_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_next_hop_group_attribute( - _In_ sai_object_id_t next_hop_group_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_next_hop_group_attribute( + _In_ sai_object_id_t next_hop_group_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_NEXT_HOP_GROUP, next_hop_group_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -91,25 +94,26 @@ sai_status_t redis_set_next_hop_group_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_next_hop_group_attribute( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_next_hop_group_attribute( + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_NEXT_HOP_GROUP, next_hop_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** * Routine Description: - * @brief Add next hop to a group + * @brief Add next hop to a group * * Arguments: * @param[in] next_hop_group_id - next hop group id @@ -120,19 +124,21 @@ sai_status_t redis_get_next_hop_group_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_add_next_hop_to_group( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t next_hop_count, - _In_ const sai_object_id_t* nexthops) +sai_status_t redis_add_next_hop_to_group( + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t next_hop_count, + _In_ const sai_object_id_t* nexthops) { SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } /** * Routine Description: - * @brief Remove next hop from a group + * @brief Remove next hop from a group * * Arguments: * @param[in] next_hop_group_id - next hop group id @@ -143,18 +149,20 @@ sai_status_t redis_add_next_hop_to_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_next_hop_from_group( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t next_hop_count, - _In_ const sai_object_id_t* nexthops) +sai_status_t redis_remove_next_hop_from_group( + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t next_hop_count, + _In_ const sai_object_id_t* nexthops) { SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } /** - * @brief Next Hop methods table retrieved with sai_api_query() + * @brief Next Hop methods table retrieved with sai_api_query() */ const sai_next_hop_group_api_t redis_next_hop_group_api = { redis_create_next_hop_group, diff --git a/lib/src/sai_redis_policer.cpp b/lib/src/sai_redis_policer.cpp index ac4ff83b4749..1a95dd6d7f7f 100644 --- a/lib/src/sai_redis_policer.cpp +++ b/lib/src/sai_redis_policer.cpp @@ -10,20 +10,21 @@ * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_create_policer( - _Out_ sai_object_id_t *policer_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_policer( + _Out_ sai_object_id_t *policer_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_POLICER, policer_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -31,23 +32,24 @@ sai_status_t redis_create_policer( * * @param[in] policer_id - Policer id * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_policer( +sai_status_t redis_remove_policer( _In_ sai_object_id_t policer_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_POLICER, - policer_id); - - return status; + policer_id, + &redis_generic_remove); } /** - * @brief Set Policer attribute + * @brief Set Policer attribute * * @param[in] policer_id - Policer id * @param[in] attr - attribute @@ -55,22 +57,23 @@ sai_status_t redis_remove_policer( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_policer_attribute( - _In_ sai_object_id_t policer_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_policer_attribute( + _In_ sai_object_id_t policer_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_POLICER, policer_id, - attr); - - return status; + attr, + &redis_generic_set); } /** - * @brief Get Policer attribute + * @brief Get Policer attribute * * @param[in] policer_id - policer id * @param[in] attr_count - number of attributes @@ -79,24 +82,25 @@ sai_status_t redis_set_policer_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_policer_attribute( - _In_ sai_object_id_t policer_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_policer_attribute( + _In_ sai_object_id_t policer_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_POLICER, policer_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief Get Policer Statistics + * @brief Get Policer Statistics * * @param[in] policer_id - policer id * @param[in] counter_ids - array of counter ids @@ -106,14 +110,18 @@ sai_status_t redis_get_policer_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_policer_stats( - _In_ sai_object_id_t policer_id, - _In_ const sai_policer_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) +sai_status_t redis_get_policer_stats( + _In_ sai_object_id_t policer_id, + _In_ const sai_policer_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t* counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } diff --git a/lib/src/sai_redis_port.cpp b/lib/src/sai_redis_port.cpp index 9a799a97768d..38b15af35e00 100644 --- a/lib/src/sai_redis_port.cpp +++ b/lib/src/sai_redis_port.cpp @@ -12,18 +12,19 @@ * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_port_attribute( - _In_ sai_object_id_t port_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_port_attribute( + _In_ sai_object_id_t port_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_PORT, port_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -39,20 +40,21 @@ sai_status_t redis_set_port_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_port_attribute( - _In_ sai_object_id_t port_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_port_attribute( + _In_ sai_object_id_t port_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_PORT, port_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -69,11 +71,11 @@ sai_status_t redis_get_port_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_port_stats( - _In_ sai_object_id_t port_id, - _In_ const sai_port_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) +sai_status_t redis_get_port_stats( + _In_ sai_object_id_t port_id, + _In_ const sai_port_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t* counters) { SWSS_LOG_ENTER(); @@ -93,10 +95,10 @@ sai_status_t redis_get_port_stats( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_clear_port_stats( - _In_ sai_object_id_t port_id, - _In_ const sai_port_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters) +sai_status_t redis_clear_port_stats( + _In_ sai_object_id_t port_id, + _In_ const sai_port_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters) { SWSS_LOG_ENTER(); @@ -114,51 +116,14 @@ sai_status_t redis_clear_port_stats( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_clear_port_all_stats( - _In_ sai_object_id_t port_id) +sai_status_t redis_clear_port_all_stats( + _In_ sai_object_id_t port_id) { SWSS_LOG_ENTER(); return SAI_STATUS_NOT_IMPLEMENTED; } -/** - * Routine Description: - * Port state change notification - * Passed as a parameter into sai_initialize_switch() - * - * Arguments: - * @param[in] count - number of notifications - * @param[in] data - array of port operational status - * - * Return Values: - * None - */ -void redis_port_state_change_notification( - _In_ uint32_t count, - _In_ sai_port_oper_status_notification_t *data) -{ - SWSS_LOG_ENTER(); -} - -/** - * Routine Description: - * @brief Port event notification - * - * Arguments: - * @param[in] count - number of notifications - * @param[in] data - array of port events - - * Return Values: - * None - */ -void redis_port_event_notification( - _In_ uint32_t count, - _In_ sai_port_event_notification_t *data) -{ - SWSS_LOG_ENTER(); -} - /** * @brief Port methods table retrieved with sai_api_query() */ diff --git a/lib/src/sai_redis_qosmaps.cpp b/lib/src/sai_redis_qosmaps.cpp index 5795f8b8e6ff..756535868677 100644 --- a/lib/src/sai_redis_qosmaps.cpp +++ b/lib/src/sai_redis_qosmaps.cpp @@ -7,43 +7,45 @@ * @param[in] attr_count number of attributes * @param[in] attr_list array of attributes * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_create_qos_map( - _Out_ sai_object_id_t* qos_map_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_qos_map( + _Out_ sai_object_id_t* qos_map_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_QOS_MAPS, qos_map_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** * @brief Remove Qos Map * - * @param[in] qos_map_id Qos Map id to be removed. + * @param[in] qos_map_id Qos Map id to be removed. * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_qos_map ( - _In_ sai_object_id_t qos_map_id) +sai_status_t redis_remove_qos_map ( + _In_ sai_object_id_t qos_map_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_QOS_MAPS, - qos_map_id); - - return status; + qos_map_id, + &redis_generic_remove); } /** @@ -52,51 +54,53 @@ sai_status_t redis_remove_qos_map ( * @param[in] qos_map_id Qos Map Id * @param[in] attr attribute to set * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_qos_map_attribute( - _In_ sai_object_id_t qos_map_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_qos_map_attribute( + _In_ sai_object_id_t qos_map_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_QOS_MAPS, qos_map_id, - attr); - - return status; + attr, + &redis_generic_set); } /** - * @brief Get attrbutes of qos map + * @brief Get attrbutes of qos map * - * @param[in] qos_map_id map id - * @param[in] attr_count number of attributes - * @param[inout] attr_list array of attributes + * @param[in] qos_map_id map id + * @param[in] attr_count number of attributes + * @param[inout] attr_list array of attributes * * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_qos_map_attribute( - _In_ sai_object_id_t qos_map_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_qos_map_attribute( + _In_ sai_object_id_t qos_map_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_QOS_MAPS, qos_map_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * Qos Map methods table retrieved with sai_api_query() + * Qos Map methods table retrieved with sai_api_query() */ const sai_qos_map_api_t redis_qos_map_api = { redis_create_qos_map, diff --git a/lib/src/sai_redis_queue.cpp b/lib/src/sai_redis_queue.cpp index 0f63c0a8f3b9..e55ead1d3685 100644 --- a/lib/src/sai_redis_queue.cpp +++ b/lib/src/sai_redis_queue.cpp @@ -1,25 +1,81 @@ #include "sai_redis.h" +/** + * Routine Description: + * @brief Create queue + * + * Arguments: + * @param[out] queue_id - queue id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + * + */ +sai_status_t redis_create_queue( + _Out_ sai_object_id_t* queue_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + std::lock_guard lock(g_apimutex); + + SWSS_LOG_ENTER(); + + return meta_sai_create_oid( + SAI_OBJECT_TYPE_QUEUE, + queue_id, + attr_count, + attr_list, + &redis_generic_create); +} + +/** + * Routine Description: + * @brief Remove queue + * + * Arguments: + * @param[in] queue_id - queue id + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_remove_queue( + _In_ sai_object_id_t queue_id) +{ + std::lock_guard lock(g_apimutex); + + SWSS_LOG_ENTER(); + + return meta_sai_remove_oid( + SAI_OBJECT_TYPE_QUEUE, + queue_id, + &redis_generic_remove); +} + /** * @brief Set attribute to Queue * @param[in] queue_id queue id to set the attribute * @param[in] attr attribute to set * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_queue_attribute( - _In_ sai_object_id_t queue_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_queue_attribute( + _In_ sai_object_id_t queue_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_QUEUE, queue_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -28,23 +84,24 @@ sai_status_t redis_set_queue_attribute( * @param[in] attr_count number of attributes * @param[inout] attr_list Array of attributes * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_queue_attribute( - _In_ sai_object_id_t queue_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_queue_attribute( + _In_ sai_object_id_t queue_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_QUEUE, queue_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -58,14 +115,18 @@ sai_status_t redis_get_queue_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_queue_stats( - _In_ sai_object_id_t queue_id, - _In_ const sai_queue_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) +sai_status_t redis_get_queue_stats( + _In_ sai_object_id_t queue_id, + _In_ const sai_queue_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t* counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } @@ -79,21 +140,22 @@ sai_status_t redis_get_queue_stats( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_clear_queue_stats( - _In_ sai_object_id_t queue_id, - _In_ const sai_queue_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters) +sai_status_t redis_clear_queue_stats( + _In_ sai_object_id_t queue_id, + _In_ const sai_queue_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters) { SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } - /** - * @brief Qos methods table retrieved with sai_api_query() + * @brief Qos methods table retrieved with sai_api_query() */ -const sai_queue_api_t redis_queue_api = { +const sai_queue_api_t redis_queue_api = { redis_set_queue_attribute, redis_get_queue_attribute, redis_get_queue_stats, diff --git a/lib/src/sai_redis_route.cpp b/lib/src/sai_redis_route.cpp index a168e27a6e9b..714da6947d8c 100644 --- a/lib/src/sai_redis_route.cpp +++ b/lib/src/sai_redis_route.cpp @@ -16,20 +16,20 @@ * Note: IP prefix/mask expected in Network Byte Order. * */ -sai_status_t redis_create_route( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_route( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( - SAI_OBJECT_TYPE_ROUTE, + return meta_sai_create_route_entry( unicast_route_entry, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create_route_entry); } /** @@ -45,16 +45,16 @@ sai_status_t redis_create_route( * * Note: IP prefix/mask expected in Network Byte Order. */ -sai_status_t redis_remove_route( - _In_ const sai_unicast_route_entry_t* unicast_route_entry) +sai_status_t redis_remove_route( + _In_ const sai_unicast_route_entry_t* unicast_route_entry) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove( - SAI_OBJECT_TYPE_ROUTE, - unicast_route_entry); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_route_entry( + unicast_route_entry, + &redis_generic_remove_route_entry); } /** @@ -69,18 +69,18 @@ sai_status_t redis_remove_route( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_route_attribute( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_route_attribute( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_ROUTE, + return meta_sai_set_route_entry( unicast_route_entry, - attr); - - return status; + attr, + &redis_generic_set_route_entry); } /** @@ -96,25 +96,24 @@ sai_status_t redis_set_route_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_route_attribute( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_route_attribute( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_ROUTE, + return meta_sai_get_route_entry( unicast_route_entry, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get_route_entry); } - /** - * @brief Router entry methods table retrieved with sai_api_query() + * @brief Router entry methods table retrieved with sai_api_query() */ const sai_route_api_t redis_route_api = { redis_create_route, diff --git a/lib/src/sai_redis_router.cpp b/lib/src/sai_redis_router.cpp index 4cfe133e06e6..3af9991939b6 100644 --- a/lib/src/sai_redis_router.cpp +++ b/lib/src/sai_redis_router.cpp @@ -3,31 +3,32 @@ /** * Routine Description: * @brief Create virtual router - * + * * Arguments: * @param[out] vr_id - virtual router id * @param[in] attr_count - number of attributes * @param[in] attr_list - array of attributes - * + * * Return Values: * @return SAI_STATUS_SUCCESS on success - * SAI_STATUS_ADDR_NOT_FOUND if neither SAI_SWITCH_ATTR_SRC_MAC_ADDRESS nor + * SAI_STATUS_ADDR_NOT_FOUND if neither SAI_SWITCH_ATTR_SRC_MAC_ADDRESS nor * SAI_VIRTUAL_ROUTER_ATTR_SRC_MAC_ADDRESS is set. */ sai_status_t redis_create_virtual_router( - _Out_ sai_object_id_t *vr_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t *vr_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -41,16 +42,17 @@ sai_status_t redis_create_virtual_router( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_virtual_router( - _In_ sai_object_id_t vr_id) +sai_status_t redis_remove_virtual_router( + _In_ sai_object_id_t vr_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_VIRTUAL_ROUTER, - vr_id); - - return status; + vr_id, + &redis_generic_remove); } /** @@ -65,18 +67,19 @@ sai_status_t redis_remove_virtual_router( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_virtual_router_attribute( - _In_ sai_object_id_t vr_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_virtual_router_attribute( + _In_ sai_object_id_t vr_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -92,24 +95,25 @@ sai_status_t redis_set_virtual_router_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_virtual_router_attribute( - _In_ sai_object_id_t vr_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_virtual_router_attribute( + _In_ sai_object_id_t vr_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief Virtual router methods table retrieved with sai_api_query() + * @brief Virtual router methods table retrieved with sai_api_query() */ const sai_virtual_router_api_t redis_router_api = { redis_create_virtual_router, diff --git a/lib/src/sai_redis_routerintf.cpp b/lib/src/sai_redis_routerintf.cpp index 38269b60c51a..72d7ca919450 100644 --- a/lib/src/sai_redis_routerintf.cpp +++ b/lib/src/sai_redis_routerintf.cpp @@ -2,7 +2,7 @@ /** * Routine Description: - * @brief Create router interface. + * @brief Create router interface. * * Arguments: * @param[out] rif_id - router interface id @@ -14,19 +14,20 @@ * Failure status code on error */ sai_status_t redis_create_router_interface( - _Out_ sai_object_id_t* rif_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* rif_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_ROUTER_INTERFACE, rif_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -41,15 +42,16 @@ sai_status_t redis_create_router_interface( * Failure status code on error */ sai_status_t redis_remove_router_interface( - _In_ sai_object_id_t rif_id) + _In_ sai_object_id_t rif_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_ROUTER_INTERFACE, - rif_id); - - return status; + rif_id, + &redis_generic_remove); } /** @@ -64,18 +66,19 @@ sai_status_t redis_remove_router_interface( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_router_interface_attribute( - _In_ sai_object_id_t rif_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_router_interface_attribute( + _In_ sai_object_id_t rif_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_ROUTER_INTERFACE, rif_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -91,24 +94,25 @@ sai_status_t redis_set_router_interface_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_router_interface_attribute( - _In_ sai_object_id_t rif_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_router_interface_attribute( + _In_ sai_object_id_t rif_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_ROUTER_INTERFACE, rif_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief Routing interface methods table retrieved with sai_api_query() + * @brief Routing interface methods table retrieved with sai_api_query() */ const sai_router_interface_api_t redis_router_interface_api = { redis_create_router_interface, diff --git a/lib/src/sai_redis_samplepacket.cpp b/lib/src/sai_redis_samplepacket.cpp index 64d70e54f7e4..556a7181005b 100644 --- a/lib/src/sai_redis_samplepacket.cpp +++ b/lib/src/sai_redis_samplepacket.cpp @@ -11,18 +11,17 @@ */ sai_status_t redis_create_samplepacket_session( _Out_ sai_object_id_t *session_id, - _In_ uint32_t attr_count, + _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_SAMPLEPACKET, session_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -33,15 +32,14 @@ sai_status_t redis_create_samplepacket_session( * error code is returned. */ sai_status_t redis_remove_samplepacket_session( - _In_ sai_object_id_t session_id) + _In_ sai_object_id_t session_id) { SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_SAMPLEPACKET, - session_id); - - return status; + session_id, + &redis_generic_remove); } /** @@ -53,17 +51,16 @@ sai_status_t redis_remove_samplepacket_session( * error code is returned. */ sai_status_t redis_set_samplepacket_attribute( - _In_ sai_object_id_t session_id, + _In_ sai_object_id_t session_id, _In_ const sai_attribute_t *attr) { SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_SAMPLEPACKET, session_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -77,18 +74,17 @@ sai_status_t redis_set_samplepacket_attribute( */ sai_status_t redis_get_samplepacket_attribute( _In_ sai_object_id_t session_id, - _In_ uint32_t attr_count, + _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_SAMPLEPACKET, session_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** diff --git a/lib/src/sai_redis_scheduler.cpp b/lib/src/sai_redis_scheduler.cpp index e7edc77d3985..680ccaeb4f7a 100644 --- a/lib/src/sai_redis_scheduler.cpp +++ b/lib/src/sai_redis_scheduler.cpp @@ -1,76 +1,79 @@ #include "sai_redis.h" /** - * @brief Create Scheduler Profile + * @brief Create Scheduler Profile * * @param[out] scheduler_id Scheduler id * @param[in] attr_count number of attributes * @param[in] attr_list array of attributes * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_create_scheduler_profile( - _Out_ sai_object_id_t *scheduler_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t *scheduler_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_SCHEDULER, scheduler_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** - * @brief Remove Scheduler profile + * @brief Remove Scheduler profile * * @param[in] scheduler_id Scheduler id * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_remove_scheduler_profile( - _In_ sai_object_id_t scheduler_id) + _In_ sai_object_id_t scheduler_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_SCHEDULER, - scheduler_id); - - return status; + scheduler_id, + &redis_generic_remove); } /** - * @brief Set Scheduler Attribute + * @brief Set Scheduler Attribute * * @param[in] scheduler_id Scheduler id * @param[in] attr attribute to set * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_set_scheduler_attribute( - _In_ sai_object_id_t scheduler_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t scheduler_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_SCHEDULER, scheduler_id, - attr); - - return status; + attr, + &redis_generic_set); } /** - * @brief Get Scheduler attribute + * @brief Get Scheduler attribute * * @param[in] scheduler_id - scheduler id * @param[in] attr_count - number of attributes @@ -81,23 +84,24 @@ sai_status_t redis_set_scheduler_attribute( */ sai_status_t redis_get_scheduler_attribute( - _In_ sai_object_id_t scheduler_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) + _In_ sai_object_id_t scheduler_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_SCHEDULER, scheduler_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief Scheduler methods table retrieved with sai_api_query() + * @brief Scheduler methods table retrieved with sai_api_query() */ const sai_scheduler_api_t redis_scheduler_api = { redis_create_scheduler_profile, diff --git a/lib/src/sai_redis_schedulergroup.cpp b/lib/src/sai_redis_schedulergroup.cpp index ca9465bad151..541b91b788d7 100644 --- a/lib/src/sai_redis_schedulergroup.cpp +++ b/lib/src/sai_redis_schedulergroup.cpp @@ -1,76 +1,79 @@ #include "sai_redis.h" /** - * @brief Create Scheduler group + * @brief Create Scheduler group * * @param[out] scheduler_group_id Scheudler group id * @param[in] attr_count number of attributes * @param[in] attr_list array of attributes * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_create_scheduler_group( - _Out_ sai_object_id_t *scheduler_group_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t *scheduler_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_SCHEDULER_GROUP, scheduler_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** - * @brief Remove Scheduler group + * @brief Remove Scheduler group * * @param[in] scheduler_group_id Scheudler group id * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_remove_scheduler_group( - _In_ sai_object_id_t scheduler_group_id) + _In_ sai_object_id_t scheduler_group_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_SCHEDULER_GROUP, - scheduler_group_id); - - return status; + scheduler_group_id, + &redis_generic_remove); } /** - * @brief Set Scheduler group Attribute + * @brief Set Scheduler group Attribute * * @param[in] scheduler_group_id Scheudler group id * @param[in] attr attribute to set * - * @return SAI_STATUS_SUCCESS on success + * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t redis_set_scheduler_group_attribute( - _In_ sai_object_id_t scheduler_group_id, - _In_ const sai_attribute_t *attr) + _In_ sai_object_id_t scheduler_group_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_SCHEDULER_GROUP, scheduler_group_id, - attr); - - return status; + attr, + &redis_generic_set); } /** - * @brief Get Scheduler Group attribute + * @brief Get Scheduler Group attribute * * @param[in] scheduler_group_id - scheduler group id * @param[in] attr_count - number of attributes @@ -80,20 +83,21 @@ sai_status_t redis_set_scheduler_group_attribute( * Failure status code on error */ -sai_status_t redis_get_scheduler_group_attribute( - _In_ sai_object_id_t scheduler_group_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_scheduler_group_attribute( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_SCHEDULER_GROUP, scheduler_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -106,17 +110,20 @@ sai_status_t redis_get_scheduler_group_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_add_child_object_to_group( - _In_ sai_object_id_t scheduler_group_id, - _In_ uint32_t child_count, - _In_ const sai_object_id_t* child_objects) +sai_status_t redis_add_child_object_to_group( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t child_count, + _In_ const sai_object_id_t* child_objects) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } - /** * @brief Remove Child queue/group objects from scheduler group * @@ -127,18 +134,22 @@ sai_status_t redis_add_child_object_to_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_child_object_from_group( - _In_ sai_object_id_t scheduler_group_id, - _In_ uint32_t child_count, - _In_ const sai_object_id_t* child_objects) +sai_status_t redis_remove_child_object_from_group( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t child_count, + _In_ const sai_object_id_t* child_objects) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } /** - * @brief Scheduler Group methods table retrieved with sai_api_query() + * @brief Scheduler Group methods table retrieved with sai_api_query() */ const sai_scheduler_group_api_t redis_scheduler_group_api = { redis_create_scheduler_group, diff --git a/lib/src/sai_redis_stp.cpp b/lib/src/sai_redis_stp.cpp index 3973d82cdc85..0b42843fa6b8 100644 --- a/lib/src/sai_redis_stp.cpp +++ b/lib/src/sai_redis_stp.cpp @@ -7,22 +7,23 @@ * @param[in] attr_count Number of attributes * @param[in] attr_list Value of attributes * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_create_stp( - _Out_ sai_object_id_t *stp_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_stp( + _Out_ sai_object_id_t *stp_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_STP_INSTANCE, stp_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -30,107 +31,110 @@ sai_status_t redis_create_stp( * * @param[in] stp_id stp instance id * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_remove_stp( - _In_ sai_object_id_t stp_id) +sai_status_t redis_remove_stp( + _In_ sai_object_id_t stp_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_STP_INSTANCE, - stp_id); - - return status; + stp_id, + &redis_generic_remove); } /** - * @brief Update stp state of a port in specified stp instance. + * @brief Set the attribute of STP instance. * * @param[in] stp_id stp instance id - * @param[in] port_id port id - * @param[in] stp_port_state stp state of the port + * @param[in] attr attribute value * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_set_stp_port_state( - _In_ sai_object_id_t stp_id, - _In_ sai_object_id_t port_id, - _In_ sai_port_stp_port_state_t stp_port_state) +sai_status_t redis_set_stp_attribute( + _In_ sai_object_id_t stp_id, + _In_ const sai_attribute_t *attr) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - // TODO function signature must be changed to match other types + SWSS_LOG_ENTER(); - return SAI_STATUS_NOT_IMPLEMENTED; + return meta_sai_set_oid( + SAI_OBJECT_TYPE_STP_INSTANCE, + stp_id, + attr, + &redis_generic_set); } /** - * @brief Retrieve stp state of a port in specified stp instance. + * @brief Get the attribute of STP instance. * * @param[in] stp_id stp instance id - * @param[in] port_id port id - * @param[out] stp_port_state stp state of the port + * @param[in] attr_count number of the attribute + * @param[in] attr_list attribute value * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_get_stp_port_state( - _In_ sai_object_id_t stp_id, - _In_ sai_object_id_t port_id, - _Out_ sai_port_stp_port_state_t *stp_port_state) +sai_status_t redis_get_stp_attribute( + _In_ sai_object_id_t stp_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - // TODO function signature must be changed to match other types + SWSS_LOG_ENTER(); - return SAI_STATUS_NOT_IMPLEMENTED; + return meta_sai_get_oid( + SAI_OBJECT_TYPE_STP_INSTANCE, + stp_id, + attr_count, + attr_list, + &redis_generic_get); } /** - * @brief Set the attribute of STP instance. + * @brief Update stp state of a port in specified stp instance. * * @param[in] stp_id stp instance id - * @param[in] attr attribute value + * @param[in] port_id port id + * @param[in] stp_port_state stp state of the port * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_set_stp_attribute( - _In_ sai_object_id_t stp_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_stp_port_state( + _In_ sai_object_id_t stp_id, + _In_ sai_object_id_t port_id, + _In_ sai_port_stp_port_state_t stp_port_state) { SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_STP_INSTANCE, - stp_id, - attr); + SWSS_LOG_ERROR("not implemented"); - return status; + return SAI_STATUS_NOT_IMPLEMENTED; } /** - * @brief Get the attribute of STP instance. + * @brief Retrieve stp state of a port in specified stp instance. * * @param[in] stp_id stp instance id - * @param[in] attr_count number of the attribute - * @param[in] attr_list attribute value + * @param[in] port_id port id + * @param[out] stp_port_state stp state of the port * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different - * error code is returned. + * error code is returned. */ -sai_status_t redis_get_stp_attribute( - _In_ sai_object_id_t stp_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_stp_port_state( + _In_ sai_object_id_t stp_id, + _In_ sai_object_id_t port_id, + _Out_ sai_port_stp_port_state_t *stp_port_state) { SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_STP_INSTANCE, - stp_id, - attr_count, - attr_list); + SWSS_LOG_ERROR("not implemented"); - return status; + return SAI_STATUS_NOT_IMPLEMENTED; } /** diff --git a/lib/src/sai_redis_switch.cpp b/lib/src/sai_redis_switch.cpp index e3c75ce30ff9..244a77a0c89f 100644 --- a/lib/src/sai_redis_switch.cpp +++ b/lib/src/sai_redis_switch.cpp @@ -1,7 +1,9 @@ #include "sai_redis.h" #include -#include "selectableevent.h" +#include "swss/selectableevent.h" + +// TODO it may be needed to obtain SAI_SWITCH_ATTR_DEFAULT_TRAP_GROUP object id // if we will not get response in 60 seconds when // notify syncd to compile new state or to switch @@ -61,19 +63,19 @@ void ntf_thread() } } -sai_status_t notify_syncd(const std::string &op) +sai_status_t notify_syncd(const std::string &operation) { SWSS_LOG_ENTER(); std::vector entry; - g_notifySyncdProducer->send(op, "", entry); + g_notifySyncdProducer->send(operation, "", entry); swss::Select s; s.addSelectable(g_notifySyncdConsumer); - SWSS_LOG_DEBUG("wait for response after: %s", op.c_str()); + SWSS_LOG_DEBUG("wait for response after: %s", operation.c_str()); swss::Selectable *sel; @@ -98,37 +100,52 @@ sai_status_t notify_syncd(const std::string &op) int index = 0; sai_deserialize_primitive(strStatus, index, status); - SWSS_LOG_INFO("%s status: %d", op.c_str(), status); + SWSS_LOG_NOTICE("%s status: %d", op.c_str(), status); return status; } - SWSS_LOG_ERROR("%s get response failed, result: %d", op.c_str(), result); + SWSS_LOG_ERROR("%s get response failed, result: %d", operation.c_str(), result); return SAI_STATUS_FAILURE; } +void clear_local_state() +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_init_db(); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("failed to init meta db FIXME"); + throw; + } +} + /** -* Routine Description: -* SDK initialization. After the call the capability attributes should be -* ready for retrieval via sai_get_switch_attribute(). -* -* Arguments: -* @param[in] profile_id - Handle for the switch profile. -* @param[in] switch_hardware_id - Switch hardware ID to open -* @param[in] firmware_path_name - Vendor specific path name of the firmware -* to load -* @param[in] switch_notifications - switch notification table -* Return Values: -* @return SAI_STATUS_SUCCESS on success -* Failure status code on error -*/ + * Routine Description: + * SDK initialization. After the call the capability attributes should be + * ready for retrieval via sai_get_switch_attribute(). + * + * Arguments: + * @param[in] profile_id - Handle for the switch profile. + * @param[in] switch_hardware_id - Switch hardware ID to open + * @param[in] firmware_path_name - Vendor specific path name of the firmware + * to load + * @param[in] switch_notifications - switch notification table + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_initialize_switch( - _In_ sai_switch_profile_id_t profile_id, - _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char* switch_hardware_id, - _In_reads_opt_z_(SAI_MAX_FIRMWARE_PATH_NAME_LEN) char* firmware_path_name, - _In_ sai_switch_notification_t* switch_notifications) + _In_ sai_switch_profile_id_t profile_id, + _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char* switch_hardware_id, + _In_reads_opt_z_(SAI_MAX_FIRMWARE_PATH_NAME_LEN) char* firmware_path_name, + _In_ sai_switch_notification_t* switch_notifications) { + std::lock_guard apilock(g_apimutex); + std::lock_guard lock(g_mutex); SWSS_LOG_ENTER(); @@ -142,7 +159,7 @@ sai_status_t redis_initialize_switch( std::string op = std::string(firmware_path_name); - SWSS_LOG_INFO("operation: '%s'", op.c_str()); + SWSS_LOG_NOTICE("operation: '%s'", op.c_str()); if (op == NOTIFY_SAI_INIT_VIEW || op == NOTIFY_SAI_APPLY_VIEW) { @@ -154,6 +171,15 @@ sai_status_t redis_initialize_switch( if (g_switchInitialized) { + if (op == NOTIFY_SAI_INIT_VIEW) + { + SWSS_LOG_NOTICE("clearing current local state sinice init view is called on initialised switch"); + + // TODO since we clear all defaults here and we are compiling new view + // there may be some problems with GET + clear_local_state(); + } + return status; } @@ -183,14 +209,16 @@ sai_status_t redis_initialize_switch( if (switch_notifications != NULL) { memcpy(&redis_switch_notifications, - switch_notifications, - sizeof(sai_switch_notification_t)); + switch_notifications, + sizeof(sai_switch_notification_t)); } else { memset(&redis_switch_notifications, 0, sizeof(sai_switch_notification_t)); } + clear_local_state(); + g_run = true; SWSS_LOG_DEBUG("creating notification thread"); @@ -213,9 +241,11 @@ sai_status_t redis_initialize_switch( * Return Values: * None */ -void redis_shutdown_switch( - _In_ bool warm_restart_hint) +void redis_shutdown_switch( + _In_ bool warm_restart_hint) { + std::lock_guard apilock(g_apimutex); + std::lock_guard lock(g_mutex); SWSS_LOG_ENTER(); @@ -254,10 +284,12 @@ void redis_shutdown_switch( * Failure status code on error */ sai_status_t redis_connect_switch( - _In_ sai_switch_profile_id_t profile_id, - _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char* switch_hardware_id, - _In_ sai_switch_notification_t* switch_notifications) + _In_ sai_switch_profile_id_t profile_id, + _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char* switch_hardware_id, + _In_ sai_switch_notification_t* switch_notifications) { + std::lock_guard apilock(g_apimutex); + std::lock_guard lock(g_mutex); SWSS_LOG_ENTER(); @@ -278,6 +310,8 @@ sai_status_t redis_connect_switch( */ void redis_disconnect_switch(void) { + std::lock_guard apilock(g_apimutex); + std::lock_guard lock(g_mutex); SWSS_LOG_ENTER(); @@ -296,17 +330,16 @@ void redis_disconnect_switch(void) * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_switch_attribute( - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_switch_attribute( + _In_ const sai_attribute_t *attr) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_set( - SAI_OBJECT_TYPE_SWITCH, - (sai_object_id_t)0, // dummy sai_object_id_t for switch - attr); + SWSS_LOG_ENTER(); - return status; + return meta_sai_set_switch( + attr, + &redis_generic_set_switch); } /** @@ -321,19 +354,18 @@ sai_status_t redis_set_switch_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_switch_attribute( - _In_ sai_uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_switch_attribute( + _In_ sai_uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( - SAI_OBJECT_TYPE_SWITCH, - (sai_object_id_t)0, + return meta_sai_get_switch( attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get_switch); } /** diff --git a/lib/src/sai_redis_tunnel.cpp b/lib/src/sai_redis_tunnel.cpp index bb7188379421..6005d39cdb28 100644 --- a/lib/src/sai_redis_tunnel.cpp +++ b/lib/src/sai_redis_tunnel.cpp @@ -14,20 +14,21 @@ * Failure status code on error * */ -sai_status_t redis_create_tunnel_map( - _Out_ sai_object_id_t* tunnel_map_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_tunnel_map( + _Out_ sai_object_id_t* tunnel_map_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_TUNNEL_MAP, tunnel_map_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -42,16 +43,17 @@ sai_status_t redis_create_tunnel_map( * Failure status code on error * */ -sai_status_t redis_remove_tunnel_map( - _In_ sai_object_id_t tunnel_map_id) +sai_status_t redis_remove_tunnel_map( + _In_ sai_object_id_t tunnel_map_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_TUNNEL_MAP, - tunnel_map_id); - - return status; + tunnel_map_id, + &redis_generic_remove); } /** @@ -66,18 +68,19 @@ sai_status_t redis_remove_tunnel_map( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_tunnel_map_attribute( - _In_ sai_object_id_t tunnel_map_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_tunnel_map_attribute( + _In_ sai_object_id_t tunnel_map_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_TUNNEL_MAP, tunnel_map_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -92,20 +95,21 @@ sai_status_t redis_set_tunnel_map_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_tunnel_map_attribute( - _In_ sai_object_id_t tunnel_map_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_tunnel_map_attribute( + _In_ sai_object_id_t tunnel_map_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_TUNNEL_MAP, tunnel_map_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -122,20 +126,21 @@ sai_status_t redis_get_tunnel_map_attribute( * Failure status code on error * */ -sai_status_t redis_create_tunnel( - _Out_ sai_object_id_t* tunnel_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_tunnel( + _Out_ sai_object_id_t* tunnel_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_TUNNEL, tunnel_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -150,16 +155,17 @@ sai_status_t redis_create_tunnel( * Failure status code on error * */ -sai_status_t redis_remove_tunnel( - _In_ sai_object_id_t tunnel_id) +sai_status_t redis_remove_tunnel( + _In_ sai_object_id_t tunnel_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_TUNNEL, - tunnel_id); - - return status; + tunnel_id, + &redis_generic_remove); } /** @@ -174,18 +180,19 @@ sai_status_t redis_remove_tunnel( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_tunnel_attribute( - _In_ sai_object_id_t tunnel_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_tunnel_attribute( + _In_ sai_object_id_t tunnel_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_TUNNEL, tunnel_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -201,20 +208,21 @@ sai_status_t redis_set_tunnel_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_tunnel_attribute( - _In_ sai_object_id_t tunnel_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_tunnel_attribute( + _In_ sai_object_id_t tunnel_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_TUNNEL, tunnel_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -231,20 +239,21 @@ sai_status_t redis_get_tunnel_attribute( * Failure status code on error * */ -sai_status_t redis_create_tunnel_term_table_entry ( - _Out_ sai_object_id_t* tunnel_term_table_entry_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_tunnel_term_table_entry ( + _Out_ sai_object_id_t* tunnel_term_table_entry_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, tunnel_term_table_entry_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -259,16 +268,17 @@ sai_status_t redis_create_tunnel_term_table_entry ( * Failure status code on error * */ -sai_status_t redis_remove_tunnel_term_table_entry ( - _In_ sai_object_id_t tunnel_term_table_entry_id) +sai_status_t redis_remove_tunnel_term_table_entry ( + _In_ sai_object_id_t tunnel_term_table_entry_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, - tunnel_term_table_entry_id); - - return status; + tunnel_term_table_entry_id, + &redis_generic_remove); } /** @@ -283,18 +293,19 @@ sai_status_t redis_remove_tunnel_term_table_entry ( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_tunnel_term_table_entry_attribute( - _In_ sai_object_id_t tunnel_term_table_entry_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_tunnel_term_table_entry_attribute( + _In_ sai_object_id_t tunnel_term_table_entry_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, tunnel_term_table_entry_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -309,24 +320,25 @@ sai_status_t redis_set_tunnel_term_table_entry_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_tunnel_term_table_entry_attribute( - _In_ sai_object_id_t tunnel_term_table_entry_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_tunnel_term_table_entry_attribute( + _In_ sai_object_id_t tunnel_term_table_entry_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, tunnel_term_table_entry_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief tunnel table methods, retrieved via sai_api_query() + * @brief tunnel table methods, retrieved via sai_api_query() */ const sai_tunnel_api_t redis_tunnel_api = { redis_create_tunnel_map, diff --git a/lib/src/sai_redis_udf.cpp b/lib/src/sai_redis_udf.cpp index 63d7448ff903..78f5a97b5597 100644 --- a/lib/src/sai_redis_udf.cpp +++ b/lib/src/sai_redis_udf.cpp @@ -14,20 +14,21 @@ * Failure status code on error * */ -sai_status_t redis_create_udf( - _Out_ sai_object_id_t* udf_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_udf( + _Out_ sai_object_id_t* udf_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_UDF, udf_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -42,15 +43,16 @@ sai_status_t redis_create_udf( * Failure status code on error */ sai_status_t redis_remove_udf( - _In_ sai_object_id_t udf_id) + _In_ sai_object_id_t udf_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_UDF, - udf_id); - - return status; + udf_id, + &redis_generic_remove); } /** @@ -65,18 +67,19 @@ sai_status_t redis_remove_udf( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_udf_attribute( - _In_ sai_object_id_t udf_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_udf_attribute( + _In_ sai_object_id_t udf_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_UDF, udf_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -92,20 +95,21 @@ sai_status_t redis_set_udf_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_udf_attribute( - _In_ sai_object_id_t udf_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_udf_attribute( + _In_ sai_object_id_t udf_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_UDF, udf_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -122,20 +126,21 @@ sai_status_t redis_get_udf_attribute( * Failure status code on error * */ -sai_status_t redis_create_udf_match( - _Out_ sai_object_id_t* udf_match_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_udf_match( + _Out_ sai_object_id_t* udf_match_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_UDF_MATCH, udf_match_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -149,16 +154,17 @@ sai_status_t redis_create_udf_match( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_udf_match( - _In_ sai_object_id_t udf_match_id) +sai_status_t redis_remove_udf_match( + _In_ sai_object_id_t udf_match_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_UDF_MATCH, - udf_match_id); - - return status; + udf_match_id, + &redis_generic_remove); } /** @@ -173,18 +179,19 @@ sai_status_t redis_remove_udf_match( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_udf_match_attribute( - _In_ sai_object_id_t udf_match_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_udf_match_attribute( + _In_ sai_object_id_t udf_match_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_UDF_MATCH, udf_match_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -200,20 +207,21 @@ sai_status_t redis_set_udf_match_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_udf_match_attribute( - _In_ sai_object_id_t udf_match_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_udf_match_attribute( + _In_ sai_object_id_t udf_match_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_UDF_MATCH, udf_match_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** @@ -230,20 +238,21 @@ sai_status_t redis_get_udf_match_attribute( * Failure status code on error * */ -sai_status_t redis_create_udf_group( - _Out_ sai_object_id_t* udf_group_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_udf_group( + _Out_ sai_object_id_t* udf_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_UDF_GROUP, udf_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -257,16 +266,17 @@ sai_status_t redis_create_udf_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_udf_group( - _In_ sai_object_id_t udf_group_id) +sai_status_t redis_remove_udf_group( + _In_ sai_object_id_t udf_group_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_UDF_GROUP, - udf_group_id); - - return status; + udf_group_id, + &redis_generic_remove); } /** @@ -281,18 +291,19 @@ sai_status_t redis_remove_udf_group( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_udf_group_attribute( - _In_ sai_object_id_t udf_group_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_udf_group_attribute( + _In_ sai_object_id_t udf_group_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_UDF_GROUP, udf_group_id, - attr); - - return status; + attr, + &redis_generic_set); } /** @@ -308,34 +319,37 @@ sai_status_t redis_set_udf_group_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_udf_group_attribute( - _In_ sai_object_id_t udf_group_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_udf_group_attribute( + _In_ sai_object_id_t udf_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_UDF_GROUP, udf_group_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** - * @brief UDF methods, retrieved via sai_api_query() + * @brief UDF methods, retrieved via sai_api_query() */ const sai_udf_api_t redis_udf_api = { redis_create_udf, redis_remove_udf, redis_set_udf_attribute, redis_get_udf_attribute, + redis_create_udf_match, redis_remove_udf_match, redis_set_udf_match_attribute, redis_get_udf_match_attribute, + redis_create_udf_group, redis_remove_udf_group, redis_set_udf_group_attribute, diff --git a/lib/src/sai_redis_vlan.cpp b/lib/src/sai_redis_vlan.cpp index f3f32a9c1ab0..ddc79a640bd8 100644 --- a/lib/src/sai_redis_vlan.cpp +++ b/lib/src/sai_redis_vlan.cpp @@ -11,16 +11,16 @@ * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_create_vlan( - _In_ sai_vlan_id_t vlan_id) +sai_status_t redis_create_vlan( + _In_ sai_vlan_id_t vlan_id) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_create_vlan( - SAI_OBJECT_TYPE_VLAN, - vlan_id); + SWSS_LOG_ENTER(); - return status; + return meta_sai_create_vlan( + vlan_id, + &redis_generic_create_vlan); } /** @@ -35,15 +35,15 @@ sai_status_t redis_create_vlan( * Failure status code on error */ sai_status_t redis_remove_vlan( - _In_ sai_vlan_id_t vlan_id) + _In_ sai_vlan_id_t vlan_id) { - SWSS_LOG_ENTER(); + std::lock_guard lock(g_apimutex); - sai_status_t status = redis_generic_remove_vlan( - SAI_OBJECT_TYPE_VLAN, - vlan_id); + SWSS_LOG_ENTER(); - return status; + return meta_sai_remove_vlan( + vlan_id, + &redis_generic_remove_vlan); } /** @@ -58,18 +58,18 @@ sai_status_t redis_remove_vlan( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_set_vlan_attribute( - _In_ sai_vlan_id_t vlan_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_vlan_attribute( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set_vlan( - SAI_OBJECT_TYPE_VLAN, + return meta_sai_set_vlan( vlan_id, - attr); - - return status; + attr, + &redis_generic_set_vlan); } /** @@ -85,111 +85,133 @@ sai_status_t redis_set_vlan_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_vlan_attribute( - _In_ sai_vlan_id_t vlan_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_vlan_attribute( + _In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get_vlan( - SAI_OBJECT_TYPE_VLAN, + return meta_sai_get_vlan( vlan_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get_vlan); } -/* - \brief Create VLAN Member - \param[out] vlan_member_id VLAN Member id - \param[in] attr_count number of attributes - \param[in] attr_list array of attributes - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ +/** + * Routine Description: + * @brief Create VLAN member + * + * Arguments: + * @param[out] vlan_member_id - VLAN member id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_create_vlan_member( - _Out_ sai_object_id_t* vlan_member_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) + _Out_ sai_object_id_t* vlan_member_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_VLAN_MEMBER, vlan_member_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } -/* - \brief Remove VLAN Member - \param[in] vlan_member_id VLAN Member id - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ +/** + * Routine Description: + * @brief Remove VLAN member + * + * Arguments: + * @param[in] vlan_member_id - VLAN member id + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ sai_status_t redis_remove_vlan_member( - _In_ sai_object_id_t vlan_member_id) + _In_ sai_object_id_t vlan_member_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_VLAN_MEMBER, - vlan_member_id); - - return status; + vlan_member_id, + &redis_generic_remove); } -/* - \brief Set VLAN Member Attribute - \param[in] vlan_member_id VLAN Member id - \param[in] attr Structure containing ID and value to be set - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ -sai_status_t redis_set_vlan_member_attribute( - _In_ sai_object_id_t vlan_member_id, - _In_ const sai_attribute_t *attr) +/** + * Routine Description: + * @brief Set VLAN member attribute + * + * Arguments: + * @param[in] vlan_member_id - VLAN member id + * @param[in] attr - Structure containing ID and value to be set + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_set_vlan_member_attribute( + _In_ sai_object_id_t vlan_member_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_VLAN_MEMBER, vlan_member_id, - attr); - - return status; + attr, + &redis_generic_set); } -/* - \brief Get VLAN Member Attribute - \param[in] vlan_member_id VLAN Member id - \param[in] attr_count Number of attributes to be get - \param[in,out] attr_list List of structures containing ID and value to be get - \return Success: SAI_STATUS_SUCCESS - Failure: Failure status code on error -*/ - -sai_status_t redis_get_vlan_member_attribute( - _In_ sai_object_id_t vlan_member_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +/** + * Routine Description: + * @brief Get VLAN member attribute + * + * Arguments: + * @param[in] vlan_member_id - VLAN member id + * @param[in] attr_count - number of attributes + * @param[inout] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t redis_get_vlan_member_attribute( + _In_ sai_object_id_t vlan_member_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_VLAN_MEMBER, vlan_member_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } - /** * Routine Description: * @brief Get vlan statistics counters. @@ -204,14 +226,18 @@ sai_status_t redis_get_vlan_member_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_vlan_stats( - _In_ sai_vlan_id_t vlan_id, - _In_ const sai_vlan_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) +sai_status_t redis_get_vlan_stats( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_vlan_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t* counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } @@ -228,13 +254,17 @@ sai_status_t redis_get_vlan_stats( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_clear_vlan_stats( - _In_ sai_vlan_id_t vlan_id, - _In_ const sai_vlan_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters) +sai_status_t redis_clear_vlan_stats( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_vlan_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); + SWSS_LOG_ERROR("not implemented"); + return SAI_STATUS_NOT_IMPLEMENTED; } diff --git a/lib/src/sai_redis_wred.cpp b/lib/src/sai_redis_wred.cpp index c7539d1e1107..f0ad8af783e9 100644 --- a/lib/src/sai_redis_wred.cpp +++ b/lib/src/sai_redis_wred.cpp @@ -12,20 +12,21 @@ * Failure status code on error */ -sai_status_t redis_create_wred_profile( - _Out_ sai_object_id_t *wred_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) +sai_status_t redis_create_wred_profile( + _Out_ sai_object_id_t *wred_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_create( + return meta_sai_create_oid( SAI_OBJECT_TYPE_WRED, wred_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_create); } /** @@ -36,16 +37,17 @@ sai_status_t redis_create_wred_profile( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_remove_wred_profile( - _In_ sai_object_id_t wred_id) +sai_status_t redis_remove_wred_profile( + _In_ sai_object_id_t wred_id) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_remove( + return meta_sai_remove_oid( SAI_OBJECT_TYPE_WRED, - wred_id); - - return status; + wred_id, + &redis_generic_remove); } /** @@ -59,44 +61,46 @@ sai_status_t redis_remove_wred_profile( * Failure status code on error */ -sai_status_t redis_set_wred_attribute( - _In_ sai_object_id_t wred_id, - _In_ const sai_attribute_t *attr) +sai_status_t redis_set_wred_attribute( + _In_ sai_object_id_t wred_id, + _In_ const sai_attribute_t *attr) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_set( + return meta_sai_set_oid( SAI_OBJECT_TYPE_WRED, wred_id, - attr); - - return status; + attr, + &redis_generic_set); } /** - * @brief Get Wred profile attribute + * @brief Get Wred profile attribute * * @param[in] wred_id Wred Profile Id * @param[in] attr_count number of attributes - * @param[inout] attr_list array of attributes + * @param[inout] attr_list array of attributes * * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t redis_get_wred_attribute( - _In_ sai_object_id_t wred_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) +sai_status_t redis_get_wred_attribute( + _In_ sai_object_id_t wred_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + std::lock_guard lock(g_apimutex); + SWSS_LOG_ENTER(); - sai_status_t status = redis_generic_get( + return meta_sai_get_oid( SAI_OBJECT_TYPE_WRED, wred_id, attr_count, - attr_list); - - return status; + attr_list, + &redis_generic_get); } /** diff --git a/meta/Makefile b/meta/Makefile new file mode 100644 index 000000000000..21938023490f --- /dev/null +++ b/meta/Makefile @@ -0,0 +1,120 @@ +warnings = \ + -Wall \ + -Wcast-align \ + -Wcast-qual \ + -Wconversion \ + -Wdisabled-optimization \ + -Werror \ + -Wextra \ + -Wextra \ + -Wfloat-equal \ + -Wformat=2 \ + -Wformat-nonliteral \ + -Wformat-security \ + -Wformat-y2k \ + -Wimport \ + -Winit-self \ + -Winline \ + -Winvalid-pch \ + -Wlong-long \ + -Wmissing-field-initializers \ + -Wmissing-format-attribute \ + -Wmissing-include-dirs \ + -Wmissing-noreturn \ + -Wno-aggregate-return \ + -Wno-padded \ + -Wno-switch-enum \ + -Wno-unused-parameter \ + -Wpacked \ + -Wpointer-arith \ + -Wredundant-decls \ + -Wshadow \ + -Wstack-protector \ + -Wstrict-aliasing=2 \ + -Wswitch \ + -Wswitch-default \ + -Wunreachable-code \ + -Wunused \ + -Wvariadic-macros \ + -Wwrite-strings +# -pedantic \ +# -pedantic-errors \ + +OBJ = \ + sai_extra_acl.o \ + sai_extra_buffer.o \ + sai_extra_fdb.o \ + sai_extra_hash.o \ + sai_extra_hostintf.o \ + sai_extra_lag.o \ + sai_extra_mirror.o \ + sai_extra_neighbor.o \ + sai_extra_nexthopgroup.o \ + sai_extra_nexthop.o \ + sai_extra_policer.o \ + sai_extra_port.o \ + sai_extra_qosmaps.o \ + sai_extra_queue.o \ + sai_extra_route.o \ + sai_extra_routerintf.o \ + sai_extra_router.o \ + sai_extra_samplepacket.o \ + sai_extra_schedulergroup.o \ + sai_extra_scheduler.o \ + sai_extra_stp.o \ + sai_extra_switch.o \ + sai_extra_tunnel.o \ + sai_extra_udf.o \ + sai_extra_vlan.o \ + sai_extra_wred.o \ + ../common/saiserialize.o \ + sai_meta.o \ + sai_meta_sanity.o \ + sai_meta_acl.o \ + sai_meta_buffer.o \ + sai_meta_fdb.o \ + sai_meta_hash.o \ + sai_meta_hostintf.o \ + sai_meta_lag.o \ + sai_meta_mirror.o \ + sai_meta_neighbor.o \ + sai_meta_nexthopgroup.o \ + sai_meta_nexthop.o \ + sai_meta_policer.o \ + sai_meta_port.o \ + sai_meta_qosmaps.o \ + sai_meta_queue.o \ + sai_meta_route.o \ + sai_meta_routerintf.o \ + sai_meta_router.o \ + sai_meta_samplepacket.o \ + sai_meta_schedulergroup.o \ + sai_meta_scheduler.o \ + sai_meta_stp.o \ + sai_meta_switch.o \ + sai_meta_tunnel.o \ + sai_meta_udf.o \ + sai_meta_vlan.o \ + sai_meta_wred.o + +DEPS = sai_meta.h sai_extra.h + +CFLAGS=-std=c++11 -I/usr/include/swss -I/usr/include/sai -I/usr/include $(warnings) +LDFLAGS=-L/usr/lib -lswsscommon + +all: tests gen + +%.o: %.cpp $(DEPS) + g++ -c -o $@ $< $(CFLAGS) + +tests: tests.o $(OBJ) + g++ -o $@ $^ $(LDFLAGS) + +gen: gen.o $(OBJ) + g++ -o $@ $^ $(LDFLAGS) + +.PHONY: clean + +clean: + rm -f *~ .*~ tests gen *.o *.lo + diff --git a/meta/gen.cpp b/meta/gen.cpp new file mode 100644 index 000000000000..fca9549bdc15 --- /dev/null +++ b/meta/gen.cpp @@ -0,0 +1,416 @@ +#include "sai_meta.h" +#include + +sai_object_type_t sai_object_type_query( + _In_ sai_object_id_t oid) +{ + return SAI_OBJECT_TYPE_NULL; +} + +void metadata_generate_type(const sai_attr_metadata_t& md, std::stringstream& ss) +{ + ss << "@type "; + +#define ST(x,y) case SAI_SERIALIZATION_TYPE_ ## x: ss << #y; break; +#define STF(x,y) case SAI_SERIALIZATION_TYPE_ ## x: ss << "sai_acl_field_data_t " << #y; break; +#define STA(x,y) case SAI_SERIALIZATION_TYPE_ ## x: ss << "sai_acl_action_data_t " << #y; break; + + if (md.isenum()) + { + ss << md.enumtypestr; + } + else if (md.isenumlist()) + { + ss << md.enumtypestr; + } + else + switch (md.serializationtype) + { + ST(BOOL, bool); + ST(CHARDATA, char); + ST(UINT8, sai_uint8_t); + ST(INT8, sai_int8_t); + ST(UINT16, sai_uint16_t); + ST(INT16, sai_int16_t); + ST(UINT32, sai_uint32_t); + ST(INT32, sai_int32_t); + ST(UINT64, sai_uint64_t); + ST(INT64, sai_int64_t); + ST(MAC, sai_mac_t); + ST(IP4, sai_ip4_t); + ST(IP6, sai_ip6_t); + ST(IP_ADDRESS, sai_ip_address_t); + ST(OBJECT_ID, sai_object_id_t); + ST(OBJECT_LIST, sai_object_list_t); + ST(UINT8_LIST, sai_uint8_list_t); + ST(INT8_LIST, sai_int8_list_t); + ST(UINT16_LIST, sai_uint16_list_t); + ST(INT16_LIST, sai_int16_list_t); + ST(UINT32_LIST, sai_uint32_list_t); + ST(INT32_LIST, sai_int32_list_t); + ST(UINT32_RANGE, sai_uint32_range_t); + ST(INT32_RANGE, sai_int32_range_t); + ST(VLAN_LIST, sai_vlan_list_t); + + STF(ACL_FIELD_DATA_BOOL, bool); + STF(ACL_FIELD_DATA_UINT8, sai_uint8_t); + STF(ACL_FIELD_DATA_INT8, sai_int8_t); + STF(ACL_FIELD_DATA_UINT16, sai_uint16_t); + STF(ACL_FIELD_DATA_INT16, sai_int16_t); + STF(ACL_FIELD_DATA_INT32, sai_int32_t); + STF(ACL_FIELD_DATA_UINT32, sai_uint32_t); + STF(ACL_FIELD_DATA_MAC, sai_mac_t); + STF(ACL_FIELD_DATA_IP4, sai_ip4_t); + STF(ACL_FIELD_DATA_IP6, sai_ip6_t); + STF(ACL_FIELD_DATA_OBJECT_ID, sai_object_id_t); + STF(ACL_FIELD_DATA_OBJECT_LIST, sai_object_list_t); + STF(ACL_FIELD_DATA_UINT8_LIST, sai_uint8_list_t); + + STA(ACL_ACTION_DATA_UINT8, sai_uint8_t); + STA(ACL_ACTION_DATA_INT8, sai_int8_t); + STA(ACL_ACTION_DATA_UINT16, sai_uint16_t); + STA(ACL_ACTION_DATA_INT16, sai_int16_t); + STA(ACL_ACTION_DATA_UINT32, sai_uint32_t); + STA(ACL_ACTION_DATA_INT32, sai_int32_t); + STA(ACL_ACTION_DATA_MAC, sai_mac_t); + STA(ACL_ACTION_DATA_IPV4, sai_ipv4_t); + STA(ACL_ACTION_DATA_IPV6, sai_ipv6_t); + STA(ACL_ACTION_DATA_OBJECT_ID, sai_object_id_t); + STA(ACL_ACTION_DATA_OBJECT_LIST, sai_object_list_t); + + ST(QOS_MAP_LIST, sai_qos_map_list_t); + + default: + + std::cerr << "unknown serialization type: " << md.serializationtype << std::endl; + throw; + } + + ss << std::endl; +} + +void metadata_generate_objects(const sai_attr_metadata_t& md, std::stringstream& ss) +{ + if (md.allowedobjecttypes.size() == 0) + { + return; + } + + ss << "@objects "; + + size_t count = md.allowedobjecttypes.size(); + + uint32_t i = 0; + + for (auto it = md.allowedobjecttypes.begin(); it != md.allowedobjecttypes.end(); it++, i++) + { + ss << "SAI_OBJECT_TYPE_" << get_object_type_name(*it); + + if (i != count - 1) + ss << ", "; + } + + ss << std::endl; +} + +void metadata_generate_flags(const sai_attr_metadata_t& md, std::stringstream& ss) +{ + ss << "@flags "; + + switch ((int)md.flags) + { + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY: + ss << "MANDATORY_ON_CREATE | CREATE_ONLY | KEY"; + break; + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY: + ss << "MANDATORY_ON_CREATE | CREATE_ONLY"; + break; + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET: + ss << "MANDATORY_ON_CREATE | CREATE_AND_SET"; + break; + case SAI_ATTR_FLAGS_CREATE_ONLY: + ss << "CREATE_ONLY"; + break; + case SAI_ATTR_FLAGS_CREATE_AND_SET: + ss << "CREATE_AND_SET"; + break; + case SAI_ATTR_FLAGS_READ_ONLY: + ss << "READ_ONLY"; + break; + + default: + std::cerr << "unknown flags" << std::endl; + throw; + } + + ss << std::endl; +} + +void metadata_generate_allownull(const sai_attr_metadata_t& md, std::stringstream& ss) +{ + if (md.allownullobjectid) + ss << "@allownull true" << std::endl; +} + +void metadata_generate_condition(const sai_attr_metadata_t& md, std::stringstream& ss) +{ + auto &hash = AttributesMetadata[md.objecttype]; + + if (md.conditions.empty()) + { + return; + } + + size_t index = 0; + + for (auto itc = md.conditions.begin(); itc!= md.conditions.end(); ++itc) + { + if (index == 0) + { + ss << "@condition "; + } + + auto& c = *itc; + auto it = hash.find(c.attrid); + + if (it == hash.end()) + { + std::cerr << "cond attr not found" << std::endl; + throw; + } + + const sai_attr_metadata_t &cmd = *it->second; + + switch (cmd.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + + ss + << get_attr_name(cmd.objecttype,cmd.attrid) + << " == " + << (c.condition.booldata ? "true" : "false"); + + break; + + case SAI_SERIALIZATION_TYPE_INT32: + + ss + << get_attr_name(cmd.objecttype,cmd.attrid) + << " == " + << c.enumstr; + break; + + default: + + std::cerr << "wrong serialization type " << cmd.serializationtype; + throw; + + } + + if (index != md.conditions.size()-1) + { + ss << " or "; + } + + index++; + } + + ss << std::endl; +} + +std::string get_default_value_string(const sai_attr_metadata_t& md) +{ + std::stringstream ss; + + // TODO we could assume default to false and 0 if not defined + auto &d = md.defaultvalue; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + return d.booldata? "true" : "false"; + case SAI_SERIALIZATION_TYPE_UINT8: + return std::to_string(d.u8); + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + return "complex"; + + case SAI_SERIALIZATION_TYPE_INT32: + return std::to_string(d.s32); + case SAI_SERIALIZATION_TYPE_UINT16: + return std::to_string(d.u16); + + case SAI_SERIALIZATION_TYPE_UINT32: + return std::to_string(d.u32); + case SAI_SERIALIZATION_TYPE_UINT64: + return std::to_string(d.u64); + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + return std::to_string(d.u32); + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + return d.aclfield.data.booldata? "true" : "false"; + + default: + + std::cerr << "not supported ser type: " << md.serializationtype <value.u32; + + // TODO range is in + // SAI_SWITCH_ATTR_ACL_TABLE_MINIMUM_PRIORITY .. SAI_SWITCH_ATTR_ACL_TABLE_MAXIMUM_PRIORITY + // extra validation will be needed here and snoop + + SWSS_LOG_DEBUG("acl priority: %d", priority); + } + + const sai_attribute_t* attr_size = get_attribute_by_id(SAI_ACL_TABLE_ATTR_SIZE, attr_count, attr_list); + + if (attr_size != NULL) + { + uint32_t size = attr_size->value.u32; // default value is zero + + SWSS_LOG_DEBUG("size %u", size); + + // TODO this attribute is special, since it can change dynamically, but it can be + // set on creation time and grow when entries are added + } + + // TODO group ID is special, since when not specified it's created automatically + // by switch and user can obtain it via GET api and group tables. + // This behaviour should be changed and so no object would be created internally + // there is a tricky way to track this object usage + + int fields = 0; + + for (uint32_t i = 0; i < attr_count; ++i) + { + if (attr_list[i].id >= SAI_ACL_TABLE_ATTR_FIELD_START && + attr_list[i].id <= SAI_ACL_TABLE_ATTR_FIELD_END) + { + fields++; + } + } + + if (fields == 0) + { + SWSS_LOG_ERROR("at least one acl table field must present"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // TODO another special attribute depending on switch SAI_SWITCH_ATTR_ACL_CAPABILITY + // it may be mandatory on create, why we need to query attributes and then pass them here? + // sdk logic can figure this out anyway + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_acl_table( + _In_ sai_object_id_t acl_table_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_acl_table_attribute( + _In_ sai_object_id_t acl_table_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_acl_table_attribute( + _In_ sai_object_id_t acl_table_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_acl_entry( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_priority = get_attribute_by_id(SAI_ACL_ENTRY_ATTR_PRIORITY, attr_count, attr_list); + + if (attr_priority != NULL) + { + SWSS_LOG_DEBUG("priority %u", attr_priority->value.u32); + + // TODO special, range in SAI_SWITCH_ATTR_ACL_ENTRY_MINIMUM_PRIORITY .. SAI_SWITCH_ATTR_ACL_ENTRY_MAXIMUM_PRIORITY + // TODO we need to check if priority was snooped and saved so we could validate it here + } + + // FIELDS + + int fields = 0; + + for (uint32_t i = 0; i < attr_count; ++i) + { + if (attr_list[i].id >= SAI_ACL_ENTRY_ATTR_FIELD_START && + attr_list[i].id <= SAI_ACL_ENTRY_ATTR_FIELD_END) + { + fields++; + } + } + + if (fields == 0) + { + SWSS_LOG_ERROR("at least one acl entry field must present"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // PORTS, some fields here may be CPU_PORT + // TODO where we use port also lag or tunnel ? + // TODO are actions read/write? + // TODO extra validation is needed since we must check if type of mirror session is ingress + // TODO extra validation is needed since we must check if type of mirror session is egress + // TODO extra validation may be needed in policer + // TODO extra validation may be needed on of sample packet + // TODO extra validation may be needed on CPU_QUEUE + // TODO extra validation may be needed on EGRESS_BLOCK_PORT_LIST + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_delete_acl_entry( + _In_ sai_object_id_t acl_entry_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_acl_entry_attribute( + _In_ sai_object_id_t acl_entry_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_acl_entry_attribute( + _In_ sai_object_id_t acl_entry_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO for get we need to check if attrib was set previously ? + // like field or action, or can we get action that was not set? + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_acl_counter( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_acl_counter( + _In_ sai_object_id_t acl_counter_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_acl_counter_attribute( + _In_ sai_object_id_t acl_counter_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_acl_counter_attribute( + _In_ sai_object_id_t acl_counter_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_acl_range( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_type = get_attribute_by_id(SAI_ACL_RANGE_ATTR_TYPE, attr_count, attr_list); + const sai_attribute_t* attr_limit = get_attribute_by_id(SAI_ACL_RANGE_ATTR_LIMIT, attr_count, attr_list); + + sai_acl_range_type_t type = (sai_acl_range_type_t)attr_type->value.s32; + sai_u32_range_t range = attr_limit->value.u32range; + + SWSS_LOG_DEBUG("acl range <%u..%u> of type %d", range.min, range.max, type); + + switch (type) + { + // layer 4 port range + case SAI_ACL_RANGE_L4_SRC_PORT_RANGE: + case SAI_ACL_RANGE_L4_DST_PORT_RANGE: + + // we allow 0 + if (range.min >= range.max || + //range.min < MINIMUM_L4_PORT_NUMBER || + //range.max < MINIMUM_L4_PORT_NUMBER || + range.min > MAXIMUM_L4_PORT_NUMBER || + range.max > MAXIMUM_L4_PORT_NUMBER) + { + SWSS_LOG_ERROR("invalid acl port range <%u..%u> in <%u..%u>", range.min, range.max, MINIMUM_L4_PORT_NUMBER, MAXIMUM_L4_PORT_NUMBER); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + case SAI_ACL_RANGE_OUTER_VLAN: + case SAI_ACL_RANGE_INNER_VLAN: + + if (range.min >= range.max || + range.min < MINIMUM_VLAN_NUMBER || + range.min > MAXIMUM_VLAN_NUMBER || + range.max < MINIMUM_VLAN_NUMBER || + range.max > MAXIMUM_VLAN_NUMBER) + { + SWSS_LOG_ERROR("invalid acl vlan range <%u..%u> in <%u..%u>", range.min, range.max, MINIMUM_VLAN_NUMBER, MAXIMUM_VLAN_NUMBER); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + case SAI_ACL_RANGE_PACKET_LENGTH: + + if (range.min >= range.max || + range.min > MAXIMUM_PACKET_SIZE || + range.max > MAXIMUM_PACKET_SIZE) + { + SWSS_LOG_ERROR("invalid acl vlan range <%u..%u> in <%u..%u>", range.min, range.max, MINIMUM_PACKET_SIZE, MAXIMUM_PACKET_SIZE); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + default: + + SWSS_LOG_ERROR("FATAL: inalid type %d", type); + + return SAI_STATUS_FAILURE; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_acl_range( + _In_ sai_object_id_t acl_range_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_acl_range_attribute( + _In_ sai_object_id_t acl_range_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_acl_range_attribute( + _In_ sai_object_id_t acl_range_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_buffer.cpp b/meta/sai_extra_buffer.cpp new file mode 100644 index 000000000000..37b7e207c9ea --- /dev/null +++ b/meta/sai_extra_buffer.cpp @@ -0,0 +1,98 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_buffer_pool( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_buffer_pool( + _In_ sai_object_id_t pool_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_buffer_pool_attr( + _In_ sai_object_id_t pool_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_buffer_pool_attr( + _In_ sai_object_id_t pool_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_buffer_profile( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO extra logic on checking profile buffer size may be needed + // TODO we need to query other attribute pool id assigned and check wheter mode is dynamic/static + + const sai_attribute_t* attr_shared_dynamic_th = get_attribute_by_id(SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH, attr_count, attr_list); + + if (attr_shared_dynamic_th != NULL) + { + // TODO check size + } + + const sai_attribute_t* attr_shared_static_th = get_attribute_by_id(SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH, attr_count, attr_list); + + if (attr_shared_static_th != NULL) + { + // TODO check size + } + + // TODO additional logic can be required for size check + // TODO check xoff xon thresholds + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_buffer_profile( + _In_ sai_object_id_t buffer_profile_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_buffer_profile_attr( + _In_ sai_object_id_t buffer_profile_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // TODO on set, changing buffer pool on profiles should noe be possible + // to change dynamic to static on the fly + // pool_id on profile should be create_only ? + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_buffer_profile_attr( + _In_ sai_object_id_t buffer_profile_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_fdb.cpp b/meta/sai_extra_fdb.cpp new file mode 100644 index 000000000000..1d1de262f987 --- /dev/null +++ b/meta/sai_extra_fdb.cpp @@ -0,0 +1,53 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_fdb_entry( + _In_ const sai_fdb_entry_t *fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_meta_data = get_attribute_by_id(SAI_FDB_ENTRY_ATTR_META_DATA, attr_count, attr_list); + + if (attr_meta_data != NULL) + { + // TODO validation range must be checked via SAI_SWITCH_ATTR_FDB_DST_USER_META_DATA_RANGE / saiswitch + + uint32_t meta_data = attr_meta_data->value.u32; + + SWSS_LOG_DEBUG("fdb metadata value: %u", meta_data); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_fdb_entry_attribute( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // TODO validate metadata SAI_FDB_ENTRY_ATTR_META_DATA + // depends on SAI_SWITCH_ATTR_FDB_DST_USER_META_DATA_RANGE + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_fdb_entry_attribute( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_hash.cpp b/meta/sai_extra_hash.cpp new file mode 100644 index 000000000000..240ee8852557 --- /dev/null +++ b/meta/sai_extra_hash.cpp @@ -0,0 +1,41 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_hash( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO validate if fields don't repeat (need param allow repeat) + // const sai_attribute_t* attr_native_field_list = get_attribute_by_id(SAI_HASH_ATTR_NATIVE_FIELD_LIST, attr_count, attr_list); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_hash( + _In_ sai_object_id_t hash_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_hash_attribute( + _In_ sai_object_id_t hash_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_hash_attribute( + _In_ sai_object_id_t hash_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_hostintf.cpp b/meta/sai_extra_hostintf.cpp new file mode 100644 index 000000000000..04b474279ee2 --- /dev/null +++ b/meta/sai_extra_hostintf.cpp @@ -0,0 +1,125 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_hostif_trap_group( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_hostif_trap_group( + _In_ sai_object_id_t hostif_trap_group_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_trap_group_attribute( + _In_ sai_object_id_t hostif_trap_group_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE: + + // TODO this can be tricky since this QUEUE is queue INDEX + // indirect depenency, by default there are 8 queues, but + // user can create extra one, so there may be 10, and what + // happens when this points to queue 10 and user remove this queue? + // on queue remove we should queue index on trap group and + // not allow to remove then + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_trap_group_attribute( + _In_ sai_object_id_t hostif_trap_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_trap_attribute( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // case SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL: + // TODO extra validation here maybe needed to check cb/fd/netdev + // we will need extra logic to validate this attribute (previous attributes) + + // case SAI_HOSTIF_TRAP_ATTR_FD: + // Valid only when SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL == SAI_HOSTIF_TRAP_CHANNEL_FD + // Must be set before set SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL to SAI_HOSTIF_TRAP_CHANNEL_FD + + // TODO additional logic here is required, this fd hostif + // must be type of sai_hostif_type_t == SAI_HOSTIF_TYPE_FD + // we need to check hostif attribute then + // + // TODO also what about netdev case ? + + // SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP: + // TODO that default trap group should also be + // on that trap groups list this would implify condition + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_trap_attribute( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_hostif( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // case SAI_HOSTIF_TYPE_FD: + // TODO check if it contains only ASCII and whether name is not used + // by other host interface + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_hostif( + _In_ sai_object_id_t hif_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_hostif_attribute( + _In_ sai_object_id_t hif_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_hostif_attribute( + _In_ sai_object_id_t hif_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + diff --git a/meta/sai_extra_lag.cpp b/meta/sai_extra_lag.cpp new file mode 100644 index 000000000000..d2fc605b083c --- /dev/null +++ b/meta/sai_extra_lag.cpp @@ -0,0 +1,80 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_lag( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_lag( + _In_ sai_object_id_t lag_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_lag_attribute( + _In_ sai_object_id_t lag_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_lag_attribute( + _In_ sai_object_id_t lag_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_lag_member( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO check if this port is not already a member in this LAG, can it be duplicated? + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_lag_member( + _In_ sai_object_id_t lag_member_id) +{ + SWSS_LOG_ENTER(); + + // since lag member is leaf it should be always safe to remove lag member + // but can there exist lag without members ? + + return SAI_STATUS_SUCCESS; +} + + +sai_status_t meta_pre_set_lag_member_attribute( + _In_ sai_object_id_t lag_member_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_lag_member_attribute( + _In_ sai_object_id_t lag_member_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_mirror.cpp b/meta/sai_extra_mirror.cpp new file mode 100644 index 000000000000..b662d46305aa --- /dev/null +++ b/meta/sai_extra_mirror.cpp @@ -0,0 +1,72 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t is_header_version_ok( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + const sai_attribute_t* attr_iphdr_version = get_attribute_by_id(SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION, attr_count, attr_list); + + if (attr_iphdr_version != NULL) + { + uint8_t iphdr_version = attr_iphdr_version->value.u8; + + switch (iphdr_version) + { + case 4: + case 6: + // ok + break; + + default: + + SWSS_LOG_ERROR("invalid ip header version value: %u", iphdr_version); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_mirror_session( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return is_header_version_ok(attr_count, attr_list); +} + +sai_status_t meta_pre_remove_mirror_session( + _In_ sai_object_id_t session_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_mirror_session_attribute( + _In_ sai_object_id_t session_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // TODO we need to type to decide which parameters are safe to set + // SAI_MIRROR_SESSION_ATTR_MONITOR_PORT: + // TODO should changing port during mirror session should be possible ? + // what if new port is somehow incompattible with current session? + + // SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE: // TODO validate GRE protocol + return is_header_version_ok(1, attr); +} + +sai_status_t meta_pre_get_mirror_session_attribute( + _In_ sai_object_id_t session_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_neighbor.cpp b/meta/sai_extra_neighbor.cpp new file mode 100644 index 000000000000..b5dd69f6221d --- /dev/null +++ b/meta/sai_extra_neighbor.cpp @@ -0,0 +1,39 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_neighbor_attribute( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_neighbor_attribute( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_nexthop.cpp b/meta/sai_extra_nexthop.cpp new file mode 100644 index 000000000000..39b21ecaa26d --- /dev/null +++ b/meta/sai_extra_nexthop.cpp @@ -0,0 +1,41 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_next_hop( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // SAI_NEXT_HOP_TUNNEL_ENCAP: + // TODO tunnel is existing, should be make some additional checks ? like tunnel encap type? + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_next_hop( + _In_ sai_object_id_t next_hop_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_next_hop_attribute( + _In_ sai_object_id_t next_hop_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_next_hop_attribute( + _In_ sai_object_id_t next_hop_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_nexthopgroup.cpp b/meta/sai_extra_nexthopgroup.cpp new file mode 100644 index 000000000000..7811a91ef6ae --- /dev/null +++ b/meta/sai_extra_nexthopgroup.cpp @@ -0,0 +1,38 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_next_hop_group( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_next_hop_group( + _In_ sai_object_id_t next_hop_group_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_next_hop_group_attribute( + _In_ sai_object_id_t next_hop_group_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_next_hop_group_attribute( + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_policer.cpp b/meta/sai_extra_policer.cpp new file mode 100644 index 000000000000..f9e0370e977f --- /dev/null +++ b/meta/sai_extra_policer.cpp @@ -0,0 +1,38 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_policer( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_policer( + _In_ sai_object_id_t policer_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_policer_attribute( + _In_ sai_object_id_t policer_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_policer_attribute( + _In_ sai_object_id_t policer_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_port.cpp b/meta/sai_extra_port.cpp new file mode 100644 index 000000000000..fb60f2e9afa6 --- /dev/null +++ b/meta/sai_extra_port.cpp @@ -0,0 +1,29 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_set_port_attribute( + _In_ sai_object_id_t port_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // case SAI_PORT_ATTR_SPEED: + // TODO validate speed's + + // TODO additional validation may be required on QOS + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_port_attribute( + _In_ sai_object_id_t port_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // SAI_PORT_ATTR_HW_LANE_LIST + // just log on post check + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_qosmaps.cpp b/meta/sai_extra_qosmaps.cpp new file mode 100644 index 000000000000..2d85401ce33b --- /dev/null +++ b/meta/sai_extra_qosmaps.cpp @@ -0,0 +1,109 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_qos_map( + _Out_ sai_object_id_t* qos_map_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO is that CREATE_ONLY or CREATE_AND_SET ? + const sai_attribute_t* attr_map_to_value_list = get_attribute_by_id(SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST, attr_count, attr_list); + + if (attr_map_to_value_list != NULL) + { + // TODO some extra validation may be required here + + sai_qos_map_list_t map_list = attr_map_to_value_list->value.qosmap; + + uint32_t count = map_list.count; + + sai_qos_map_t* list = map_list.list; + + if (list == NULL) + { + SWSS_LOG_ERROR("qos map list is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (count < 1) + { + SWSS_LOG_ERROR("qos map count is zero"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + SWSS_LOG_DEBUG("qos map count value: %u", count); + + for (uint32_t i = 0; i < count; ++i) + { + sai_qos_map_t qos_map = list[i]; + + // TODO queue index needs validation + + switch (qos_map.key.color) + { + case SAI_PACKET_COLOR_GREEN: + case SAI_PACKET_COLOR_YELLOW: + case SAI_PACKET_COLOR_RED: + // ok + break; + + default: + + SWSS_LOG_ERROR("qos map packet color invalid value: %d", qos_map.key.color); + + return SAI_STATUS_INVALID_PARAMETER; + } + + switch (qos_map.value.color) + { + case SAI_PACKET_COLOR_GREEN: + case SAI_PACKET_COLOR_YELLOW: + case SAI_PACKET_COLOR_RED: + // ok + break; + + default: + + SWSS_LOG_ERROR("qos map packet color invalid value: %d", qos_map.value.color); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_qos_map( + _In_ sai_object_id_t qos_map_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_qos_map_attribute( + _In_ sai_object_id_t qos_map_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // TODO double check if it's possible to change that attributes on the fly + // case SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST: + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_qos_map_attribute( + _In_ sai_object_id_t qos_map_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_queue.cpp b/meta/sai_extra_queue.cpp new file mode 100644 index 000000000000..02fe0b8141bc --- /dev/null +++ b/meta/sai_extra_queue.cpp @@ -0,0 +1,60 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_queue( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_index = get_attribute_by_id(SAI_QUEUE_ATTR_INDEX, attr_count, attr_list); + + uint8_t index = attr_index->value.u8; + + if (index > 16) // TODO see where we can get actual value + { + SWSS_LOG_ERROR("invalid queue index value: %u", index); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // TODO scheduler and profile are assigned by default from some internal objects + // they must be here set as mandatory_on create, or is it possible to disable scheduler or profile? + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_queue( + _In_ sai_object_id_t queue_id) +{ + SWSS_LOG_ENTER(); + + // TODO check if it safe to remove queue + // it may require some extra logic sine queues + // are pointed by index + // some internal queues may not be possible to remove + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_queue_attribute( + _In_ sai_object_id_t queue_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + // TODO double check if it's possible to change that attributes on the fly + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_queue_attribute( + _In_ sai_object_id_t queue_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + diff --git a/meta/sai_extra_route.cpp b/meta/sai_extra_route.cpp new file mode 100644 index 000000000000..7d3f866c44b1 --- /dev/null +++ b/meta/sai_extra_route.cpp @@ -0,0 +1,39 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_route( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_route( + _In_ const sai_unicast_route_entry_t* unicast_route_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_route_attribute( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_route_attribute( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_router.cpp b/meta/sai_extra_router.cpp new file mode 100644 index 000000000000..6f0ba6822068 --- /dev/null +++ b/meta/sai_extra_router.cpp @@ -0,0 +1,38 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_virtual_router( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_virtual_router( + _In_ sai_object_id_t vr_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_virtual_router_attribute( + _In_ sai_object_id_t vr_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_virtual_router_attribute( + _In_ sai_object_id_t vr_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_routerintf.cpp b/meta/sai_extra_routerintf.cpp new file mode 100644 index 000000000000..62f60326db5a --- /dev/null +++ b/meta/sai_extra_routerintf.cpp @@ -0,0 +1,38 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_router_interface( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_router_interface( + _In_ sai_object_id_t rif_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_router_interface_attribute( + _In_ sai_object_id_t rif_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_router_interface_attribute( + _In_ sai_object_id_t rif_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_samplepacket.cpp b/meta/sai_extra_samplepacket.cpp new file mode 100644 index 000000000000..650998682b20 --- /dev/null +++ b/meta/sai_extra_samplepacket.cpp @@ -0,0 +1,38 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_samplepacket_session( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_samplepacket_session( + _In_ sai_object_id_t session_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_samplepacket_attribute( + _In_ sai_object_id_t session_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_samplepacket_attribute( + _In_ sai_object_id_t session_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_scheduler.cpp b/meta/sai_extra_scheduler.cpp new file mode 100644 index 000000000000..faf53d1e4bcc --- /dev/null +++ b/meta/sai_extra_scheduler.cpp @@ -0,0 +1,68 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +// could be in metadata +#define MIN_SCHEDULING_WEIGHT 1 +#define MAX_SCHEDULING_WEIGHT 100 + +sai_status_t meta_pre_create_scheduler_profile( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_scheduling_weight = get_attribute_by_id(SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT, attr_count, attr_list); + + if (attr_scheduling_weight != NULL) + { + uint8_t weight = attr_scheduling_weight->value.u8; + + if (weight < MIN_SCHEDULING_WEIGHT || weight > MAX_SCHEDULING_WEIGHT) + { + SWSS_LOG_ERROR("invalid scheduling weight %u <%u..%u>", weight, MIN_SCHEDULING_WEIGHT, MAX_SCHEDULING_WEIGHT); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_scheduler_profile( + _In_ sai_object_id_t scheduler_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_scheduler_attribute( + _In_ sai_object_id_t scheduler_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + if (attr->id == SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT) + { + uint8_t weight = attr->value.u8; + + if (weight < MIN_SCHEDULING_WEIGHT || weight > MAX_SCHEDULING_WEIGHT) + { + SWSS_LOG_ERROR("invalid scheduling weight %u <%u..%u>", weight, MIN_SCHEDULING_WEIGHT, MAX_SCHEDULING_WEIGHT); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_scheduler_attribute( + _In_ sai_object_id_t scheduler_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_schedulergroup.cpp b/meta/sai_extra_schedulergroup.cpp new file mode 100644 index 000000000000..ca3baa4c04d2 --- /dev/null +++ b/meta/sai_extra_schedulergroup.cpp @@ -0,0 +1,63 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_scheduler_group( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_level = get_attribute_by_id(SAI_SCHEDULER_GROUP_ATTR_LEVEL, attr_count, attr_list); + const sai_attribute_t* attr_max_childs = get_attribute_by_id(SAI_SCHEDULER_GROUP_ATTR_MAX_CHILDS , attr_count, attr_list); + + uint8_t level = attr_level->value.u8; + + if (level > 16) + { + SWSS_LOG_ERROR("invalid level value: %u <%u..%u>", level, 0, 16); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // TODO level will require some additional validation to not crete loops + + uint8_t max_childs = attr_max_childs->value.u8; + + if (max_childs > 64) + { + SWSS_LOG_ERROR("invalid max childs value: %u <%u..%u>", max_childs, 0, 64); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // TODO max childs may require more validation + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_scheduler_group( + _In_ sai_object_id_t scheduler_group_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_scheduler_group_attribute( + _In_ sai_object_id_t scheduler_group_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_scheduler_group_attribute( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_stp.cpp b/meta/sai_extra_stp.cpp new file mode 100644 index 000000000000..62f4ee21c3bb --- /dev/null +++ b/meta/sai_extra_stp.cpp @@ -0,0 +1,38 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_stp( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_stp( + _In_ sai_object_id_t stp_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_stp_attribute( + _In_ sai_object_id_t stp_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_stp_attribute( + _In_ sai_object_id_t stp_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_switch.cpp b/meta/sai_extra_switch.cpp new file mode 100644 index 000000000000..3f2c69ac118a --- /dev/null +++ b/meta/sai_extra_switch.cpp @@ -0,0 +1,19 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_set_switch_attribute( + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_switch_attribute( + _In_ sai_uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_tunnel.cpp b/meta/sai_extra_tunnel.cpp new file mode 100644 index 000000000000..ac98cc845355 --- /dev/null +++ b/meta/sai_extra_tunnel.cpp @@ -0,0 +1,179 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_tunnel_map( + _Out_ sai_object_id_t* tunnel_map_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + const sai_attribute_t* attr_map_to_value_list = get_attribute_by_id(SAI_TUNNEL_MAP_ATTR_MAP_TO_VALUE_LIST, attr_count, attr_list); + + // TODO check if additional validation is needed on those types + // SAI_TUNNEL_MAP_OECN_TO_UECN: + // SAI_TUNNEL_MAP_UECN_OECN_TO_OECN: + // SAI_TUNNEL_MAP_VNI_TO_VLAN_ID: + // SAI_TUNNEL_MAP_VLAN_ID_TO_VNI: + + // TODO validate tunnel map list + + if (attr_map_to_value_list != NULL) + { + const sai_tunnel_map_list_t* tunnel_map_list = &attr_map_to_value_list->value.tunnelmap; + + if (tunnel_map_list->list == NULL) + { + SWSS_LOG_ERROR("tunnel map list is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + for (uint32_t i = 0; i < tunnel_map_list->count; ++i) + { + const sai_tunnel_map_t* tunnel_map = &tunnel_map_list->list[i]; + + // TODO validate tunnel map + SWSS_LOG_DEBUG("tunnel map pointer: %llx", tunnel_map); + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_tunnel_map( + _In_ sai_object_id_t tunnel_map_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_tunnel_map_attribute( + _In_ sai_object_id_t tunnel_map_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_tunnel_map_attribute( + _In_ sai_object_id_t tunnel_map_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_tunnel( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO for GRE/VXLAN it may be different type (router interface, overlay/underlay + // + // TODO validate object on that list! if they exist + // shoud this list contain at least 1 element ? or can it be empty? + // check for duplicates on list ? - ecn mappers + + // TODO sai spec is inconsisten here, if this is mandatory attribute on some condition, + // then it cannot have default value, dscp mode and ttl mode + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_tunnel( + _In_ sai_object_id_t tunnel_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_tunnel_attribute( + _In_ sai_object_id_t tunnel_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + switch (attr->id) + { + case SAI_TUNNEL_ATTR_ENCAP_ECN_MODE: + case SAI_TUNNEL_ATTR_ENCAP_MAPPERS: + + // TODO validate this use case + + break; + + case SAI_TUNNEL_ATTR_DECAP_ECN_MODE: + case SAI_TUNNEL_ATTR_DECAP_MAPPERS: + + // TODO validate this use case + + break; + + default: + + SWSS_LOG_ERROR("set attribute id %d is not allowed", attr->id); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_tunnel_attribute( + _In_ sai_object_id_t tunnel_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_tunnel_term_table_entry ( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO check is this conditional attribute, maybe this action is only + // required for ip in ip tunnel types + + // TODO additional checks may be required sinec this action tunnel id is used for + // decap so maybe this tunnel must have special attributes on creation set + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_tunnel_term_table_entry ( + _In_ sai_object_id_t tunnel_term_table_entry_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_tunnel_term_table_entry_attribute( + _In_ sai_object_id_t tunnel_term_table_entry_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_tunnel_term_table_entry_attribute( + _In_ sai_object_id_t tunnel_term_table_entry_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_udf.cpp b/meta/sai_extra_udf.cpp new file mode 100644 index 000000000000..a9e0695da87a --- /dev/null +++ b/meta/sai_extra_udf.cpp @@ -0,0 +1,129 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_udf( + _Out_ sai_object_id_t* udf_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO validate offset value range + // TODO length must be quual to group attr length ? + // TODO extra validation may be required here on mask + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_udf( + _In_ sai_object_id_t udf_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_udf_attribute( + _In_ sai_object_id_t udf_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_udf_attribute( + _In_ sai_object_id_t udf_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_udf_match( + _Out_ sai_object_id_t* udf_match_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // const sai_attribute_t* attr_l2_type = get_attribute_by_id(SAI_UDF_MATCH_ATTR_L2_TYPE, attr_count, attr_list); + // const sai_attribute_t* attr_l3_type = get_attribute_by_id(SAI_UDF_MATCH_ATTR_L3_TYPE, attr_count, attr_list); + // const sai_attribute_t* attr_gre_type = get_attribute_by_id(SAI_UDF_MATCH_ATTR_GRE_TYPE, attr_count, attr_list); + // const sai_attribute_t* attr_priority = get_attribute_by_id(SAI_UDF_MATCH_ATTR_PRIORITY, attr_count, attr_list); + + // sai_acl_field_data_t(uint16_t) + // sai_acl_field_data_t(uint8_t) + // sai_acl_field_data_t(uint16_t) + + // TODO default is to NONE, what this mean? is disabled or what ? + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_udf_match( + _In_ sai_object_id_t udf_match_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_udf_match_attribute( + _In_ sai_object_id_t udf_match_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_udf_match_attribute( + _In_ sai_object_id_t udf_match_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_udf_group( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + // TODO extra validation may be required on length + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_udf_group( + _In_ sai_object_id_t udf_group_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_udf_group_attribute( + _In_ sai_object_id_t udf_group_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_udf_group_attribute( + _In_ sai_object_id_t udf_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_vlan.cpp b/meta/sai_extra_vlan.cpp new file mode 100644 index 000000000000..9afa67541936 --- /dev/null +++ b/meta/sai_extra_vlan.cpp @@ -0,0 +1,73 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_vlan( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_vlan( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_vlan_attribute( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_vlan_attribute( + _In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_create_vlan_member( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_vlan_member( + _In_ sai_object_id_t vlan_member_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_vlan_member_attribute( + _In_ sai_object_id_t vlan_member_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_vlan_member_attribute( + _In_ sai_object_id_t vlan_member_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_extra_wred.cpp b/meta/sai_extra_wred.cpp new file mode 100644 index 000000000000..ded0024ba989 --- /dev/null +++ b/meta/sai_extra_wred.cpp @@ -0,0 +1,333 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +sai_status_t meta_pre_create_wred_profile( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_ecn_mark_mode_t ecn_mark_mode = SAI_ECN_MARK_MODE_NONE; + + const sai_attribute_t* attr_ecn_mark_mode = get_attribute_by_id(SAI_WRED_ATTR_ECN_MARK_MODE, attr_count, attr_list); + + if (attr_ecn_mark_mode != NULL) + { + ecn_mark_mode = (sai_ecn_mark_mode_t)attr_ecn_mark_mode->value.s32; + + switch (ecn_mark_mode) + { + case SAI_ECN_MARK_MODE_NONE: + case SAI_ECN_MARK_MODE_GREEN: + case SAI_ECN_MARK_MODE_YELLOW: + case SAI_ECN_MARK_MODE_RED: + case SAI_ECN_MARK_MODE_GREEN_YELLOW: + case SAI_ECN_MARK_MODE_GREEN_RED: + case SAI_ECN_MARK_MODE_YELLOW_RED: + case SAI_ECN_MARK_MODE_ALL: + // ok + break; + + default: + + SWSS_LOG_ERROR("invalid ecn mark mode value: %d", ecn_mark_mode); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // TODO there should be probably logic here like: + // green_min < green_max < yellow_min < yellow_max < red_min < red_max + // This logic will be required also inside SET, so + + // TODO need to be obrained from switch, also will be required during set + uint32_t max_buffer_size = 0x10000; // is this SAI_SWITCH_ATTR_TOTAL_BUFFER_SIZE ? + + // TODO change numbers to defines + + // GREEN + + bool green_enable = false; // default value + + const sai_attribute_t* attr_green_enable = get_attribute_by_id(SAI_WRED_ATTR_GREEN_ENABLE, attr_count, attr_list); + + if (attr_green_enable != NULL) + { + green_enable = attr_green_enable->value.booldata; + } + + const sai_attribute_t* attr_green_min_threshold = get_attribute_by_id(SAI_WRED_ATTR_GREEN_MIN_THRESHOLD, attr_count, attr_list); + const sai_attribute_t* attr_green_max_threshold = get_attribute_by_id(SAI_WRED_ATTR_GREEN_MAX_THRESHOLD, attr_count, attr_list); + + if (green_enable || + ecn_mark_mode == SAI_ECN_MARK_MODE_GREEN || + ecn_mark_mode == SAI_ECN_MARK_MODE_GREEN_YELLOW || + ecn_mark_mode == SAI_ECN_MARK_MODE_GREEN_RED || + ecn_mark_mode == SAI_ECN_MARK_MODE_ALL) + { + if (attr_green_min_threshold == NULL) + { + SWSS_LOG_ERROR("missing green min threshold attribute"); + + return SAI_STATUS_MANDATORY_ATTRIBUTE_MISSING; + } + + uint32_t green_min_threshold = attr_green_min_threshold->value.u32; + + // TODO this is extra validation + // TODO get max buffer size + if (green_min_threshold < 1 || green_min_threshold > max_buffer_size) + { + SWSS_LOG_ERROR("invalid green min threshold value: %u <%u..%u>", green_min_threshold, 1, max_buffer_size); + + return SAI_STATUS_INVALID_PARAMETER; + } + + uint32_t green_max_threshold = attr_green_max_threshold->value.u32; + + // TODO this is extra validation + // TODO get max buffer size + if (green_max_threshold < 1 || green_max_threshold > max_buffer_size) + { + SWSS_LOG_ERROR("invalid green max threshold value: %u <%u..%u>", green_max_threshold, 1, max_buffer_size); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // TODO should this be only valid when green enable? + const sai_attribute_t* attr_green_drop_probability = get_attribute_by_id(SAI_WRED_ATTR_GREEN_DROP_PROBABILITY, attr_count, attr_list); + + uint32_t green_drop_probability = 100; // default value + + if (attr_green_drop_probability != NULL) + { + green_drop_probability = attr_green_drop_probability->value.u32; + + if (green_drop_probability > 100) + { + SWSS_LOG_ERROR("invalid green drop probability: %u <%u..%u>", green_drop_probability, 0, 100); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // YELLOW + + bool yellow_enable = false; // default value + + const sai_attribute_t* attr_yellow_enable = get_attribute_by_id(SAI_WRED_ATTR_YELLOW_ENABLE, attr_count, attr_list); + + if (attr_yellow_enable != NULL) + { + yellow_enable = attr_yellow_enable->value.booldata; + } + + const sai_attribute_t* attr_yellow_min_threshold = get_attribute_by_id(SAI_WRED_ATTR_YELLOW_MIN_THRESHOLD, attr_count, attr_list); + const sai_attribute_t* attr_yellow_max_threshold = get_attribute_by_id(SAI_WRED_ATTR_YELLOW_MAX_THRESHOLD, attr_count, attr_list); + + if (yellow_enable || + ecn_mark_mode == SAI_ECN_MARK_MODE_YELLOW || + ecn_mark_mode == SAI_ECN_MARK_MODE_GREEN_YELLOW || + ecn_mark_mode == SAI_ECN_MARK_MODE_YELLOW_RED || + ecn_mark_mode == SAI_ECN_MARK_MODE_ALL) + { + if (attr_yellow_min_threshold == NULL) + { + SWSS_LOG_ERROR("missing yellow min threshold attribute"); + + return SAI_STATUS_MANDATORY_ATTRIBUTE_MISSING; + } + + uint32_t yellow_min_threshold = attr_yellow_min_threshold->value.u32; + + // TODO this is extra validation + // TODO get max buffer size + if (yellow_min_threshold < 1 || yellow_min_threshold > max_buffer_size) + { + SWSS_LOG_ERROR("invalid yellow min threshold value: %u <%u..%u>", yellow_min_threshold, 1, max_buffer_size); + + return SAI_STATUS_INVALID_PARAMETER; + } + + uint32_t yellow_max_threshold = attr_yellow_max_threshold->value.u32; + + // TODO this is extra validation + // TODO get max buffer size + if (yellow_max_threshold < 1 || yellow_max_threshold > max_buffer_size) + { + SWSS_LOG_ERROR("invalid yellow max threshold value: %u <%u..%u>", yellow_max_threshold, 1, max_buffer_size); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // TODO should this be only valid when yellow enable? + const sai_attribute_t* attr_yellow_drop_probability = get_attribute_by_id(SAI_WRED_ATTR_YELLOW_DROP_PROBABILITY, attr_count, attr_list); + + uint32_t yellow_drop_probability = 100; // default value + + if (attr_yellow_drop_probability != NULL) + { + yellow_drop_probability = attr_yellow_drop_probability->value.u32; + + if (yellow_drop_probability > 100) + { + SWSS_LOG_ERROR("invalid yellow drop probability: %u <%u..%u>", yellow_drop_probability, 0, 100); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // RED + + bool red_enable = false; // default value + + const sai_attribute_t* attr_red_enable = get_attribute_by_id(SAI_WRED_ATTR_RED_ENABLE, attr_count, attr_list); + + if (attr_red_enable != NULL) + { + red_enable = attr_red_enable->value.booldata; + } + + const sai_attribute_t* attr_red_min_threshold = get_attribute_by_id(SAI_WRED_ATTR_RED_MIN_THRESHOLD, attr_count, attr_list); + const sai_attribute_t* attr_red_max_threshold = get_attribute_by_id(SAI_WRED_ATTR_RED_MAX_THRESHOLD, attr_count, attr_list); + + if (red_enable || + ecn_mark_mode == SAI_ECN_MARK_MODE_RED || + ecn_mark_mode == SAI_ECN_MARK_MODE_GREEN_RED || + ecn_mark_mode == SAI_ECN_MARK_MODE_YELLOW_RED || + ecn_mark_mode == SAI_ECN_MARK_MODE_ALL) + { + if (attr_red_min_threshold == NULL) + { + SWSS_LOG_ERROR("missing red min threshold attribute"); + + return SAI_STATUS_MANDATORY_ATTRIBUTE_MISSING; + } + + uint32_t red_min_threshold = attr_red_min_threshold->value.u32; + + // TODO this is extra validation + // TODO get max buffer size + if (red_min_threshold < 1 || red_min_threshold > max_buffer_size) + { + SWSS_LOG_ERROR("invalid red min threshold value: %u <%u..%u>", red_min_threshold, 1, max_buffer_size); + + return SAI_STATUS_INVALID_PARAMETER; + } + + uint32_t red_max_threshold = attr_red_max_threshold->value.u32; + + // TODO this is extra validation + // TODO get max buffer size + if (red_max_threshold < 1 || red_max_threshold > max_buffer_size) + { + SWSS_LOG_ERROR("invalid red max threshold value: %u <%u..%u>", red_max_threshold, 1, max_buffer_size); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // TODO should this be only valid when red enable? + const sai_attribute_t* attr_red_drop_probability = get_attribute_by_id(SAI_WRED_ATTR_RED_DROP_PROBABILITY, attr_count, attr_list); + + uint32_t red_drop_probability = 100; // default value + + if (attr_red_drop_probability != NULL) + { + red_drop_probability = attr_red_drop_probability->value.u32; + + if (red_drop_probability > 100) + { + SWSS_LOG_ERROR("invalid red drop probability: %u <%u..%u>", red_drop_probability, 0, 100); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // END OF GREEN YELLOW RED + + sai_uint8_t weight = 0; // default weight + + const sai_attribute_t* attr_weight = get_attribute_by_id(SAI_WRED_ATTR_WEIGHT, attr_count, attr_list); + + if (attr_weight != NULL) + { + weight = attr_weight->value.u8; + } + + if (weight > 15) + { + SWSS_LOG_ERROR("invalid weight value: %u <%u..%u>", weight, 0, 15); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_remove_wred_profile( + _In_ sai_object_id_t wred_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_set_wred_attribute( + _In_ sai_object_id_t wred_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + switch (attr->id) + { + // TODO what happen if enable green and green threshold is not set ? + case SAI_WRED_ATTR_GREEN_MIN_THRESHOLD: + case SAI_WRED_ATTR_GREEN_MAX_THRESHOLD: + // TODO check if min < max + break; + case SAI_WRED_ATTR_GREEN_DROP_PROBABILITY: + break; + + case SAI_WRED_ATTR_YELLOW_MIN_THRESHOLD: + case SAI_WRED_ATTR_YELLOW_MAX_THRESHOLD: + // TODO check if min < max + break; + case SAI_WRED_ATTR_YELLOW_DROP_PROBABILITY: + break; + + case SAI_WRED_ATTR_RED_MIN_THRESHOLD: + case SAI_WRED_ATTR_RED_MAX_THRESHOLD: + // TODO check if min < max + break; + case SAI_WRED_ATTR_RED_DROP_PROBABILITY: + break; + + case SAI_WRED_ATTR_WEIGHT: + break; + + // TODO can ECN be changed ? some attributes may be invalid or they may start to be valid + // case SAI_WRED_ATTR_ECN_MARK_MODE: // TODO this should be CREATE_ONLY attribute + // break; + + default: + + SWSS_LOG_ERROR("setting attribute id %d is not supported", attr->id); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_pre_get_wred_attribute( + _In_ sai_object_id_t wred_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} diff --git a/meta/sai_meta.cpp b/meta/sai_meta.cpp new file mode 100644 index 000000000000..a02bf040dd6e --- /dev/null +++ b/meta/sai_meta.cpp @@ -0,0 +1,4884 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +#include + +#include +#include + +bool is_ipv6_mask_valid( + _In_ const uint8_t* mask) +{ + if (mask == NULL) + { + SWSS_LOG_ERROR("mask is null"); + + return false; + } + + int ones = 0; + bool zeros = false; + + for (uint8_t i = 0; i < 128; i++) + { + bool bit = mask[i/8] & (1 << (7 - (i%8))); + + if (zeros && bit) + { + return false; + } + + zeros |= !bit; + + if (bit) + { + ones++; + } + } + + return true; +} + +int get_ipv6_mask( + _In_ const uint8_t* mask) +{ + if (mask == NULL) + { + SWSS_LOG_ERROR("FATAL: mask is null"); + throw; + } + + int ones = 0; + bool zeros = false; + + for (uint8_t i = 0; i < 128; i++) + { + bool bit = mask[i/8] & (1 << (7 - (i%8))); + + if (zeros && bit) + { + SWSS_LOG_ERROR("FATAL: mask is not correct"); + throw; + } + + zeros |= !bit; + + if (bit) + { + ones++; + } + } + + return ones; +} + +std::string mac_to_string( + _In_ const sai_mac_t& mac) +{ + char macstr[128]; + + sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + return macstr; +} + +std::string fdb_entry_to_string( + _In_ const sai_fdb_entry_t& fdb_entry) +{ + return "mac:" + mac_to_string(fdb_entry.mac_address) +";vlan:" + std::to_string(fdb_entry.vlan_id); +} + +std::string oid_to_string( + _In_ sai_object_id_t oid) +{ + char str[32]; + + sprintf(str, "0x%lx", oid); + + return str; +} + +std::string ip_addr_to_string( + _In_ sai_ip_addr_family_t family, const void* mem) +{ + char str[INET6_ADDRSTRLEN]; + + switch (family) + { + case SAI_IP_ADDR_FAMILY_IPV4: + + { + struct sockaddr_in sa; + + memcpy(&sa.sin_addr, mem, 4); + + if (inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN) == NULL) + { + SWSS_LOG_ERROR("FATAL: failed to convert IPv4 address, errno: %d", errno); + throw; + } + + break; + } + + case SAI_IP_ADDR_FAMILY_IPV6: + + { + struct sockaddr_in6 sa6; + + memcpy(&sa6.sin6_addr, mem, 16); + + if (inet_ntop(AF_INET6, &(sa6.sin6_addr), str, INET6_ADDRSTRLEN) == NULL) + { + SWSS_LOG_ERROR("FATAL: failed to convert IPv6 address, errno: %d", errno); + throw; + } + + break; + } + + default: + + SWSS_LOG_ERROR("FATAL: invalid ip address family: %d", family); + throw; + } + + return str; +} + +std::string ip_address_to_string( + _In_ const sai_ip_address_t& ip) +{ + return "[" + ip_addr_to_string(ip.addr_family, &ip.addr) + "]"; +} + +std::string neighbor_entry_to_string( + _In_ const sai_neighbor_entry_t& neighbor_entry) +{ + return "rif:" + oid_to_string(neighbor_entry.rif_id) + ";ip:" + ip_address_to_string(neighbor_entry.ip_address); +} + +std::string ip_prefix_to_string( + _In_ const sai_ip_prefix_t& prefix) +{ + if (prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + return "[" + ip_addr_to_string(prefix.addr_family, &prefix.addr) + "/" + + ip_addr_to_string(prefix.addr_family, &prefix.mask) + "]"; + } + + return "[" + ip_addr_to_string(prefix.addr_family, &prefix.addr) + "/" + + std::to_string(get_ipv6_mask(prefix.mask.ip6)) + "]"; +} + +std::string route_entry_to_string( + _In_ const sai_unicast_route_entry_t& route_entry) +{ + return "vr:" + oid_to_string(route_entry.vr_id) + ";dest:" + ip_prefix_to_string(route_entry.destination); +} + +std::string get_object_meta_key_string( + _In_ const sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); + + std::string key; + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_SWITCH: + key = "switch:0"; + break; + + case SAI_OBJECT_TYPE_VLAN: + key = "vlan:" + std::to_string(meta_key.key.vlan_id); + break; + + case SAI_OBJECT_TYPE_TRAP: + key = "trap:" + std::to_string(meta_key.key.trap_id); + break; + + case SAI_OBJECT_TYPE_FDB: + key = "fdb:" + fdb_entry_to_string(meta_key.key.fdb_entry); + break; + + case SAI_OBJECT_TYPE_ROUTE: + key = "route:" + route_entry_to_string(meta_key.key.route_entry); + break; + + case SAI_OBJECT_TYPE_NEIGHBOR: + key = "neighbor:" + neighbor_entry_to_string(meta_key.key.neighbor_entry); + break; + + default: + key = "oid:" + oid_to_string(meta_key.key.object_id); + break; + } + + SWSS_LOG_DEBUG("%s", key.c_str()); + + return key; +} + +const sai_attribute_t* get_attribute_by_id( + _In_ sai_attr_id_t id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + if (attr_list == NULL) + { + SWSS_LOG_ERROR("attribute list is null"); + + return NULL; + } + + for (uint32_t i = 0; i < attr_count; ++i) + { + if (attr_list[i].id == id) + { + return &attr_list[i]; + } + } + + return NULL; +} + +const sai_attr_metadata_t* get_attribute_metadata( + _In_ sai_object_type_t objecttype, + _In_ sai_attr_id_t attrid) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_DEBUG("objecttype: %s, attrid: %d", get_object_type_name(objecttype), attrid); + + const auto &it = AttributesMetadata.find(objecttype); + + if (it == AttributesMetadata.end()) + { + SWSS_LOG_ERROR("invalid object type value: %d", objecttype); + + return NULL; + } + + const auto &attrset = it->second; + + const auto &ita = attrset.find(attrid); + + if (ita == attrset.end()) + { + SWSS_LOG_ERROR("attribute %d not found in metadata", attrid); + + return NULL; + } + + return ita->second; +} + +std::vector get_attributes_metadata( + _In_ sai_object_type_t objecttype) +{ + SWSS_LOG_ENTER(); + + // NOTE: this is not performance best, we can do better + + SWSS_LOG_DEBUG("objecttype: %d", objecttype); + + const auto &it = AttributesMetadata.find(objecttype); + + std::vector attrs; + + if (it == AttributesMetadata.end()) + { + SWSS_LOG_ERROR("invalid object type value: %d", objecttype); + + return attrs; + } + + for (auto i: it->second) + { + attrs.push_back(i.second); + } + + return attrs; +} + +class SaiAttrWrapper +{ + public: + + SaiAttrWrapper( + _In_ sai_object_type_t objecttype, + _In_ sai_attr_serialization_type_t st, + _In_ const sai_attribute_t& attr): + m_objecttype(objecttype), + m_serializationtype(st), + m_attr(attr) + { + m_attr.id = attr.id; + + std::string s; + sai_serialize_attr_value(st, attr, s, false); + + int index = 0; + sai_deserialize_attr_value(s, index, st, m_attr, false); + } + + ~SaiAttrWrapper() + { + sai_deserialize_free_attribute_value(m_serializationtype, m_attr); + } + + const sai_attribute_t* getattr() const + { + return &m_attr; + } + + sai_attr_serialization_type_t getserializationtype() const + { + return m_serializationtype; + } + + private: + + SaiAttrWrapper(const SaiAttrWrapper&); + SaiAttrWrapper& operator=(const SaiAttrWrapper&); + + sai_object_type_t m_objecttype; + sai_attr_serialization_type_t m_serializationtype; + sai_attribute_t m_attr; +}; + +#define META_LOG_ERROR(md, format, ...) SWSS_LOG_ERROR("%s " format, get_attr_info(md).c_str(), ##__VA_ARGS__) +#define META_LOG_DEBUG(md, format, ...) SWSS_LOG_DEBUG("%s " format, get_attr_info(md).c_str(), ##__VA_ARGS__) +#define META_LOG_NOTICE(md, format, ...) SWSS_LOG_NOTICE("%s " format, get_attr_info(md).c_str(), ##__VA_ARGS__) + +// traps and vlan will be converted to oid +// fdb, route, neighbor don't need reference count, +// they are leafs and can be removed at any time +std::unordered_map ObjectReferences; +std::unordered_map VlanReferences; +std::unordered_map AttributeKeys; +std::unordered_map>> ObjectAttrHash; + +// GENERIC REFERENCE FUNCTIONS + +bool object_reference_exists( + _In_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + bool exists = ObjectReferences.find(oid) != ObjectReferences.end(); + + SWSS_LOG_DEBUG("object 0x%llx refrence: %s", oid, exists ? "exists" : "missing"); + + return exists; +} + +void object_reference_inc( + _In_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + if (oid == SAI_NULL_OBJECT_ID) + { + return; + } + + if (!object_reference_exists(oid)) + { + SWSS_LOG_ERROR("FATAL: object oid 0x%llx not in reference map", oid); + throw; + } + + ObjectReferences[oid]++; + + SWSS_LOG_DEBUG("increased reference on oid 0x%llx to %d", oid, ObjectReferences[oid]); +} + +void object_reference_dec( + _In_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + if (oid == SAI_NULL_OBJECT_ID) + { + return; + } + + if (!object_reference_exists(oid)) + { + SWSS_LOG_ERROR("FATAL: object oid 0x%llx not in reference map", oid); + throw; + } + + ObjectReferences[oid]--; + + if (ObjectReferences[oid] < 0) + { + SWSS_LOG_ERROR("FATAL: object oid 0x%llx reference count is negative!", oid); + throw; + } + + SWSS_LOG_DEBUG("decreased reference on oid 0x%llx to %d", oid, ObjectReferences[oid]); +} + +void object_reference_dec( + _In_ const sai_object_list_t& list) +{ + SWSS_LOG_ENTER(); + + for (uint32_t i = 0; i < list.count; ++i) + { + object_reference_dec(list.list[i]); + } +} + +void object_reference_inc( + _In_ const sai_object_list_t& list) +{ + SWSS_LOG_ENTER(); + + for (uint32_t i = 0; i < list.count; ++i) + { + object_reference_inc(list.list[i]); + } +} + +void object_reference_insert( + _In_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + if (object_reference_exists(oid)) + { + SWSS_LOG_ERROR("FATAL: object oid 0x%llx already in reference map"); + throw; + } + + ObjectReferences[oid] = 0; + + SWSS_LOG_DEBUG("inserted reference on 0x%llx", oid); +} + +int32_t object_reference_count( + _In_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + if (object_reference_exists(oid)) + { + int32_t count = ObjectReferences[oid]; + + SWSS_LOG_DEBUG("reference count on oid 0x%llx is %d", oid, count); + + return count; + } + + SWSS_LOG_ERROR("FATAL: object oid 0x%llx reference not in map", oid); + throw; +} + +void object_reference_remove( + _In_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + if (object_reference_exists(oid)) + { + int32_t count = object_reference_count(oid); + + if (count > 0) + { + SWSS_LOG_ERROR("FATAL: removing object oid 0x%llx but reference count is: %d", oid, count); + throw; + } + } + + SWSS_LOG_DEBUG("removing object oid 0x%llx reference", oid); + + ObjectReferences.erase(oid); +} + +// VLAN REFERENCE FUNCTIONS + +bool vlan_reference_exists( + _In_ sai_vlan_id_t vlanid) +{ + SWSS_LOG_ENTER(); + + bool exists = VlanReferences.find(vlanid) != VlanReferences.end(); + + SWSS_LOG_DEBUG("vlan %u refrence: %s", vlanid, exists ? "exists" : "missing"); + + return exists; +} + +void vlan_reference_inc( + _In_ sai_vlan_id_t vlanid) +{ + SWSS_LOG_ENTER(); + + if (!vlan_reference_exists(vlanid)) + { + SWSS_LOG_ERROR("FATAL: vlan vlanid %u not in reference map", vlanid); + throw; + } + + VlanReferences[vlanid]++; + + SWSS_LOG_DEBUG("increased reference on vlan %u to %d", vlanid, VlanReferences[vlanid]); +} + +void vlan_reference_dec( + _In_ sai_vlan_id_t vlanid) +{ + SWSS_LOG_ENTER(); + + if (!vlan_reference_exists(vlanid)) + { + SWSS_LOG_ERROR("FATAL: vlan vlanid %u not in reference map", vlanid); + throw; + } + + VlanReferences[vlanid]--; + + if (VlanReferences[vlanid] < 0) + { + SWSS_LOG_ERROR("FATAL: vlan vlanid %u reference count is negative!", vlanid); + throw; + } + + SWSS_LOG_DEBUG("decreased reference on vlan %u to %d", vlanid, VlanReferences[vlanid]); +} + +void vlan_reference_insert( + _In_ sai_vlan_id_t vlanid) +{ + SWSS_LOG_ENTER(); + + if (vlan_reference_exists(vlanid)) + { + SWSS_LOG_ERROR("FATAL: vlan %u already in reference map", vlanid); + throw; + } + + VlanReferences[vlanid] = 0; + + SWSS_LOG_DEBUG("inserted reference on vlan %u", vlanid); +} + +int32_t vlan_reference_count( + _In_ sai_vlan_id_t vlanid) +{ + SWSS_LOG_ENTER(); + + if (vlan_reference_exists(vlanid)) + { + int32_t count = VlanReferences[vlanid]; + + SWSS_LOG_DEBUG("reference count on vlan %u is %d", vlanid, count); + + return count; + } + + SWSS_LOG_ERROR("FATAL: vlan vlanid 0x%llx reference not in map", vlanid); + throw; +} + +void vlan_reference_remove( + _In_ sai_vlan_id_t vlanid) +{ + SWSS_LOG_ENTER(); + + if (vlan_reference_exists(vlanid)) + { + int32_t count = vlan_reference_count(vlanid); + + if (count > 0) + { + SWSS_LOG_ERROR("FATAL: removing vlan vlanid 0x%llx but reference count is: %d", vlanid, count); + throw; + } + } + + VlanReferences.erase(vlanid); + + SWSS_LOG_DEBUG("removing vlan %u reference", vlanid); +} + +bool object_exists( + _In_ const std::string& key) +{ + SWSS_LOG_ENTER(); + + bool exists = ObjectAttrHash.find(key) != ObjectAttrHash.end(); + + SWSS_LOG_DEBUG("%s %s", key.c_str(), exists ? "exists" : "missing"); + + return exists; +} + +bool object_exists( + _In_ const sai_object_meta_key_t meta_key) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + return object_exists(key); +} + +sai_status_t meta_init_db() +{ + SWSS_LOG_ENTER(); + + meta_init(); + + // we need local db to keep track if + // we are performing "get" or set on + // conditional attribute and whether + // condition is in force + + ObjectReferences.clear(); + VlanReferences.clear(); + ObjectAttrHash.clear(); + AttributeKeys.clear(); + + // init switch + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_SWITCH, .key = { } }; + + std::string switch_key = get_object_meta_key_string(meta_key); + + ObjectAttrHash[switch_key] = { }; + + // init default vlan + + sai_object_meta_key_t meta_key_vlan = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = DEFAULT_VLAN_NUMBER } }; + + std::string vlan_key = get_object_meta_key_string(meta_key_vlan); + + ObjectAttrHash[vlan_key] = { }; + + vlan_reference_insert(DEFAULT_VLAN_NUMBER); + vlan_reference_inc(DEFAULT_VLAN_NUMBER); + + // init traps + + for (auto& trap: enum_sai_hostif_trap_id_t_values) + { + sai_object_meta_key_t meta_key_trap = { .object_type = SAI_OBJECT_TYPE_TRAP, .key = { .trap_id = (sai_hostif_trap_id_t)trap } }; + + std::string trap_key = get_object_meta_key_string(meta_key_trap); + + ObjectAttrHash[trap_key] = { }; + + // not need for now creating trap references since + // in this SAI all traps are created by default + } + + // TODO For object references like virtual router or vlanmembers they can + // be using some other references (like vlan member can use port or vlan so + // there may be existing dependency there and we dont know it so we should + // do actual "get" here and populate them we could use object api to retrve + // all objects and rebuild dependencies basing on metadata. + + // TODO Getting default object id's like TRAP which can contain other + // object id as dependency (in this case queue/policer) we need to also GET + // those attributes at first switch init to have full asic view of what's + // going on and also we need extra logic on remove function (we can add 4 + // pointers in metadata c/r/s/g) because some default object's can't be + // removed like cpu port or default virtual router and probably default + // trap group. + + return SAI_STATUS_SUCCESS; +} + +const sai_attribute_t* get_object_previous_attr( + _In_ const sai_object_meta_key_t meta_key, + _In_ const sai_attr_metadata_t& md) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + auto it = ObjectAttrHash.find(key); + + if (it == ObjectAttrHash.end()) + { + SWSS_LOG_ERROR("object key %s not found", key.c_str()); + + return NULL; + } + + auto ita = it->second.find(md.attrid); + + if (ita == it->second.end()) + { + // attribute id not found + return NULL; + } + + // NOTE: this is actually dangerous since + // we possibly expose memory on attribute + // list that could be already freed + return ita->second->getattr(); +} + +void set_object( + _In_ const sai_object_meta_key_t meta_key, + _In_ const sai_attr_metadata_t& md, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + if (!object_exists(key)) + { + SWSS_LOG_ERROR("FATAL: object %s don't exists", key.c_str()); + throw; + } + + META_LOG_DEBUG(md, "set attribute %d on %s", attr->id, key.c_str()); + + auto p = new SaiAttrWrapper(meta_key.object_type, md.serializationtype, *attr); + + ObjectAttrHash[key][attr->id] = std::shared_ptr(p); +} + +const std::vector> get_object( + _In_ const sai_object_meta_key_t meta_key) +{ + std::string key = get_object_meta_key_string(meta_key); + + if (!object_exists(key)) + { + SWSS_LOG_ERROR("FATAL: object %s don't exists", key.c_str()); + throw; + } + + std::vector> attrs; + + const auto& hash = ObjectAttrHash[key]; + + for (auto it = hash.begin(); it != hash.end(); ++it) + { + attrs.push_back(it->second); + } + + return attrs; +} + +void remove_object( + _In_ const sai_object_meta_key_t meta_key) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + if (!object_exists(key)) + { + SWSS_LOG_ERROR("FATAL: object %s don't exists", key.c_str()); + throw; + } + + SWSS_LOG_DEBUG("removing object %s", key.c_str()); + + ObjectAttrHash.erase(key); +} + +void create_object( + _In_ const sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + if (object_exists(key)) + { + SWSS_LOG_ERROR("FATAL: object %s already exists", key.c_str()); + throw; + } + + SWSS_LOG_DEBUG("creating object %s", key.c_str()); + + ObjectAttrHash[key] = {}; +} + +sai_status_t meta_generic_validation_objlist( + _In_ const sai_attr_metadata_t& md, + _In_ uint32_t count, + _In_ const sai_object_id_t* list) +{ + SWSS_LOG_ENTER(); + + if (count > MAX_LIST_COUNT) + { + META_LOG_ERROR(md, "object list count %u is > then max list count %u", count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (list == NULL) + { + if (count == 0) + { + return SAI_STATUS_SUCCESS; + } + + META_LOG_ERROR(md, "object list is null, but count is %u", count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + std::set oids; + + sai_object_type_t object_type = SAI_OBJECT_TYPE_NULL; + + for (uint32_t i = 0; i < count; ++i) + { + sai_object_id_t oid = list[i]; + + if (oids.find(oid) != oids.end()) + { + META_LOG_ERROR(md, "object on list [%u] oid 0x%llx is duplicated, but not allowed", i, oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + oids.insert(oid); + + if (oid == SAI_NULL_OBJECT_ID) + { + if (md.allownullobjectid) + { + // ok, null object is allowed + continue; + } + + META_LOG_ERROR(md, "object on list [%u] is NULL, but not allowed", i); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t ot = sai_object_type_query(oid); + + if (ot == SAI_NULL_OBJECT_ID) + { + META_LOG_ERROR(md, "object on list [%u] oid 0x%llx is not valid, returned null object id", i, oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (md.allowedobjecttypes.find(ot) == md.allowedobjecttypes.end()) + { + META_LOG_ERROR(md, "object on list [%u] oid 0x%llx object type %d is not allowed on this attribute", i, oid, ot); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (!object_reference_exists(oid)) + { + META_LOG_ERROR(md, "object on list [%u] oid 0x%llx object type %d does not exists in local DB", i, oid, ot); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (i > 1) + { + // currently all objects on list must be the same type + if (object_type != ot) + { + META_LOG_ERROR(md, "object list contain's mixed object types: %d vs %d, not allowed", object_type, ot); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + object_type = ot; + } + + return SAI_STATUS_SUCCESS; +} + +template sai_status_t meta_genetic_validation_list(const sai_attr_metadata_t& md, const T&list) +{ + uint32_t count = list.count; + + if (count > MAX_LIST_COUNT) + { + META_LOG_ERROR(md, "list count %u is > then max list count %u", count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (count == 0 && list.list != NULL) + { + META_LOG_ERROR(md, "when count is zero, list must be NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (list.list == NULL) + { + if (count == 0) + { + return SAI_STATUS_SUCCESS; + } + + META_LOG_ERROR(md, "list is null, but count is %u", count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +#define VALIDATION_LIST(md,list) \ +{\ + auto status = meta_genetic_validation_list(md,list);\ + if (status != SAI_STATUS_SUCCESS)\ + {\ + return status;\ + }\ +} + +std::string construct_key( + _In_ const sai_object_meta_key_t& meta_key, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t* attr_list) +{ + SWSS_LOG_ENTER(); + + // use map to make sure that kays will be always sorded by id + + std::map keys; + + for (uint32_t idx = 0; idx < attr_count; ++idx) + { + const sai_attribute_t* attr = &attr_list[idx]; + + const auto& md = *get_attribute_metadata(meta_key.object_type, attr->id); + + const sai_attribute_value_t& value = attr->value; + + if (!HAS_FLAG_KEY(md.flags)) + { + continue; + } + + std::string name = std::string(get_attr_name(md.objecttype, md.attrid)) + ":"; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_UINT32_LIST: // only for port + + // TODO this list should be sorted + for (uint32_t i = 0; i < value.u32list.count; ++i) + { + name += std::to_string(value.u32list.list[i]); + + if (i != value.u32list.count - 1) + { + name += ","; + } + } + + break; + + case SAI_SERIALIZATION_TYPE_INT32: + name += std::to_string(value.s32); // if enum then get enum name? + break; + + case SAI_SERIALIZATION_TYPE_UINT32: + name += std::to_string(value.u32); + break; + + case SAI_SERIALIZATION_TYPE_UINT8: + name += std::to_string(value.u8); + break; + + default: + META_LOG_ERROR(md, "FATAL: marked as key, but have invalid serialization type"); + throw; + } + + keys[md.attrid] = name; + } + + std::string key; + + for (auto& k: keys) + { + key += k.second + ";"; + } + + SWSS_LOG_DEBUG("constructed key: %s", key.c_str()); + + return key; +} + +sai_status_t meta_generic_validation_create( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + if (attr_count > MAX_LIST_COUNT) + { + SWSS_LOG_ERROR("create attribute count is too large %u > then max list count %u", attr_count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (attr_count > 0 && attr_list == NULL) + { + SWSS_LOG_ERROR("attr count is %u but attribute list pointer is NULL", attr_count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + std::unordered_map attrs; + + SWSS_LOG_DEBUG("attr count = %u", attr_count); + + bool haskeys = false; + + // check each attribute separetly + for (uint32_t idx = 0; idx < attr_count; ++idx) + { + const sai_attribute_t* attr = &attr_list[idx]; + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + if (mdp == NULL) + { + SWSS_LOG_ERROR("unable to find attribute metadata %d:%d", meta_key.object_type, attr->id); + + return SAI_STATUS_FAILURE; + } + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + META_LOG_DEBUG(md, "(create)"); + + if (attrs.find(attr->id) != attrs.end()) + { + META_LOG_ERROR(md, "attribute id (%u) is defined on attr list multiple times", attr->id); + + return SAI_STATUS_INVALID_PARAMETER; + } + + attrs[attr->id] = attr; + + if (HAS_FLAG_READ_ONLY(md.flags)) + { + META_LOG_ERROR(md, "attr is read only and cannot be created"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (HAS_FLAG_KEY(md.flags)) + { + haskeys = true; + META_LOG_DEBUG(md, "attr is key"); + } + + // if we set OID check if exists and if type is correct + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_CHARDATA: + + { + const char* chardata = value.chardata; + + size_t len = strnlen(chardata, HOSTIF_NAME_SIZE); + + if (len == HOSTIF_NAME_SIZE) + { + META_LOG_ERROR(md, "host interface name is too long"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (len == 0) + { + META_LOG_ERROR(md, "host interface name is zero"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + for (size_t i = 0; i < len; ++i) + { + char c = chardata[i]; + + if (c < 0x20 || c > 0x7e) + { + META_LOG_ERROR(md, "interface name contains invalid character 0x%02x", c); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // TODO check whether name is not used by other host interface + break; + } + + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + break; + + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + + { + switch (value.ipaddr.addr_family) + { + case SAI_IP_ADDR_FAMILY_IPV4: + case SAI_IP_ADDR_FAMILY_IPV6: + break; + + default: + + SWSS_LOG_ERROR("invalid address family: %d", value.ipaddr.addr_family); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + + { + sai_status_t status = meta_generic_validation_objlist(md, 1, &value.oid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + + { + sai_status_t status = meta_generic_validation_objlist(md, value.objlist.count, value.objlist.list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + // case SAI_SERIALIZATION_TYPE_VLAN_LIST: + // require test for vlan existence + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + + { + sai_status_t status = meta_generic_validation_objlist(md, 1, &value.aclfield.data.oid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + + { + sai_status_t status = meta_generic_validation_objlist(md, value.aclfield.data.objlist.count, value.aclfield.data.objlist.list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + // ACL ACTION + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + + { + sai_status_t status = meta_generic_validation_objlist(md, 1, &value.aclaction.parameter.oid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + + { + sai_status_t status = meta_generic_validation_objlist(md, value.aclaction.parameter.objlist.count, value.aclaction.parameter.objlist.list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + VALIDATION_LIST(md, value.u8list); + break; + case SAI_SERIALIZATION_TYPE_INT8_LIST: + VALIDATION_LIST(md, value.s8list); + break; + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + VALIDATION_LIST(md, value.u16list); + break; + case SAI_SERIALIZATION_TYPE_INT16_LIST: + VALIDATION_LIST(md, value.s16list); + break; + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + VALIDATION_LIST(md, value.u32list); + break; + case SAI_SERIALIZATION_TYPE_INT32_LIST: + VALIDATION_LIST(md, value.s32list); + break; + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + VALIDATION_LIST(md, value.qosmap); + break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + VALIDATION_LIST(md, value.tunnelmap); + break; + + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + + if (value.u32range.min > value.u32range.max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.u32range.min > value.u32range.max); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + + if (value.s32range.min > value.s32range.max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.s32range.min > value.s32range.max); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + default: + + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + + if (md.isenum()) + { + int32_t val = value.s32; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + val = value.aclfield.data.s32; + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + val = value.aclaction.parameter.s32; + break; + + default: + val = value.s32; + break; + } + + if (md.enumallowedvalues.find(val) == md.enumallowedvalues.end()) + { + META_LOG_ERROR(md, "is enum, but value %d not found on allowed values list", val); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + if (md.isenumlist()) + { + // we allow repeats on enum list + if (value.s32list.count != 0 && value.s32list.list == NULL) + { + META_LOG_ERROR(md, "enum list is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + for (uint32_t i = value.s32list.count; i < value.s32list.count; ++i) + { + int32_t s32 = value.s32list.list[i]; + + if (md.enumallowedvalues.find(s32) == md.enumallowedvalues.end()) + { + META_LOG_ERROR(md, "is enum list, but value %d not found on allowed values list", value.s32); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + } + + if (md.isvlan()) + { + if (!vlan_reference_exists(value.u16)) + { + SWSS_LOG_ERROR("vlan %d is missing", value.u16); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + // conditions are checked later on + } + + // we are creating object, no need for check if exists (only key values needs to be checked) + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_SWITCH: + case SAI_OBJECT_TYPE_ROUTE: + case SAI_OBJECT_TYPE_FDB: + case SAI_OBJECT_TYPE_NEIGHBOR: + case SAI_OBJECT_TYPE_VLAN: + case SAI_OBJECT_TYPE_TRAP: + + { + // just sanity check if object already exists + std::string key = get_object_meta_key_string(meta_key); + + if (object_exists(key)) + { + SWSS_LOG_ERROR("object key %s already exists", key.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + } + + default: + // we are creating OID object, and we don't have it's value yet + break; + } + + const auto& metadata = get_attributes_metadata(meta_key.object_type); + + if (metadata.empty()) + { + SWSS_LOG_ERROR("get attributes metadata returned empty list for object type: %d", meta_key.object_type); + + return SAI_STATUS_FAILURE; + } + + // check if all mandatory attrributes were passed + + for (auto mdp: metadata) + { + const sai_attr_metadata_t& md = *mdp; + + if (!HAS_FLAG_MANDATORY_ON_CREATE(md.flags)) + { + continue; + } + + if (md.isconditional()) + { + // skip conditional attributes for now + continue; + } + + const auto &it = attrs.find(md.attrid); + + if (it == attrs.end()) + { + META_LOG_ERROR(md, "attribute is mandatory but not passed in attr list"); + + return SAI_STATUS_MANDATORY_ATTRIBUTE_MISSING; + } + } + + // check if we need any conditional attributes + for (auto mdp: metadata) + { + const sai_attr_metadata_t& md = *mdp; + + if (!md.isconditional()) + { + continue; + } + + // this is conditional attribute, check if it's required + + bool any = false; + + for (auto& c : md.conditions) + { + // condtions may only be on the same object type + const auto& cmd = *get_attribute_metadata(meta_key.object_type, c.attrid); + + const sai_attribute_value_t* cvalue = &cmd.defaultvalue; + + const sai_attribute_t *cattr = get_attribute_by_id(c.attrid, attr_count, attr_list); + + if (cattr != NULL) + { + META_LOG_DEBUG(md, "condition attr %d was passed, using it's value", c.attrid); + + cvalue = &cattr->value; + } + + if (cmd.serializationtype == SAI_SERIALIZATION_TYPE_BOOL) + { + if (c.condition.booldata == cvalue->booldata) + { + META_LOG_DEBUG(md, "bool condition was met on attr %d = %d", cmd.attrid, c.condition.booldata); + + any = true; + break; + } + } + else // enum condition + { + int32_t val = cvalue->s32; + + switch (cmd.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + val = cvalue->aclfield.data.s32; + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + val = cvalue->aclaction.parameter.s32; + break; + + default: + val = cvalue->s32; + break; + } + + if (c.condition.s32 == val) + { + META_LOG_DEBUG(md, "enum condition was met on attr id %d, val = %d", cmd.attrid, val); + + any = true; + break; + } + } + } + + if (!any) + { + // maybe we can let it go here? + if (attrs.find(md.attrid) != attrs.end()) + { + META_LOG_DEBUG(md, "conditional, but condition was not met, this attribute is not required, but passed"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + continue; + } + + // is required, check if user passed it + const auto &it = attrs.find(md.attrid); + + if (it == attrs.end()) + { + META_LOG_ERROR(md, "attribute is conditional and is mandatory but not passed in attr list"); + + return SAI_STATUS_MANDATORY_ATTRIBUTE_MISSING; + } + } + + if (haskeys) + { + std::string key = construct_key(meta_key, attr_count, attr_list); + + for (auto& it: AttributeKeys) + { + // since we didn't created oid yet, we don't know if attribute key exists, check all + + if (it.second == key) + { + SWSS_LOG_ERROR("attribute key %s already exists, can't create", key.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_generic_validation_remove( + _In_ const sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + if (!object_exists(key)) + { + SWSS_LOG_ERROR("object key %s don't exists", key.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_ROUTE: + case SAI_OBJECT_TYPE_FDB: + case SAI_OBJECT_TYPE_NEIGHBOR: + // we don't keep reference of those since those are leafs + break; + + case SAI_OBJECT_TYPE_SWITCH: + SWSS_LOG_ERROR("remove switch not supported yet FIXME"); + throw; + + case SAI_OBJECT_TYPE_TRAP: + SWSS_LOG_ERROR("remove trap not supported yet FIXME"); + throw; + + case SAI_OBJECT_TYPE_VLAN: + + { + sai_vlan_id_t vlan_id = meta_key.key.vlan_id; + + if (!vlan_reference_exists(vlan_id)) + { + SWSS_LOG_ERROR("vlan %u reference don't exists", vlan_id); + + return SAI_STATUS_INVALID_PARAMETER; + } + + int count = vlan_reference_count(vlan_id); + + if (count != 0) + { + SWSS_LOG_ERROR("vlan %u reference count is %d, can't remove", vlan_id, count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (vlan_id == DEFAULT_VLAN_NUMBER) + { + SWSS_LOG_ERROR("removing vlan number %u is not supported", DEFAULT_VLAN_NUMBER); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // should be safe to remove + + break; + } + + default: + + { + sai_object_id_t oid = meta_key.key.object_id; + + if (oid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("can't remove null object id"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t object_type = sai_object_type_query(oid); + + if (object_type == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("oid 0x%llx is not valid, returned null object id", oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (object_type != meta_key.object_type) + { + SWSS_LOG_ERROR("oid 0x%llx type %d is not accepted, expected object type %d", oid, object_type, meta_key.object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (!object_reference_exists(oid)) + { + SWSS_LOG_ERROR("object 0x%llx reference don't exists", oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + int count = object_reference_count(oid); + + if (count != 0) + { + SWSS_LOG_ERROR("object 0x%llx reference count is %d, can't remove", oid, count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // should be safe to remove + + break; + } + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_generic_validation_set( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + if (attr == NULL) + { + SWSS_LOG_ERROR("attribute pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + if (mdp == NULL) + { + SWSS_LOG_ERROR("unable to find attribute metadata %d:%d", meta_key.object_type, attr->id); + + return SAI_STATUS_FAILURE; + } + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + META_LOG_DEBUG(md, "(set)"); + + if (HAS_FLAG_READ_ONLY(md.flags)) + { + META_LOG_ERROR(md, "attr is read only and cannot be modified"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (HAS_FLAG_CREATE_ONLY(md.flags)) + { + META_LOG_ERROR(md, "attr is create only and cannot be modified"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (HAS_FLAG_KEY(md.flags)) + { + META_LOG_ERROR(md, "attr is key and cannot be modified"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // if we set OID check if exists and if type is correct + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + // case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + + { + switch (value.ipaddr.addr_family) + { + case SAI_IP_ADDR_FAMILY_IPV4: + case SAI_IP_ADDR_FAMILY_IPV6: + break; + + default: + + SWSS_LOG_ERROR("invalid address family: %d", value.ipaddr.addr_family); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + + { + sai_status_t status = meta_generic_validation_objlist(md, 1, &value.oid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + + { + sai_status_t status = meta_generic_validation_objlist(md, value.objlist.count, value.objlist.list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + // case SAI_SERIALIZATION_TYPE_VLAN_LIST: + // will require test vlan existence + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + + { + sai_status_t status = meta_generic_validation_objlist(md, 1, &value.aclfield.data.oid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + + { + sai_status_t status = meta_generic_validation_objlist(md, value.aclfield.data.objlist.count, value.aclfield.data.objlist.list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + // ACL ACTION + // + // NOTE: when we are going to disable action parameter is not + // needed (we don't need to validate it) also same object can be + // enabled/disabled without changing oid? this makes things + // complicated + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + + { + sai_status_t status = meta_generic_validation_objlist(md, 1, &value.aclaction.parameter.oid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + + { + sai_status_t status = meta_generic_validation_objlist(md, value.aclaction.parameter.objlist.count, value.aclaction.parameter.objlist.list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + break; + } + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + VALIDATION_LIST(md, value.u8list); + break; + case SAI_SERIALIZATION_TYPE_INT8_LIST: + VALIDATION_LIST(md, value.s8list); + break; + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + VALIDATION_LIST(md, value.u16list); + break; + case SAI_SERIALIZATION_TYPE_INT16_LIST: + VALIDATION_LIST(md, value.s16list); + break; + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + VALIDATION_LIST(md, value.u32list); + break; + case SAI_SERIALIZATION_TYPE_INT32_LIST: + VALIDATION_LIST(md, value.s32list); + break; + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + VALIDATION_LIST(md, value.qosmap); + break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + VALIDATION_LIST(md, value.tunnelmap); + break; + + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + + if (value.u32range.min > value.u32range.max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.u32range.min > value.u32range.max); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + + if (value.s32range.min > value.s32range.max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.s32range.min > value.s32range.max); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + default: + + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + + if (md.isenum()) + { + int32_t val = value.s32; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + val = value.aclfield.data.s32; + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + val = value.aclaction.parameter.s32; + break; + + default: + val = value.s32; + break; + } + + if (md.enumallowedvalues.find(val) == md.enumallowedvalues.end()) + { + META_LOG_ERROR(md, "is enum, but value %d not found on allowed values list", val); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + if (md.isenumlist()) + { + // we allow repeats on enum list + if (value.s32list.count != 0 && value.s32list.list == NULL) + { + META_LOG_ERROR(md, "enum list is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + for (uint32_t i = value.s32list.count; i < value.s32list.count; ++i) + { + int32_t s32 = value.s32list.list[i]; + + if (md.enumallowedvalues.find(s32) == md.enumallowedvalues.end()) + { + SWSS_LOG_ERROR("is enum list, but value %d not found on allowed values list", value.s32); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + } + + if (md.isvlan()) + { + if (!vlan_reference_exists(value.u16)) + { + SWSS_LOG_ERROR("vlan %d is missing", value.u16); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + if (md.isconditional()) + { + // check if it was set on local DB + // (this will not respect create_only with default) + if (get_object_previous_attr(meta_key, md) == NULL) + { + META_LOG_ERROR(md, "set for conditional, but not found in local db"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + META_LOG_DEBUG(md, "conditional attr found in local db"); + } + + // check if object on which we perform operation exists + + std::string key = get_object_meta_key_string(meta_key); + + if (!object_exists(key)) + { + META_LOG_ERROR(md, "object key %s don't exists", key.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // object exists in DB so we can do "set" operation + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_SWITCH: + case SAI_OBJECT_TYPE_ROUTE: + case SAI_OBJECT_TYPE_FDB: + case SAI_OBJECT_TYPE_NEIGHBOR: + case SAI_OBJECT_TYPE_VLAN: + case SAI_OBJECT_TYPE_TRAP: + + SWSS_LOG_DEBUG("object key exists: %s", key.c_str()); + break; + + default: + + { + // check if object we are calling SET is the same object type + // as the type of SET function + + sai_object_id_t oid = meta_key.key.object_id; + + sai_object_type_t object_type = sai_object_type_query(oid); + + if (object_type == SAI_NULL_OBJECT_ID) + { + META_LOG_ERROR(md, "oid 0x%llx is not valid, returned null object id", oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (object_type != meta_key.object_type) + { + META_LOG_ERROR(md, "oid 0x%llx type %d is not accepted, expected object type %d", oid, object_type, meta_key.object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + break; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_generic_validation_get( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + if (attr_count < 1) + { + SWSS_LOG_ERROR("expected at least 1 attribute when calling get, zero given"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (attr_count > MAX_LIST_COUNT) + { + SWSS_LOG_ERROR("get attribute count is too large %u > then max list count %u", attr_count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (attr_list == NULL) + { + SWSS_LOG_ERROR("attribute list pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + SWSS_LOG_DEBUG("attr count = %u", attr_count); + + for (uint32_t i = 0; i < attr_count; ++i) + { + const sai_attribute_t* attr = &attr_list[i]; + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + if (mdp == NULL) + { + SWSS_LOG_ERROR("unable to find attribute metadata %d:%d", meta_key.object_type, attr->id); + + return SAI_STATUS_FAILURE; + } + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + META_LOG_DEBUG(md, "(get)"); + + if (md.isconditional()) + { + // check if it was set on local DB + // (this will not respect create_only with default) + if (get_object_previous_attr(meta_key, md) == NULL) + { + META_LOG_ERROR(md, "request for conditional, but not found in local db"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + META_LOG_DEBUG(md, "conditional attr found in local db"); + } + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + + // allow NULL list if count is zero (just get list length) + + if (value.objlist.count != 0 && value.objlist.list == NULL) + { + META_LOG_ERROR(md, "object list count is %u, but list is NULL", value.objlist.count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (value.objlist.count > MAX_LIST_COUNT) + { + META_LOG_ERROR(md, "object list count %u is > then max list count %u", value.objlist.count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + case SAI_SERIALIZATION_TYPE_VLAN_LIST: + + { + if (value.vlanlist.count != 0 && value.vlanlist.list == NULL) + { + META_LOG_ERROR(md, "vlan list count is %u, but list is NULL", value.vlanlist.count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (value.vlanlist.count > MAXIMUM_VLAN_NUMBER) + { + META_LOG_ERROR(md, "vlan count is too big %u > %u", value.vlanlist.count, MAXIMUM_VLAN_NUMBER); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + } + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + + { + // allow NULL list if count is zero (just get list length) + + if (value.aclfield.data.objlist.count != 0 && value.aclfield.data.objlist.list == NULL) + { + META_LOG_ERROR(md, "object list count is %u, but list is NULL", value.aclfield.data.objlist.count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (value.aclfield.data.objlist.count > MAX_LIST_COUNT) + { + META_LOG_ERROR(md, "object list count %u is > then max list count %u", value.aclfield.data.objlist.count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + } + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + // ACL ACTION + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + + { + // allow NULL list if count is zero (just get list length) + + if (value.aclaction.parameter.objlist.count != 0 && value.aclaction.parameter.objlist.list == NULL) + { + META_LOG_ERROR(md, "object list count is %u, but list is NULL", value.aclaction.parameter.objlist.count); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (value.aclaction.parameter.objlist.count > MAX_LIST_COUNT) + { + META_LOG_ERROR(md, "object list count %u is > then max list count %u", value.aclaction.parameter.objlist.count, MAX_LIST_COUNT); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + } + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + VALIDATION_LIST(md, value.u8list); + break; + case SAI_SERIALIZATION_TYPE_INT8_LIST: + VALIDATION_LIST(md, value.s8list); + break; + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + VALIDATION_LIST(md, value.u16list); + break; + case SAI_SERIALIZATION_TYPE_INT16_LIST: + VALIDATION_LIST(md, value.s16list); + break; + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + VALIDATION_LIST(md, value.u32list); + break; + case SAI_SERIALIZATION_TYPE_INT32_LIST: + VALIDATION_LIST(md, value.s32list); + break; + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + VALIDATION_LIST(md, value.qosmap); + break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + VALIDATION_LIST(md, value.tunnelmap); + break; + + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + // primitives + break; + + default: + + // acl capability will is more complex since is in/out we need to check stage + + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + } + + std::string key = get_object_meta_key_string(meta_key); + + if (!object_exists(key)) + { + SWSS_LOG_ERROR("object key %s don't exists", key.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_SWITCH: + case SAI_OBJECT_TYPE_ROUTE: + case SAI_OBJECT_TYPE_FDB: + case SAI_OBJECT_TYPE_NEIGHBOR: + case SAI_OBJECT_TYPE_VLAN: + case SAI_OBJECT_TYPE_TRAP: + + SWSS_LOG_DEBUG("object key exists: %s", key.c_str()); + + break; + + default: + + { + // check if object we are calling GET is the same object type + // as the type of GET function + + sai_object_id_t oid = meta_key.key.object_id; + + sai_object_type_t object_type = sai_object_type_query(oid); + + if (object_type == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("oid 0x%llx is not valid, returned null object id", oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (object_type != meta_key.object_type) + { + SWSS_LOG_ERROR("oid 0x%llx type %d is not accepted, expected object type %d", oid, object_type, meta_key.object_type); + + return SAI_STATUS_INVALID_PARAMETER; + } + } + + break; + } + + // object exists in DB so we can do "get" operation + + return SAI_STATUS_SUCCESS; +} + +void meta_generic_validation_post_create( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + std::string key = get_object_meta_key_string(meta_key); + + if (object_exists(key)) + { + SWSS_LOG_ERROR("object key %s already exists (vendor bug?)", key.c_str()); + + // this may produce inconsistency + } + + create_object(meta_key); + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_ROUTE: + object_reference_inc(meta_key.key.route_entry.vr_id); + break; + + case SAI_OBJECT_TYPE_NEIGHBOR: + object_reference_inc(meta_key.key.neighbor_entry.rif_id); + break; + + case SAI_OBJECT_TYPE_FDB: + vlan_reference_inc(meta_key.key.fdb_entry.vlan_id); + break; + + case SAI_OBJECT_TYPE_VLAN: + vlan_reference_insert(meta_key.key.vlan_id); + break; + + case SAI_OBJECT_TYPE_SWITCH: + case SAI_OBJECT_TYPE_TRAP: + SWSS_LOG_ERROR("object not supported FIXME"); + throw; + + default: + + { + // check if object created was expected type + // as the type of SET function + + sai_object_id_t oid = meta_key.key.object_id; + + if (oid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("created oid is null object id (vendor bug?)"); + break; + } + + sai_object_type_t object_type = sai_object_type_query(oid); + + if (object_type == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("created oid 0x%llx is not valid object type after create, returned null object id (vendor bug?)", oid); + break; + } + + if (object_type != meta_key.object_type) + { + SWSS_LOG_ERROR("created oid 0x%llx type %d is wrond type, expected object type %d (vendor bug?)", oid, object_type, meta_key.object_type); + break; + } + + object_reference_insert(oid); + + break; + } + } + + bool haskeys; + + for (uint32_t idx = 0; idx < attr_count; ++idx) + { + const sai_attribute_t* attr = &attr_list[idx]; + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + if (HAS_FLAG_KEY(md.flags)) + { + haskeys = true; + META_LOG_DEBUG(md, "attr is key"); + } + + // increase reference on object id types + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + object_reference_inc(value.oid); + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + object_reference_inc(value.objlist); + break; + + case SAI_SERIALIZATION_TYPE_VLAN_LIST: + break; + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + object_reference_inc(value.aclfield.data.oid); + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + object_reference_inc(value.aclfield.data.objlist); + break; + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + // ACL ACTION + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + object_reference_inc(value.aclaction.parameter.oid); + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + object_reference_inc(value.aclaction.parameter.objlist); + break; + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + case SAI_SERIALIZATION_TYPE_INT8_LIST: + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + case SAI_SERIALIZATION_TYPE_INT16_LIST: + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + case SAI_SERIALIZATION_TYPE_INT32_LIST: + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + // no special action required + break; + + default: + + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + + if (md.isvlan()) + { + vlan_reference_inc(value.u16); + } + + set_object(meta_key, md, attr); + } + + if (haskeys) + { + std::string ok = get_object_meta_key_string(meta_key); + + AttributeKeys[ok] = construct_key(meta_key, attr_count, attr_list); + } +} + +void meta_generic_validation_post_remove( + _In_ const sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); + + // get all attributes that was set + + for (auto&it: get_object(meta_key)) + { + const sai_attribute_t* attr = it->getattr(); + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + // decrease reference on object id types + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + // primitives, ok + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + object_reference_dec(value.oid); + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + object_reference_dec(value.objlist); + break; + + //case SAI_SERIALIZATION_TYPE_VLAN_LIST: + // will require dec vlan references + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + object_reference_dec(value.aclfield.data.oid); + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + object_reference_dec(value.aclfield.data.objlist); + break; + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + // ACL ACTION + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + object_reference_dec(value.aclaction.parameter.oid); + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + object_reference_dec(value.aclaction.parameter.objlist); + break; + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + case SAI_SERIALIZATION_TYPE_INT8_LIST: + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + case SAI_SERIALIZATION_TYPE_INT16_LIST: + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + case SAI_SERIALIZATION_TYPE_INT32_LIST: + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + // no special action required + break; + + default: + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + + if (md.isvlan()) + { + vlan_reference_dec(value.u16); + } + } + + // we don't keep track of fdb, neighbor, route since + // those are safe to remove any time (leafs) + + switch (meta_key.object_type) + { + case SAI_OBJECT_TYPE_SWITCH: + SWSS_LOG_ERROR("remove switch not supported yet FIXME"); + throw; + + case SAI_OBJECT_TYPE_ROUTE: + object_reference_dec(meta_key.key.route_entry.vr_id); + break; + + case SAI_OBJECT_TYPE_NEIGHBOR: + object_reference_dec(meta_key.key.neighbor_entry.rif_id); + break; + + case SAI_OBJECT_TYPE_FDB: + vlan_reference_dec(meta_key.key.fdb_entry.vlan_id); + break; + + case SAI_OBJECT_TYPE_TRAP: + SWSS_LOG_ERROR("trap remove not supported yet FIXME"); + throw; + + case SAI_OBJECT_TYPE_VLAN: + vlan_reference_remove(meta_key.key.vlan_id); + break; + + default: + object_reference_remove(meta_key.key.object_id); + break; + } + + remove_object(meta_key); + + std::string ok = get_object_meta_key_string(meta_key); + + if (AttributeKeys.find(ok) != AttributeKeys.end()) + { + SWSS_LOG_DEBUG("erasing attributes key %s", AttributeKeys[ok].c_str()); + + AttributeKeys.erase(ok); + } +} + +void meta_generic_validation_post_set( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + // primitives, ok + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + object_reference_dec(previous_attr->value.oid); + } + + object_reference_inc(value.oid); + + break; + } + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + object_reference_dec(previous_attr->value.objlist); + } + + object_reference_inc(value.objlist); + + break; + } + + // case SAI_SERIALIZATION_TYPE_VLAN_LIST: + // will require increase vlan references + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + object_reference_dec(previous_attr->value.aclfield.data.oid); + } + + object_reference_inc(value.aclfield.data.oid); + + break; + } + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + object_reference_dec(previous_attr->value.aclfield.data.objlist); + } + + object_reference_inc(value.aclfield.data.objlist); + + break; + } + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + // ACL ACTION + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + object_reference_dec(previous_attr->value.aclaction.parameter.oid); + } + + object_reference_inc(value.aclaction.parameter.oid); + break; + } + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + object_reference_dec(previous_attr->value.aclaction.parameter.objlist); + } + + object_reference_inc(value.aclaction.parameter.objlist); + + break; + } + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + case SAI_SERIALIZATION_TYPE_INT8_LIST: + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + case SAI_SERIALIZATION_TYPE_INT16_LIST: + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + case SAI_SERIALIZATION_TYPE_INT32_LIST: + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + // no special action required + break; + + default: + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + + if (md.isvlan()) + { + const sai_attribute_t *previous_attr = get_object_previous_attr(meta_key, md); + + if (previous_attr != NULL) + { + // decrease previous if it was set + vlan_reference_dec(previous_attr->value.u16); + } + + vlan_reference_inc(value.u16); + } + + // only on create we need to increase entry object types members + // save actual attributes and values to local db + + set_object(meta_key, md, attr); +} + +void meta_generic_validation_post_get_objlist( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const sai_attr_metadata_t& md, + _In_ uint32_t count, + _In_ const sai_object_id_t* list) +{ + SWSS_LOG_ENTER(); + + if (count > MAX_LIST_COUNT) + { + META_LOG_ERROR(md, "returned get object list count %u is > then max list count %u", count, MAX_LIST_COUNT); + } + + if (list == NULL) + { + // query was for length + return; + } + + std::set oids; + + for (uint32_t i = 0; i < count; ++i) + { + sai_object_id_t oid = list[i]; + + if (oids.find(oid) != oids.end()) + { + META_LOG_ERROR(md, "returned get object on list [%u] is duplicated, but not allowed", i); + continue; + } + + oids.insert(oid); + + if (oid == SAI_NULL_OBJECT_ID) + { + if (md.allownullobjectid) + { + // ok, null object is allowed + continue; + } + + META_LOG_ERROR(md, "returned get object on list [%u] is NULL, but not allowed", i); + continue; + } + + sai_object_type_t ot = sai_object_type_query(oid); + + if (ot == SAI_NULL_OBJECT_ID) + { + META_LOG_ERROR(md, "returned get object on list [%u] oid 0x%llx is not valid, returned null object id", i, oid); + continue; + } + + if (md.allowedobjecttypes.find(ot) == md.allowedobjecttypes.end()) + { + META_LOG_ERROR(md, "returned get object on list [%u] oid 0x%llx object type %d is not allowed on this attribute", i, oid, ot); + } + + if (!object_reference_exists(oid)) + { + META_LOG_NOTICE(md, "returned get object on list [%u] oid 0x%llx object type %d does not exists in local DB (snoop)", i, oid, ot); + + sai_object_meta_key_t key = { .object_type = ot, .key = { .object_id = oid } }; + + object_reference_insert(oid); + + if (!object_exists(key)) + { + create_object(key); + } + } + } +} + +#define VALIDATION_LIST_GET(md, list) \ +{\ + if (list.count > MAX_LIST_COUNT)\ + {\ + META_LOG_ERROR(md, "list count %u is > then max list count %u", list.count, MAX_LIST_COUNT);\ + }\ +} + +void meta_generic_validation_post_get( + _In_ const sai_object_meta_key_t& meta_key, + _In_ const uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + for (uint32_t idx = 0; idx < attr_count; ++idx) + { + const sai_attribute_t* attr = &attr_list[idx]; + + auto mdp = get_attribute_metadata(meta_key.object_type, attr->id); + + const sai_attribute_value_t& value = attr->value; + + const sai_attr_metadata_t& md = *mdp; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_INT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_INT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP4: + case SAI_SERIALIZATION_TYPE_IP6: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + // primitives, ok + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + meta_generic_validation_post_get_objlist(meta_key, md, 1, &value.oid); + break; + + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + meta_generic_validation_post_get_objlist(meta_key, md, value.objlist.count, value.objlist.list); + break; + + case SAI_SERIALIZATION_TYPE_VLAN_LIST: + + { + uint32_t count = value.vlanlist.count; + + if (count > MAXIMUM_VLAN_NUMBER) + { + META_LOG_ERROR(md, "too many vlans returned on vlan list (vendor bug?)"); + } + + if (value.vlanlist.list == NULL) + { + break; + } + + for (uint32_t i = 0; i < count; ++i) + { + sai_vlan_id_t vlan_id = value.vlanlist.list[i]; + + sai_object_meta_key_t meta_key_vlan = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + std::string key_vlan = get_object_meta_key_string(meta_key_vlan); + + if (object_exists(key_vlan)) + { + continue; + } + + META_LOG_ERROR(md, "vlan id %d not exists, but returned on list [%u] (snoop?)", vlan_id, i); + } + + break; + } + + // ACL FIELD + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + meta_generic_validation_post_get_objlist(meta_key, md, 1, &value.aclfield.data.oid); + break; + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + meta_generic_validation_post_get_objlist(meta_key, md, value.aclfield.data.objlist.count, value.aclfield.data.objlist.list); + break; + + // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: (2 lists) + + // ACL ACTION + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + // primitives + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + meta_generic_validation_post_get_objlist(meta_key, md, 1, &value.aclaction.parameter.oid); + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + meta_generic_validation_post_get_objlist(meta_key, md, value.aclaction.parameter.objlist.count, value.aclaction.parameter.objlist.list); + break; + + // ACL END + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + VALIDATION_LIST_GET(md, value.u8list); + break; + case SAI_SERIALIZATION_TYPE_INT8_LIST: + VALIDATION_LIST_GET(md, value.s8list); + break; + case SAI_SERIALIZATION_TYPE_UINT16_LIST: + VALIDATION_LIST_GET(md, value.u16list); + break; + case SAI_SERIALIZATION_TYPE_INT16_LIST: + VALIDATION_LIST_GET(md, value.s16list); + break; + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + VALIDATION_LIST_GET(md, value.u32list); + break; + case SAI_SERIALIZATION_TYPE_INT32_LIST: + VALIDATION_LIST_GET(md, value.s32list); + break; + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + VALIDATION_LIST_GET(md, value.qosmap); + break; + case SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST: + VALIDATION_LIST_GET(md, value.tunnelmap); + break; + + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + + if (value.u32range.min > value.u32range.max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.u32range.min > value.u32range.max); + } + + break; + + case SAI_SERIALIZATION_TYPE_INT32_RANGE: + + if (value.s32range.min > value.s32range.max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.s32range.min > value.s32range.max); + } + + break; + + default: + + META_LOG_ERROR(md, "serialization type is not supported yet FIXME"); + throw; + } + + if (md.isenum()) + { + int32_t val = value.s32; + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + val = value.aclfield.data.s32; + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + val = value.aclaction.parameter.s32; + break; + + default: + val = value.s32; + break; + } + + if (md.enumallowedvalues.find(val) == md.enumallowedvalues.end()) + { + META_LOG_ERROR(md, "is enum, but value %d not found on allowed values list", val); + continue; + } + } + + if (md.isenumlist()) + { + if (value.s32list.list == NULL) + { + continue; + } + + for (uint32_t i = value.s32list.count; i < value.s32list.count; ++i) + { + int32_t s32 = value.s32list.list[i]; + + if (md.enumallowedvalues.find(s32) == md.enumallowedvalues.end()) + { + META_LOG_ERROR(md, "is enum list, but value %d not found on allowed values list", value.s32); + } + } + } + + if (md.isvlan()) + { + if (value.u16 < MINIMUM_VLAN_NUMBER || value.u16 > MAXIMUM_VLAN_NUMBER) + { + META_LOG_ERROR(md, "get returned invalid vlan %d", value.u16); + } + } + } +} + +// SWITCH + +sai_status_t meta_sai_set_switch( + _In_ const sai_attribute_t *attr, + _In_ sai_set_switch_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status; + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_SWITCH, .key = { } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + //status = meta_pre_set_switch(attr); + + //if (status != SAI_STATUS_SUCCESS) + //{ + // return status; + //} + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_switch( + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_switch_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status; + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_SWITCH, .key = { } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} + +// FDB ENTRY + +sai_status_t meta_sai_validate_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ bool create) +{ + SWSS_LOG_ENTER(); + + if (fdb_entry == NULL) + { + SWSS_LOG_ERROR("fdb_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_vlan_id_t vlan_id = fdb_entry->vlan_id; + + if (vlan_id < MINIMUM_VLAN_NUMBER || vlan_id > MAXIMUM_VLAN_NUMBER) + { + SWSS_LOG_ERROR("invalid vlan number %d expected <%d..%d>", vlan_id, MINIMUM_VLAN_NUMBER, MAXIMUM_VLAN_NUMBER); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check if vlan exists + + sai_object_meta_key_t meta_key_vlan = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + std::string key_vlan = get_object_meta_key_string(meta_key_vlan); + + if (!object_exists(key_vlan)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_vlan.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check if fdb entry exists + + sai_object_meta_key_t meta_key_fdb = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = *fdb_entry } }; + + std::string key_fdb = get_object_meta_key_string(meta_key_fdb); + + if (create) + { + if (object_exists(key_fdb)) + { + SWSS_LOG_ERROR("object key %s already exists", key_fdb.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + + if (!object_exists(key_fdb)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_fdb.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // fdb entry is valid + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_sai_create_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_fdb_entry_fn create) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, true); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = *fdb_entry } }; + + status = meta_generic_validation_create(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (create == NULL) + { + SWSS_LOG_ERROR("create function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = create(fdb_entry, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("create status: %d", status); + } + else + { + SWSS_LOG_ERROR("create status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_create(meta_key, attr_count, attr_list); + } + + return status; +} + +sai_status_t meta_sai_remove_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ sai_remove_fdb_entry_fn remove) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = *fdb_entry } }; + + status = meta_generic_validation_remove(meta_key); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (remove == NULL) + { + SWSS_LOG_ERROR("remove function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = remove(fdb_entry); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("remove status: %d", status); + } + else + { + SWSS_LOG_ERROR("remove status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_remove(meta_key); + } + + return status; +} + +sai_status_t meta_sai_set_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ const sai_attribute_t *attr, + _In_ sai_set_fdb_entry_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = *fdb_entry } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(fdb_entry, attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_fdb_entry_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = *fdb_entry } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(fdb_entry, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} + +// NEIGHBOR ENTRY + +sai_status_t meta_sai_validate_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ bool create) +{ + SWSS_LOG_ENTER(); + + if (neighbor_entry == NULL) + { + SWSS_LOG_ERROR("neighbor_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + switch (neighbor_entry->ip_address.addr_family) + { + case SAI_IP_ADDR_FAMILY_IPV4: + case SAI_IP_ADDR_FAMILY_IPV6: + break; + + default: + + SWSS_LOG_ERROR("invalid address family: %d", neighbor_entry->ip_address.addr_family); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_id_t rif = neighbor_entry->rif_id; + + if (rif == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("router interface is set to null object id"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t object_type = sai_object_type_query(rif); + + if (object_type == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("router interface oid 0x%llx is not valid object type, returned null object id", rif); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t expected = SAI_OBJECT_TYPE_ROUTER_INTERFACE; + + if (object_type != expected) + { + SWSS_LOG_ERROR("router interface oid 0x%llx type %d is wrond type, expected object type %d", rif, object_type, expected); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check if router interface exists + + sai_object_meta_key_t meta_key_rif = { .object_type = expected, .key = { .object_id = rif } }; + + std::string key_rif = get_object_meta_key_string(meta_key_rif); + + if (!object_exists(key_rif)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_rif.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_neighbor = { .object_type = SAI_OBJECT_TYPE_NEIGHBOR, .key = { .neighbor_entry = *neighbor_entry } }; + + std::string key_neighbor = get_object_meta_key_string(meta_key_neighbor); + + if (create) + { + if (object_exists(key_neighbor)) + { + SWSS_LOG_ERROR("object key %s already exists", key_neighbor.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + + if (!object_exists(key_neighbor)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_neighbor.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // neighbor entry is valid + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_sai_create_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_neighbor_entry_fn create) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, true); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_NEIGHBOR, .key = { .neighbor_entry = *neighbor_entry } }; + + status = meta_generic_validation_create(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (create == NULL) + { + SWSS_LOG_ERROR("create function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = create(neighbor_entry, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("create status: %d", status); + } + else + { + SWSS_LOG_ERROR("create status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_create(meta_key, attr_count, attr_list); + } + + return status; +} + +sai_status_t meta_sai_remove_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ sai_remove_neighbor_entry_fn remove) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_NEIGHBOR, .key = { .neighbor_entry = *neighbor_entry } }; + + status = meta_generic_validation_remove(meta_key); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (remove == NULL) + { + SWSS_LOG_ERROR("remove function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = remove(neighbor_entry); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("remove status: %d", status); + } + else + { + SWSS_LOG_ERROR("remove status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_remove(meta_key); + } + + return status; +} + +sai_status_t meta_sai_set_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ const sai_attribute_t *attr, + _In_ sai_set_neighbor_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_NEIGHBOR, .key = { .neighbor_entry = *neighbor_entry } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(neighbor_entry, attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_neighbor_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_NEIGHBOR, .key = { .neighbor_entry = *neighbor_entry } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(neighbor_entry, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} + +// VLAN + +sai_status_t meta_sai_validate_vlan_id( + _In_ sai_vlan_id_t vlan_id, + _In_ bool create) +{ + SWSS_LOG_ENTER(); + + if (vlan_id < MINIMUM_VLAN_NUMBER || vlan_id > MAXIMUM_VLAN_NUMBER) + { + SWSS_LOG_ERROR("invalid vlan number %d", vlan_id); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_vlan = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + std::string key_vlan = get_object_meta_key_string(meta_key_vlan); + + if (create) + { + if (object_exists(key_vlan)) + { + SWSS_LOG_ERROR("object key %s already exists", key_vlan.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; + } + + if (!object_exists(key_vlan)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_vlan.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_sai_create_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ sai_create_vlan_fn create) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_vlan_id(vlan_id, true); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + status = meta_generic_validation_create(meta_key, 0, NULL); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (create == NULL) + { + SWSS_LOG_ERROR("create function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = create(vlan_id); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("create status: %d", status); + } + else + { + SWSS_LOG_ERROR("create status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_create(meta_key, 0, NULL); + } + + return status; +} + +sai_status_t meta_sai_remove_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ sai_remove_vlan_fn remove) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_vlan_id(vlan_id, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (vlan_id == DEFAULT_VLAN_NUMBER) + { + SWSS_LOG_ERROR("default vlan %d can't be removed", vlan_id); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + status = meta_generic_validation_remove(meta_key); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (remove == NULL) + { + SWSS_LOG_ERROR("remove function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = remove(vlan_id); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("remove status: %d", status); + } + else + { + SWSS_LOG_ERROR("remove status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_remove(meta_key); + } + + return status; +} + +sai_status_t meta_sai_set_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr, + _In_ sai_set_vlan_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_vlan_id(vlan_id, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(vlan_id, attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_vlan_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_vlan_id(vlan_id, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_VLAN, .key = { .vlan_id = vlan_id } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(vlan_id, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} + +// ROUTE ENTRY + +sai_status_t meta_sai_validate_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ bool create) +{ + SWSS_LOG_ENTER(); + + if (unicast_route_entry == NULL) + { + SWSS_LOG_ERROR("unicast_route_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + auto family = unicast_route_entry->destination.addr_family; + + switch (family) + { + case SAI_IP_ADDR_FAMILY_IPV4: + break; + + case SAI_IP_ADDR_FAMILY_IPV6: + + if (!is_ipv6_mask_valid(unicast_route_entry->destination.mask.ip6)) + { + SWSS_LOG_ERROR("invalid ipv6 mask: %s", ip_addr_to_string(family, unicast_route_entry->destination.mask.ip6).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + break; + + default: + + SWSS_LOG_ERROR("invalid prefix family: %d", family); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_id_t vr = unicast_route_entry->vr_id; + + if (vr == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("virtual router is set to null object id"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t object_type = sai_object_type_query(vr); + + if (object_type == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("virtual router oid 0x%llx is not valid object type, returned null object id", vr); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t expected = SAI_OBJECT_TYPE_VIRTUAL_ROUTER; + + if (object_type != expected) + { + SWSS_LOG_ERROR("virtual router oid 0x%llx type %d is wrond type, expected object type %d", vr, object_type, expected); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check if virtual router exists + + sai_object_meta_key_t meta_key_vr = { .object_type = expected, .key = { .object_id = vr } }; + + std::string key_vr = get_object_meta_key_string(meta_key_vr); + + if (!object_exists(key_vr)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_vr.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check if route entry exists + + sai_object_meta_key_t meta_key_route = { .object_type = SAI_OBJECT_TYPE_ROUTE, .key = { .route_entry = *unicast_route_entry } }; + + std::string key_route = get_object_meta_key_string(meta_key_route); + + if (create) + { + if (object_exists(key_route)) + { + SWSS_LOG_ERROR("object key %s already exists", key_route.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + + if (!object_exists(key_route)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_route.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_sai_create_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_route_fn create) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_route_entry(unicast_route_entry, true); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_ROUTE, .key = { .route_entry = *unicast_route_entry } }; + + status = meta_generic_validation_create(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (create == NULL) + { + SWSS_LOG_ERROR("create function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = create(unicast_route_entry, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("create status: %d", status); + } + else + { + SWSS_LOG_ERROR("create status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_create(meta_key, attr_count, attr_list); + } + + return status; +} + +sai_status_t meta_sai_remove_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ sai_remove_route_fn remove) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_route_entry(unicast_route_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_ROUTE, .key = { .route_entry = *unicast_route_entry } }; + + status = meta_generic_validation_remove(meta_key); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (remove == NULL) + { + SWSS_LOG_ERROR("remove function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = remove(unicast_route_entry); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("remove status: %d", status); + } + else + { + SWSS_LOG_ERROR("remove status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_remove(meta_key); + } + + return status; +} + +sai_status_t meta_sai_set_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ const sai_attribute_t *attr, + _In_ sai_set_route_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_route_entry(unicast_route_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_ROUTE, .key = { .route_entry = *unicast_route_entry } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(unicast_route_entry, attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_route_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_route_entry(unicast_route_entry, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_ROUTE, .key = { .route_entry = *unicast_route_entry } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(unicast_route_entry, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} + +// TRAP + +sai_status_t meta_sai_validate_trap( + _In_ sai_hostif_trap_id_t hostif_trapid) +{ + SWSS_LOG_ENTER(); + + if (enum_sai_hostif_trap_id_t_values.find(hostif_trapid) == enum_sai_hostif_trap_id_t_values.end()) + { + SWSS_LOG_ERROR("trap id %d not found on allowed trap id values list", hostif_trapid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_sai_set_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr, + _In_ sai_set_hostif_trap_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_trap(hostif_trapid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_TRAP, .key = { .trap_id = hostif_trapid } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(hostif_trapid, attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_hostif_trap_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_trap(hostif_trapid); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = SAI_OBJECT_TYPE_TRAP, .key = { .trap_id = hostif_trapid } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(hostif_trapid, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} + +// GENERIC + +sai_status_t meta_sai_validate_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t* object_id, + _In_ bool create) +{ + SWSS_LOG_ENTER(); + + if (object_type <= SAI_OBJECT_TYPE_NULL || + object_type >= SAI_OBJECT_TYPE_MAX) + { + SWSS_LOG_ERROR("invalid object type specified: %d, FIXME", object_type); + throw; + } + + const char* otname = get_object_type_name(object_type); + + switch (object_type) + { + case SAI_OBJECT_TYPE_SWITCH: + case SAI_OBJECT_TYPE_FDB: + case SAI_OBJECT_TYPE_ROUTE: + case SAI_OBJECT_TYPE_NEIGHBOR: + case SAI_OBJECT_TYPE_VLAN: + case SAI_OBJECT_TYPE_TRAP: + + SWSS_LOG_ERROR("invalid object type (%s) specified as generic, FIXME", otname); + throw; + + default: + break; + } + + SWSS_LOG_DEBUG("generic object type: %s", otname); + + if (object_id == NULL) + { + SWSS_LOG_ERROR("oid pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (create) + { + return SAI_STATUS_SUCCESS; + } + + sai_object_id_t oid = *object_id; + + if (oid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("oid is set to null object id"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t ot = sai_object_type_query(oid); + + if (ot == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("%s oid 0x%llx is not valid object type, returned null object id", otname, oid); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t expected = object_type; + + if (ot != expected) + { + SWSS_LOG_ERROR("%s oid 0x%llx type %d is wrond type, expected object type %d", otname, oid, ot, expected); + + return SAI_STATUS_INVALID_PARAMETER; + } + + // check if object exists + + sai_object_meta_key_t meta_key_oid = { .object_type = expected, .key = { .object_id = oid } }; + + std::string key_oid = get_object_meta_key_string(meta_key_oid); + + if (!object_exists(key_oid)) + { + SWSS_LOG_ERROR("object key %s don't exists", key_oid.c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t meta_sai_create_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t* object_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_generic_fn create) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_oid(object_type, object_id, true); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = object_type, .key = { .object_id = SAI_NULL_OBJECT_ID } }; + + status = meta_generic_validation_create(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (create == NULL) + { + SWSS_LOG_ERROR("create function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = create(object_type, object_id, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("create status: %d", status); + } + else + { + SWSS_LOG_ERROR("create status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + // new oid was created, save id and validate it + + meta_key.key.object_id = *object_id; + meta_generic_validation_post_create(meta_key, attr_count, attr_list); + } + + return status; +} + +sai_status_t meta_sai_remove_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ sai_remove_generic_fn remove) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = object_type, .key = { .object_id = object_id } }; + + status = meta_generic_validation_remove(meta_key); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (remove == NULL) + { + SWSS_LOG_ERROR("remove function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = remove(object_type, object_id); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("remove status: %d", status); + } + else + { + SWSS_LOG_ERROR("remove status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_remove(meta_key); + } + + return status; +} + +sai_status_t meta_sai_set_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ const sai_attribute_t *attr, + _In_ sai_set_generic_attribute_fn set) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = object_type, .key = { .object_id = object_id } }; + + status = meta_generic_validation_set(meta_key, attr); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (set == NULL) + { + SWSS_LOG_ERROR("set function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = set(object_type, object_id, attr); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("set status: %d", status); + } + else + { + SWSS_LOG_ERROR("set status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_set(meta_key, attr); + } + + return status; +} + +sai_status_t meta_sai_get_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_generic_attribute_fn get) +{ + SWSS_LOG_ENTER(); + + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, false); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + sai_object_meta_key_t meta_key = { .object_type = object_type, .key = { .object_id = object_id } }; + + status = meta_generic_validation_get(meta_key, attr_count, attr_list); + + if (status != SAI_STATUS_SUCCESS) + { + return status; + } + + if (get == NULL) + { + SWSS_LOG_ERROR("get function pointer is NULL"); + + return SAI_STATUS_FAILURE; + } + + status = get(object_type, object_id, attr_count, attr_list); + + if (status == SAI_STATUS_SUCCESS) + { + SWSS_LOG_DEBUG("get status: %d", status); + } + else + { + SWSS_LOG_ERROR("get status: %d", status); + } + + if (status == SAI_STATUS_SUCCESS) + { + meta_generic_validation_post_get(meta_key, attr_count, attr_list); + } + + return status; +} diff --git a/meta/sai_meta.h b/meta/sai_meta.h new file mode 100644 index 000000000000..4210a28a55e4 --- /dev/null +++ b/meta/sai_meta.h @@ -0,0 +1,791 @@ +#ifndef __SAI_META_H__ +#define __SAI_META_H__ + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "sai.h" +} + +#include "swss/logger.h" +#include "../common/saiserialize.h" + +#define MAX_LIST_COUNT 128 + +#define DEFAULT_LAYER2_FRAME_SIZE 1514 + +#define DEFAULT_VLAN_NUMBER 1 +#define MINIMUM_VLAN_NUMBER 1 +#define MAXIMUM_VLAN_NUMBER 4094 + +#define MINIMUM_L4_PORT_NUMBER 0x0 +#define MAXIMUM_L4_PORT_NUMBER 0xFFFF + +// should be 64 ? +#define MINIMUM_PACKET_SIZE 0 +#define MAXIMUM_PACKET_SIZE 0x10000 + +#ifndef SAI_QUEUE_ATTR_INDEX +#define SAI_QUEUE_ATTR_INDEX 0x100 // TODO remove on new SAI +#endif + +#define StringifyEnum(x) ((std::is_enum::value) ? #x : 0) + +typedef struct _sai_object_meta_key_t +{ + sai_object_type_t object_type; + + union + { + sai_object_id_t object_id; + sai_vlan_id_t vlan_id; + sai_hostif_trap_id_t trap_id; + sai_fdb_entry_t fdb_entry; + sai_neighbor_entry_t neighbor_entry; + sai_unicast_route_entry_t route_entry; + + } key; + +} sai_object_meta_key_t; + +typedef enum _sai_attr_flags_t { + + /* + * Attribute with this flags is mandatory when calling CREATE api, unless + * this attribute is marked as conditional. Must be combined with + * CREATE_ONLY or CREATE_AND_SET flag. + */ + + SAI_ATTR_FLAGS_MANDATORY_ON_CREATE = (1 << 0), + + /* + * Attribute with this flag can only be created and it's value cannot be + * changed by SET api. Can be combined with with MANDATORY flag. If + * attribute is not combined with MANDATORY flag then DEFAULT value must be + * provided for this attribute. + */ + + SAI_ATTR_FLAGS_CREATE_ONLY = (1 << 1), + + /* + * Attribute with this flag can be created and after creation value may be + * modified using SET api. Can be bombined with MANDATORY flag. If + * attribute is not combined with MANDATORY flag then DEFAULT value must be + * provided for this attribute. + */ + + SAI_ATTR_FLAGS_CREATE_AND_SET = (1 << 2), + + /* + * Attribute with this flag can only be read using GET api. Creation and + * modification is not possible. Can be combined with DYNAMIC flag for + * example counter attribute. + */ + + SAI_ATTR_FLAGS_READ_ONLY = (1 << 3), + + /* + * Attribute with this flag is treated as unique key (can only be combined + * with MANDATORY and CREATE_ONLY flags. This flag will indicate that + * creating new object with the same key will fail (for example VLAN). + * There may be more than one key in attributes when creating object. Key + * should be used only on primitive attribute values (like enum or int). + * In some cases it may be supported on list (for port lanes) but then + * extra logic is needed to compute and handle that key. + * + * If multiple keys are provided, meta key is created as combination of + * keys in order attribute id's are declared (internal details). + */ + + SAI_ATTR_FLAGS_KEY = (1 << 4), + + /* + * Attribute with this flag indicates that value of the attribute is + * dynamic and can change in time (like a attribute counter value, or port + * operational status). Change may happen independently or when other + * attribute was created or modified (creating vlan member will change vlan + * member list). Can be combined with READ_ONLY flag. In future it maybe + * possible to combine this attribute with other flags. + */ + + //SAI_ATTR_FLAGS_DYNAMIC = (1 << 5), + + /* Below flags are subject to be removed */ + + /* + * Attribute with this flag will indicate that this attribute is special + * and it needs extended logic to be handled. This flag can only be + * standalone. This flag may be removed in the future. + * + * NOTE: we could assume that this logic will skip generic validation + * on attribute that has this flag. + */ + + //SAI_ATTR_FLAGS_SPECIAL = (1 << 6), + + /* + * Attribute with this flag can be SET only. This flag is subject to be + * removed since SAI api spec is changing. This attribute must be + * standalone. + */ + + //SAI_ATTR_FLAGS_SET_ONLY = (1 << 7), + + /* + * Attribute with this flag will indicate that this attribute is acl entry + * field. This flag is subject to be removed since it can be deduced from + * serialization type. + */ + + //SAI_ATTR_FLAGS_ACL_FIELD = (1 << 8), + + /* + * Attribute with this flag will indicate that this attribute is acl entry + * action. This flag is subject to be removed since it can be deduced from + * serialization type. + */ + //SAI_ATTR_FLAGS_ACL_ACTION = (1 << 9), + +} sai_attr_flags_t; + +#define HAS_FLAG_MANDATORY_ON_CREATE(x) ((x & SAI_ATTR_FLAGS_MANDATORY_ON_CREATE) == SAI_ATTR_FLAGS_MANDATORY_ON_CREATE) +#define HAS_FLAG_CREATE_ONLY(x) ((x & SAI_ATTR_FLAGS_CREATE_ONLY) == SAI_ATTR_FLAGS_CREATE_ONLY) +#define HAS_FLAG_CREATE_AND_SET(x) ((x & SAI_ATTR_FLAGS_CREATE_AND_SET) == SAI_ATTR_FLAGS_CREATE_AND_SET) +#define HAS_FLAG_READ_ONLY(x) ((x & SAI_ATTR_FLAGS_READ_ONLY) == SAI_ATTR_FLAGS_READ_ONLY) +#define HAS_FLAG_KEY(x) ((x & SAI_ATTR_FLAGS_KEY) == SAI_ATTR_FLAGS_KEY) +#define HAS_FLAG_DYNAMIC(x) ((x & SAI_ATTR_FLAGS_DYNAMIC) == SAI_ATTR_FLAGS_DYNAMIC) +#define HAS_FLAG_SPECIAL(x) ((x & SAI_ATTR_FLAGS_SPECIAL) == SAI_ATTR_FLAGS_SPECIAL) +#define HAS_FLAG_SET_ONLY(x) ((x & SAI_ATTR_FLAGS_SET_ONLY) == SAI_ATTR_FLAGS_SET_ONLY) +#define HAS_FLAG_ACL_FIELD(x) ((x & SAI_ATTR_FLAGS_ACL_FIELD) == SAI_ATTR_FLAGS_ACL_FIELD) +#define HAS_FLAG_ACL_ACTION(x) ((x & SAI_ATTR_FLAGS_ACL_ACTION) == SAI_ATTR_FLAGS_ACL_ACTION) + +/* + * Inline operator is required to not cause error when combining flags. + * Error is raised by compiler flags: -Werror -fpermissive + */ + +constexpr inline sai_attr_flags_t operator|(sai_attr_flags_t a, sai_attr_flags_t b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +typedef enum _sai_default_value_type_t { + + /* + * There is no default value. + * This must be assigned on MANDATORY_ON_CREATE + * attributes. + */ + + SAI_DEFAULT_VALUE_TYPE_NONE = 0, + + /* + * Default value is just a const value. + */ + + SAI_DEFAULT_VALUE_TYPE_CONST, + + /* + * Value must be in range provided by other attribute + * (usually by SWITCH). Range can be obtined by GET api. + * Usually default value is minimum of range. + */ + + SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + + /* + * Default value in this case is equal to other + * attribute value (usually SWITCH attribute). + */ + + SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE, + + /* + * Default value is just empty list. + * We introduce this type to not declare empty list each time. + * TODO this can be obvious if attribute is + * serialization type list, and pointer in list is NULL + */ + + SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + + /* + * This value is assigned by switch vendor + * like default switch MAC address. + * + * It can also be default created object + * like default hash. + * + * TODO vendor specific should be different + * than default objects that are created + * by default. + */ + + SAI_DEFAULT_VALUE_TYPE_VENDOR_SPECIFIC, + + /* + * This object is created by default + * inside switch (hidden object). + * + * Should be used only on object id types. + */ + SAI_DEFAULT_VALUE_TYPE_SWITCH_INTERNAL, + + /* + * If attribute is not specified, then default value + * is inherited from other object (type + attr). + */ + + SAI_DEFAULT_VALUE_TYPE_INHERIT, + + // TODO + // - const assigned by switch + // - min in range assigned by switch + // - max in range assigned by switch + // - default created object assigned by switch + +} sai_default_value_type_t; + +typedef enum _sai_attr_condition_type_t { + + /* + * This attribute is not conditional atttribute + */ + + SAI_ATTR_CONDITION_TYPE_NONE = 0, + + /* + * Any condition that will be true will make + * this attribute mandatory. + */ + + SAI_ATTR_CONDITION_TYPE_OR, + + /* + * All condictions must meet for this attribute + * to be mandatory on create. + */ + + SAI_ATTR_CONDITION_TYPE_AND, + +} sai_attr_condition_type_t; + +typedef struct _sai_attr_condition_t { + + /* + * Specifies valid attribute id for this object type. + * Attribute is for the same object type. + */ + + const sai_attr_id_t attrid; + + /* + * Condition value that attribute will be mandatory + * then default value must be provided for attribute. + * + * We would like to use sai_attribute_value_t here + * but there is gcc bug: + * + * internal compiler error: in reshape_init_class, at cp/decl.c:5208 + * + * when union is used, so we declare our own value class + * withoud uniotn. Unfortunetly this will lead to populate + * all fields in struct even if not used. + * + */ + + const sai_attribute_value_t condition; + + const char * const enumstr; + + // TODO for enums we could have a + +} sai_attr_condition_t; + +// TODO we need string representations of: +// - object types +// - attributes id's +// - enum types +// - enum values + +// TODO add extra fields that maybe useful +// bool allowrepetitiononlist; (false by default) +// bool allowmixedobjecttypes; (false by default) +// bool allowemptylist; (false by default) +// bool hasMandatoryAttribytes (auto set) +// bool hasContitionalAttributes (auto set) +// bool hasValidOnlyAttributes (auto set) +// bool snoopsave (for readonly attributes it will be stored in local db +// also must be ignored on post set/remve (check flags) so +// we could validate ranges for example what are valid when doing query + +typedef struct _sai_attr_metadata_t { + + /* + * Specifies valid SAI object type. + */ + + const sai_object_type_t objecttype; + + /* + * Specifies valid attribute id for this object type. + */ + + const sai_attr_id_t attrid; + + /* + * Specifies serialization type for this attribute. + */ + + const sai_attr_serialization_type_t serializationtype; + + /* + * Specifies flags for this attribute. + */ + + const sai_attr_flags_t flags; + + // TODO we should have flag - allow list duplicates + + /* + * If object serialization type is OBJECT_ID + * this list specifies what object type can be used. + * + * TODO if list contains SAI_NULL_OBJECT_ID then + * it can be used as actual object. + */ + + //const std::vector&allowedobjecttypes; + const std::set allowedobjecttypes; + + /* + * If object serialization type is OBJECT_ID + * it tells whether SAI_NULL_OBJECT_ID can be used + * as actual id. + * + * TODO could be passed as SAI_NULL_OBJECT_ID to list + * instead of this flag but then we would need extra + * check on checking types. + */ + + const bool allownullobjectid; + + /* + * Specifies default value type. Since default value + * can be a const value, a const assigned by switch + * (which is not know at compile time, but can be + * obtained by GET api, or a min/max value in specific + * range also assigned by switch at runtime. + * Also default value can be an object + */ + + const sai_default_value_type_t defaultvaluetype; + + /* + * TODO if value type is ATTR type, then we need to + * specify object_id and attr_id from which we need + * to get value. + */ + + /* + * If creation flag is CREATE_ONLY or CREATE_AND_SET + * then default value must be provided for attribute. + * + * NOTE: default value may not apply for: + * - ACL ENTRY FIELD or ACL ENTRY ACTION + * we need to take special care about those + */ + + const sai_attribute_value_t defaultvalue; + + /* + * Indicates wheter attribute is enum value. + * Serialization type must be INT32. + * + * NOTE: could be deduced from enum type string or + * enum vector values and serialization type. + */ + + // const bool isenum; + + /* + * Indicates wheter attribute is enum list value. + * Serialization type must be INT32_LIST. + * + * NOTE: could be deduced from enum type string or + * enum vector values and serialization type. + */ + + // const bool isenumlist; + + /* + * If attribute is enum, this entry should provide + * a string name of enum type. + */ + + const char* const enumtypestr; + + /* + * If attribute is enum this set will specify + * all possible values for this enum type. + * + * NOTE: reference here is important since enum + * sets are declared in only one cpp file and + * init is done only at compile time. + */ + + const std::set& enumallowedvalues; + + /* + * Specifies condition type of attribute. + * + * NOTE: currently all conditions are "OR" conditions + * so we can deduce if this is conditional type + * if any conditions are defined. + */ + + //const sai_attr_condition_type_t conditiontype; + + /* + * If condition type is specified, this vector will + * describe all conditions. + */ + + const std::vector conditions; + + /* + * If conditions are specified (OR condition assumed) + * then this attribute is only valid when different + * atribute has condition value set. Valid only + * attribute (against we check) can be dynamic so + * this attribute can't be marked as MANDATORY on + * create since default value will be required. + * + * NOTE: There is only handful of attributes with + * valid only mark. For now we will check that in + * specific attribute logic. + */ + + // const std::vector validonlywhen; + + // HELPER METHODS + + bool isconditional() const + { + return !conditions.empty(); + } + + bool isenum() const + { + return (serializationtype == SAI_SERIALIZATION_TYPE_INT32 || + serializationtype == SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32 || + serializationtype == SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32) && + (!enumallowedvalues.empty()) && + (enumtypestr != NULL); + } + + bool isenumlist() const + { + return (serializationtype == SAI_SERIALIZATION_TYPE_INT32_LIST) && + (!enumallowedvalues.empty()) && + (enumtypestr != NULL); + } + + bool isvlan() const + { + // TODO would be better to be a field + + if (objecttype == SAI_OBJECT_TYPE_VLAN_MEMBER && + attrid == SAI_VLAN_MEMBER_ATTR_VLAN_ID) + { + return true; + } + + if (objecttype == SAI_OBJECT_TYPE_ROUTER_INTERFACE && + attrid == SAI_ROUTER_INTERFACE_ATTR_VLAN_ID) + { + return true; + } + + + if (objecttype == SAI_OBJECT_TYPE_PORT && + attrid == SAI_PORT_ATTR_PORT_VLAN_ID) + { + return true; + } + + if (objecttype == SAI_OBJECT_TYPE_MIRROR && + attrid == SAI_MIRROR_SESSION_ATTR_VLAN_ID) + { + return true; + } + + // has different serialization than u16 + // SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID + // SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID + // SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_ID + // SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_ID + + return false; + } + + ~_sai_attr_metadata_t() { } + +} sai_attr_metadata_t; + +#define ENUM_VALUES(x) enum_ ## x ## _values +#define DEFINE_ENUM_VALUES(x) const std::set ENUM_VALUES(x) +#define EXTERN_ENUM_VALUES(x) extern DEFINE_ENUM_VALUES(x) + +#define COND_ENUM(id,value) { .attrid = id, .condition = sai_attribute_value_t { .s32 = value }, .enumstr = #value } +#define COND_BOOL(id,value) { .attrid = id, .condition = sai_attribute_value_t { .booldata = value }, .enumstr = NULL } + +EXTERN_ENUM_VALUES(sai_packet_action_t); +EXTERN_ENUM_VALUES(sai_meter_type_t); +EXTERN_ENUM_VALUES(sai_packet_color_t); +EXTERN_ENUM_VALUES(sai_hostif_trap_id_t); + +#define EXTERN_METADATA(x)\ +extern const sai_attr_metadata_t sai_ ## x ## _attr_metadata[];\ +extern const size_t sai_ ## x ## _attr_metadata_count; + +EXTERN_METADATA(acl_counter); +EXTERN_METADATA(acl_entry); +EXTERN_METADATA(acl_range); +EXTERN_METADATA(acl_table); +EXTERN_METADATA(buffer_pool); +EXTERN_METADATA(buffer_profile); +EXTERN_METADATA(fdb); +EXTERN_METADATA(hash); +EXTERN_METADATA(hostintf); +EXTERN_METADATA(hostintf_trap); +EXTERN_METADATA(hostintf_trap_group); +EXTERN_METADATA(lag); +EXTERN_METADATA(lag_member); +EXTERN_METADATA(mirror); +EXTERN_METADATA(neighbor); +EXTERN_METADATA(nexthop); +EXTERN_METADATA(nexthopgroup); +EXTERN_METADATA(policer); +EXTERN_METADATA(port); +EXTERN_METADATA(qos_maps); +EXTERN_METADATA(queue); +EXTERN_METADATA(route); +EXTERN_METADATA(router); +EXTERN_METADATA(routerintf); +EXTERN_METADATA(samplepacket); +EXTERN_METADATA(scheduler); +EXTERN_METADATA(scheduler_group); +EXTERN_METADATA(stp); +EXTERN_METADATA(switch); +EXTERN_METADATA(tunnel); +EXTERN_METADATA(tunnel_map); +EXTERN_METADATA(tunnel_table_entry); +EXTERN_METADATA(udf); +EXTERN_METADATA(udf_group); +EXTERN_METADATA(udf_match); +EXTERN_METADATA(vlan); +EXTERN_METADATA(vlan_member); +EXTERN_METADATA(wred); + +struct HashForEnum +{ + template std::size_t operator()(T t) const + { + return static_cast(t); + } +}; + +extern std::unordered_map, HashForEnum> AttributesMetadata; + +extern std::string get_attr_info(const sai_attr_metadata_t& md); +extern const char* get_object_type_name(sai_object_type_t o); +extern const char* get_attr_name(sai_object_type_t o, sai_attr_id_t a); + +extern const sai_attribute_t* get_attribute_by_id( + _In_ sai_attr_id_t id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + +extern const sai_attr_metadata_t* get_attribute_metadata( + _In_ sai_object_type_t objecttype, + _In_ sai_attr_id_t attrid); + +extern const sai_attribute_t* get_object_previous_attr( + _In_ const sai_object_meta_key_t meta_key, + _In_ const sai_attr_metadata_t& md); + +extern sai_status_t meta_init_db(); +extern void meta_init(); + +// GENERIC FUNCTION POINTERS + +typedef sai_status_t (*sai_create_generic_fn)( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t* object_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + +typedef sai_status_t (*sai_remove_generic_fn)( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id); + +typedef sai_status_t (*sai_set_generic_attribute_fn)( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ const sai_attribute_t *attr); + +typedef sai_status_t (*sai_get_generic_attribute_fn)( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list); + +// META GENERIC + +extern sai_status_t meta_sai_create_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t* object_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_generic_fn create); + +extern sai_status_t meta_sai_remove_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ sai_remove_generic_fn remove); + +extern sai_status_t meta_sai_set_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ const sai_attribute_t *attr, + _In_ sai_set_generic_attribute_fn set); + +extern sai_status_t meta_sai_get_oid( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_generic_attribute_fn get); + +// META TRAP + +extern sai_status_t meta_sai_set_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr, + _In_ sai_set_hostif_trap_attribute_fn set); + +extern sai_status_t meta_sai_get_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_hostif_trap_attribute_fn get); + +// META FDB + +extern sai_status_t meta_sai_create_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_fdb_entry_fn create); + +extern sai_status_t meta_sai_remove_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ sai_remove_fdb_entry_fn remove); + +extern sai_status_t meta_sai_set_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ const sai_attribute_t *attr, + _In_ sai_set_fdb_entry_attribute_fn set); + +extern sai_status_t meta_sai_get_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_fdb_entry_attribute_fn get); + +// META NEIGHBOR + +extern sai_status_t meta_sai_create_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_neighbor_entry_fn create); + +extern sai_status_t meta_sai_remove_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ sai_remove_neighbor_entry_fn remove); + +extern sai_status_t meta_sai_set_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ const sai_attribute_t *attr, + _In_ sai_set_neighbor_attribute_fn set); + +extern sai_status_t meta_sai_get_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_neighbor_attribute_fn get); + +// META SWITCH + +extern sai_status_t meta_sai_set_switch( + _In_ const sai_attribute_t *attr, + _In_ sai_set_switch_attribute_fn set); + +extern sai_status_t meta_sai_get_switch( + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_switch_attribute_fn get); + +// META VLAN + +extern sai_status_t meta_sai_create_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ sai_create_vlan_fn create); + +extern sai_status_t meta_sai_remove_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ sai_remove_vlan_fn remove); + +extern sai_status_t meta_sai_set_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr, + _In_ sai_set_vlan_attribute_fn set); + +extern sai_status_t meta_sai_get_vlan( + _In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_vlan_attribute_fn get); + +// META ROUTE + +extern sai_status_t meta_sai_create_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ sai_create_route_fn create); + +extern sai_status_t meta_sai_remove_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ sai_remove_route_fn remove); + +extern sai_status_t meta_sai_set_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ const sai_attribute_t *attr, + _In_ sai_set_route_attribute_fn set); + +extern sai_status_t meta_sai_get_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list, + _In_ sai_get_route_attribute_fn get); + +#endif // __SAI_META_H__ diff --git a/meta/sai_meta_acl.cpp b/meta/sai_meta_acl.cpp new file mode 100644 index 000000000000..286ed6ee54dc --- /dev/null +++ b/meta/sai_meta_acl.cpp @@ -0,0 +1,1465 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_ACL_TABLE + +#define DEF_ACL_TABLE_FIELD(x)\ + {\ + .objecttype = SAI_OBJECT_TYPE_ACL_TABLE,\ + .attrid = SAI_ACL_TABLE_ATTR_FIELD_ ## x,\ + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL,\ + .flags = SAI_ATTR_FLAGS_CREATE_ONLY,\ + .allowedobjecttypes = { },\ + .allownullobjectid = false,\ + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST,\ + .defaultvalue = { .booldata = false },\ + .enumtypestr = NULL,\ + .enumallowedvalues = { },\ + .conditions = { },\ + }, + +DEFINE_ENUM_VALUES(sai_acl_stage_t) +{ + SAI_ACL_STAGE_INGRESS, + SAI_ACL_STAGE_EGRESS, + SAI_ACL_SUBSTAGE_INGRESS_PRE_L2, + SAI_ACL_SUBSTAGE_INGRESS_POST_L3 +}; + +DEFINE_ENUM_VALUES(sai_acl_range_type_t) +{ + SAI_ACL_RANGE_L4_SRC_PORT_RANGE, + SAI_ACL_RANGE_L4_DST_PORT_RANGE, + SAI_ACL_RANGE_OUTER_VLAN, + SAI_ACL_RANGE_INNER_VLAN, + SAI_ACL_RANGE_PACKET_LENGTH +}; + +DEFINE_ENUM_VALUES(sai_packet_color_t) +{ + SAI_PACKET_COLOR_GREEN, + SAI_PACKET_COLOR_YELLOW, + SAI_PACKET_COLOR_RED +}; + +DEFINE_ENUM_VALUES(sai_acl_ip_type_t) + +{ + SAI_ACL_IP_TYPE_ANY, + SAI_ACL_IP_TYPE_IP, + SAI_ACL_IP_TYPE_NON_IP, + SAI_ACL_IP_TYPE_IPv4ANY, + SAI_ACL_IP_TYPE_NON_IPv4, + SAI_ACL_IP_TYPE_IPv6ANY, + SAI_ACL_IP_TYPE_NON_IPv6, + SAI_ACL_IP_TYPE_ARP, + SAI_ACL_IP_TYPE_ARP_REQUEST, + SAI_ACL_IP_TYPE_ARP_REPLY +}; + +DEFINE_ENUM_VALUES(sai_acl_ip_frag_t) +{ + SAI_ACL_IP_FRAG_ANY, + SAI_ACL_IP_FRAG_NON_FRAG, + SAI_ACL_IP_FRAG_NON_FRAG_OR_HEAD, + SAI_ACL_IP_FRAG_HEAD, + SAI_ACL_IP_FRAG_NON_HEAD +}; + +DEFINE_ENUM_VALUES(sai_packet_vlan_t) +{ + SAI_PACKET_VLAN_UNTAG, + SAI_PACKET_VLAN_SINGLE_OUTER_TAG, + SAI_PACKET_VLAN_DOUBLE_TAG +}; + +const sai_attr_metadata_t sai_acl_table_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_ACL_TABLE, + .attrid = SAI_ACL_TABLE_ATTR_STAGE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_acl_stage_t ), + .enumallowedvalues = ENUM_VALUES ( sai_acl_stage_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_TABLE, + .attrid = SAI_ACL_TABLE_ATTR_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // Value in range + // SAI_SWITCH_ATTR_ACL_TABLE_MINIMUM_PRIORITY + // SAI_SWITCH_ATTR_ACL_TABLE_MAXIMUM_PRIORITY + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_TABLE, + .attrid = SAI_ACL_TABLE_ATTR_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO this attribute is special, since it can change dynamically, dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_TABLE, + .attrid = SAI_ACL_TABLE_ATTR_GROUP_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ACL_TABLE_GROUP }, // TODO there is no API to create this + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO group ID is special, since when not specified it's created automatically + // by switch and user can obtain it via GET api and group tables. + // This behaviour should be changed so no object would be created internally. + // It will be tricky to track this object usage. + }, + + // ACL TABLE FIELDS + + // NOTE: At least one field must be specified this is extra condition on create function + + DEF_ACL_TABLE_FIELD ( SRC_IPv6 ) + DEF_ACL_TABLE_FIELD ( DST_IPv6 ) + DEF_ACL_TABLE_FIELD ( SRC_MAC ) + DEF_ACL_TABLE_FIELD ( DST_MAC ) + DEF_ACL_TABLE_FIELD ( SRC_IP ) + DEF_ACL_TABLE_FIELD ( DST_IP ) + DEF_ACL_TABLE_FIELD ( IN_PORTS ) + DEF_ACL_TABLE_FIELD ( OUT_PORTS ) + DEF_ACL_TABLE_FIELD ( IN_PORT ) + DEF_ACL_TABLE_FIELD ( OUT_PORT ) + DEF_ACL_TABLE_FIELD ( SRC_PORT ) + DEF_ACL_TABLE_FIELD ( OUTER_VLAN_ID ) + DEF_ACL_TABLE_FIELD ( OUTER_VLAN_PRI ) + DEF_ACL_TABLE_FIELD ( OUTER_VLAN_CFI ) + DEF_ACL_TABLE_FIELD ( INNER_VLAN_ID ) + DEF_ACL_TABLE_FIELD ( INNER_VLAN_PRI ) + DEF_ACL_TABLE_FIELD ( INNER_VLAN_CFI ) + DEF_ACL_TABLE_FIELD ( L4_SRC_PORT ) + DEF_ACL_TABLE_FIELD ( L4_DST_PORT ) + DEF_ACL_TABLE_FIELD ( ETHER_TYPE ) + DEF_ACL_TABLE_FIELD ( IP_PROTOCOL ) + DEF_ACL_TABLE_FIELD ( DSCP ) + DEF_ACL_TABLE_FIELD ( ECN ) + DEF_ACL_TABLE_FIELD ( TTL ) + DEF_ACL_TABLE_FIELD ( TOS ) + DEF_ACL_TABLE_FIELD ( IP_FLAGS ) + DEF_ACL_TABLE_FIELD ( TCP_FLAGS ) + DEF_ACL_TABLE_FIELD ( IP_TYPE ) + DEF_ACL_TABLE_FIELD ( IP_FRAG ) + DEF_ACL_TABLE_FIELD ( IPv6_FLOW_LABEL ) + DEF_ACL_TABLE_FIELD ( TC ) + DEF_ACL_TABLE_FIELD ( ICMP_TYPE ) + DEF_ACL_TABLE_FIELD ( ICMP_CODE ) + DEF_ACL_TABLE_FIELD ( VLAN_TAGS ) + DEF_ACL_TABLE_FIELD ( FDB_DST_USER_META ) + DEF_ACL_TABLE_FIELD ( ROUTE_DST_USER_META ) + DEF_ACL_TABLE_FIELD ( NEIGHBOR_DST_USER_META ) + DEF_ACL_TABLE_FIELD ( PORT_USER_META ) + DEF_ACL_TABLE_FIELD ( VLAN_USER_META ) + DEF_ACL_TABLE_FIELD ( ACL_USER_META ) + DEF_ACL_TABLE_FIELD ( FDB_NPU_META_DST_HIT ) + DEF_ACL_TABLE_FIELD ( NEIGHBOR_NPU_META_DST_HIT ) + DEF_ACL_TABLE_FIELD ( ROUTE_NPU_META_DST_HIT ) + + // TODO SAI_ACL_TABLE_ATTR_USER_DEFINED_FIELD_GROUP_MIN .. SAI_ACL_TABLE_ATTR_USER_DEFINED_FIELD_GROUP_MAX + + { + .objecttype = SAI_OBJECT_TYPE_ACL_TABLE, + .attrid = SAI_ACL_TABLE_ATTR_FIELD_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_acl_range_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_acl_range_type_t ), + .conditions = { }, + }, + + //{ + // .objecttype = SAI_OBJECT_TYPE_ACL_TABLE, + // .attrid = SAI_ACL_TABLE_ATTR_ACTION_LIST + // .serializationtype = SAI_SERIALIZATION_TYPE_INT32_LIST, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, // TODO if not mandatory, what is default? + // .allowedobjecttypes = { }, + // .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + // .allownullobjectid = false, + // .defaultvalue = { }, + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { }, + + // // TODO this is special since if switch supports it, it may be mandatory to pass it + // // or it maybe mandatory to pass some fields and they may be const, or we can add + // // more dynamicaly, we need very special handling for this + + // /** List of actions in sai_acl_table_action_list_t [sai_s32_list_t] + // * Based on the acl capability per stage obtained from the switch + // * attribute SAI_SWITCH_ATTR_ACL_CAPABILITY application should + // * pass the action list if its mandatory per stage. + // * If its not mandatory application can either pass the action list + // * or ignore it. + // */ + //}, +}; + +const size_t sai_acl_table_attr_metadata_count = sizeof(sai_acl_table_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_ACL_ENTRY + +const sai_attr_metadata_t sai_acl_entry_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_TABLE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ACL_TABLE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // valid range in SAI_SWITCH_ATTR_ACL_ENTRY_MINIMUM_PRIORITY .. SAI_SWITCH_ATTR_ACL_ENTRY_MAXIMUM_PRIORITY + }, + + // ACL ENTRY FIELDS + + // it is mandatory to pass at least one field this will require logic on creation time + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_SRC_IPv6, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_DST_IPv6, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_SRC_MAC, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_DST_MAC, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_DST_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_PRI, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_CFI, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_PRI, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_CFI, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_L4_SRC_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_L4_DST_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_DSCP, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ECN, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_TTL, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_TOS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IP_FLAGS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IP_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_acl_ip_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_acl_ip_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IP_FRAG, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_acl_ip_frag_t ), + .enumallowedvalues = ENUM_VALUES ( sai_acl_ip_frag_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_IPv6_FLOW_LABEL, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_TC, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ICMP_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ICMP_CODE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_VLAN_TAGS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_packet_vlan_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_vlan_t ), + .conditions = { }, + }, + + // TODO we need checks for all ranges + + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_FDB_DST_USER_META, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST_USER_META, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_USER_META, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_PORT_USER_META, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_VLAN_USER_META, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ACL_USER_META, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_FDB_NPU_META_DST_HIT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_NPU_META_DST_HIT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // TODO SAI_ACL_ENTRY_ATTR_USER_DEFINED_FIELD_MIN .. SAI_ACL_ENTRY_ATTR_USER_DEFINED_FIELD_MAX + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_FIELD_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ACL_RANGE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // ACL ENTRY ACTIONS + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_LAG, SAI_OBJECT_TYPE_NEXT_HOP, SAI_OBJECT_TYPE_NEXT_HOP_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_LAG, SAI_OBJECT_TYPE_NEXT_HOP, SAI_OBJECT_TYPE_NEXT_HOP_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_FLOOD, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32, // TODO what type? parameter not needed? + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_COUNTER, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ACL_COUNTER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_MIRROR }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // extra condition maybe needed to check on session + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_MIRROR }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // extra condition maybe needed to check on session + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_POLICER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_DECREMENT_TTL, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32, // TODO parameter not needed? + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_TC, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_COLOR, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_packet_color_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_color_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO should this vlan exist? should it be object id? + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_PRI, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO should this vlan exist? should it be object id? + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_PRI, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_MAC, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_MAC, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IPv6, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IPv6, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_DSCP, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_ECN, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_SRC_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_DST_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SAMPLEPACKET }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SAMPLEPACKET }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_CPU_QUEUE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QUEUE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_ACL_META_DATA, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_BLOCK_PORT_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_ENTRY, + .attrid = SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // range in SAI_SWITCH_ATTR_ACL_USER_TRAP_ID_RANGE + }, +}; + +const size_t sai_acl_entry_attr_metadata_count = sizeof(sai_acl_entry_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_ACL_COUNTER + +const sai_attr_metadata_t sai_acl_counter_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_ACL_COUNTER, + .attrid = SAI_ACL_COUNTER_ATTR_TABLE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ACL_TABLE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_COUNTER, + .attrid = SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_COUNTER, + .attrid = SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_COUNTER, + .attrid = SAI_ACL_COUNTER_ATTR_PACKETS, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_ACL_COUNTER, + .attrid = SAI_ACL_COUNTER_ATTR_BYTES, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, +}; + +const size_t sai_acl_counter_attr_metadata_count = sizeof(sai_acl_counter_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_ACL_RANGE + +const sai_attr_metadata_t sai_acl_range_attr_metadata[] = { + + // TODO declared only in newer SAI + +// { +// .objecttype = SAI_OBJECT_TYPE_ACL_RANGE, +// .attrid = SAI_ACL_RANGE_ATTR_TYPE, +// .serializationtype = SAI_SERIALIZATION_TYPE_ACL_RANGE +// .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, +// .allowedobjecttypes = { }, +// .allownullobjectid = false, +// .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, +// .defaultvalue = { }, +// .enumtypestr = StringifyEnum ( sai_acl_range_type_t ), +// .enumallowedvalues = ENUM_VALUES ( sai_acl_range_type_t ), +// .conditions = { }, +// }, + +// { +// .objecttype = SAI_OBJECT_TYPE_ACL_RANGE, +// .attrid = SAI_ACL_RANGE_ATTR_LIMIT, +// .serializationtype = SAI_SERIALIZATION_TYPE_ACL_RANGE +// .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, +// .allowedobjecttypes = { }, +// .allownullobjectid = false, +// .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, +// .defaultvalue = { }, +// .enumtypestr = NULL, +// .enumallowedvalues = { }, +// .conditions = { }, +// +// // TODO extra logic is needed to check that range depending on type +// }, + +}; + +const size_t sai_acl_range_attr_metadata_count = sizeof(sai_acl_range_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_buffer.cpp b/meta/sai_meta_buffer.cpp new file mode 100644 index 000000000000..e01e2426674a --- /dev/null +++ b/meta/sai_meta_buffer.cpp @@ -0,0 +1,199 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_BUFFER_POOL + +DEFINE_ENUM_VALUES(sai_buffer_pool_type_t) +{ + SAI_BUFFER_POOL_INGRESS, + SAI_BUFFER_POOL_EGRESS +}; + +DEFINE_ENUM_VALUES(sai_buffer_threshold_mode_t) +{ + SAI_BUFFER_THRESHOLD_MODE_STATIC, + SAI_BUFFER_THRESHOLD_MODE_DYNAMIC +}; + +const sai_attr_metadata_t sai_buffer_pool_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_POOL, + .attrid = SAI_BUFFER_POOL_ATTR_SHARED_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_POOL, + .attrid = SAI_BUFFER_POOL_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_buffer_pool_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_buffer_pool_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_POOL, + .attrid = SAI_BUFFER_POOL_ATTR_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_POOL, + .attrid = SAI_BUFFER_POOL_ATTR_TH_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_BUFFER_THRESHOLD_MODE_DYNAMIC }, + .enumtypestr = StringifyEnum ( sai_buffer_threshold_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_buffer_threshold_mode_t ), + .conditions = { }, + }, +}; + +const size_t sai_buffer_pool_attr_metadata_count = sizeof(sai_buffer_pool_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_BUFFER_PROFILE + +const sai_attr_metadata_t sai_buffer_profile_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_POOL_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_BUFFER_POOL }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // Pool id = SAI_NULL_OBJECT_ID can be used when profile is not associated with specific + // pool, for example for global port buffer. Not applicable to priority group or queue buffer profile + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_TH_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_INHERIT, // TODO we need to specify from which inherit .oid? + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_buffer_threshold_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_buffer_threshold_mode_t ), // TODO 3rd value needed to use pool and set to default (PR in progress) + .conditions = { }, + + // If set, this overrides SAI_BUFFER_POOL_ATTR_TH_MODE. + // If not set, use SAI_BUFFER_POOL_ATTR_TH_MODE. + // (default to value set in SAI_BUFFER_POOL_ATTR_TH_MODE.) + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH, + .serializationtype = SAI_SERIALIZATION_TYPE_INT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, // ENUM_COND ( SAI_BUFFER_PROFILE_ATTR_TH_MODE, SAI_BUFFER_THRESHOLD_MODE_DYNAMIC ), + + // TODO condition here is complex, since if TH is inherited from pool then this is hard to determine + // and it should be SAI_BUFFER_POOL_TH_MODE = SAI_BUFFER_THRESHOLD_MODE_DYNAMIC, so this attribute depends on other attribute + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, // ENUM_COND ( SAI_BUFFER_PROFILE_ATTR_TH_MODE, SAI_BUFFER_THRESHOLD_MODE_DYNAMIC ), + + // TODO condition here is complex, since if TH is inherited from pool then this is hard to determine + // and it should be SAI_BUFFER_POOL_TH_MODE = SAI_BUFFER_THRESHOLD_MODE_DYNAMIC, so this attribute depends on other attribute + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_XOFF_TH, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO valid only for ingress priority group + }, + + { + .objecttype = SAI_OBJECT_TYPE_BUFFER_PROFILE, + .attrid = SAI_BUFFER_PROFILE_ATTR_XON_TH, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO valid only for ingress priority group + }, +}; + +const size_t sai_buffer_profile_attr_metadata_count = sizeof(sai_buffer_profile_attr_metadata)/sizeof(sai_attr_metadata_t); + diff --git a/meta/sai_meta_fdb.cpp b/meta/sai_meta_fdb.cpp new file mode 100644 index 000000000000..fc26227ccd81 --- /dev/null +++ b/meta/sai_meta_fdb.cpp @@ -0,0 +1,74 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_FDB + +DEFINE_ENUM_VALUES(sai_fdb_entry_type_t) +{ + SAI_FDB_ENTRY_DYNAMIC, + SAI_FDB_ENTRY_STATIC +}; + +const sai_attr_metadata_t sai_fdb_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_FDB, + .attrid = SAI_FDB_ENTRY_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_fdb_entry_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_fdb_entry_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_FDB, + .attrid = SAI_FDB_ENTRY_ATTR_PORT_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_LAG, SAI_OBJECT_TYPE_TUNNEL }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO some extra check may be required on tunnel + }, + + { + .objecttype = SAI_OBJECT_TYPE_FDB, + .attrid = SAI_FDB_ENTRY_ATTR_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_FDB, + .attrid = SAI_FDB_ENTRY_ATTR_META_DATA, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO valid range is SAI_SWITCH_ATTR_FDB_DST_USER_META_DATA_RANGE + }, +}; + +const size_t sai_fdb_attr_metadata_count = sizeof(sai_fdb_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_hash.cpp b/meta/sai_meta_hash.cpp new file mode 100644 index 000000000000..ce36d40445f7 --- /dev/null +++ b/meta/sai_meta_hash.cpp @@ -0,0 +1,52 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_HASH + +DEFINE_ENUM_VALUES(sai_native_hash_field_t) +{ + SAI_NATIVE_HASH_FIELD_SRC_IP, + SAI_NATIVE_HASH_FIELD_DST_IP, + SAI_NATIVE_HASH_FIELD_INNER_SRC_IP, + SAI_NATIVE_HASH_FIELD_INNER_DST_IP, + SAI_NATIVE_HASH_FIELD_VLAN_ID, + SAI_NATIVE_HASH_FIELD_IP_PROTOCOL, + SAI_NATIVE_HASH_FIELD_ETHERTYPE, + SAI_NATIVE_HASH_FIELD_L4_SRC_PORT, + SAI_NATIVE_HASH_FIELD_L4_DST_PORT, + SAI_NATIVE_HASH_FIELD_SRC_MAC, + SAI_NATIVE_HASH_FIELD_DST_MAC, + SAI_NATIVE_HASH_FIELD_IN_PORT +}; + +const sai_attr_metadata_t sai_hash_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_HASH, + .attrid = SAI_HASH_ATTR_NATIVE_FIELD_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_native_hash_field_t ), + .enumallowedvalues = ENUM_VALUES ( sai_native_hash_field_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_HASH, + .attrid = SAI_HASH_ATTR_UDF_GROUP_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_UDF_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_hash_attr_metadata_count = sizeof(sai_hash_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_hostintf.cpp b/meta/sai_meta_hostintf.cpp new file mode 100644 index 000000000000..850fcfc40b79 --- /dev/null +++ b/meta/sai_meta_hostintf.cpp @@ -0,0 +1,301 @@ +#include "sai_meta.h" + +// NOTE: user defined traps are subject to be removed + +// METADATA for SAI_OBJECT_TYPE_HOST_INTERFACE + +DEFINE_ENUM_VALUES(sai_hostif_type_t) +{ + SAI_HOSTIF_TYPE_NETDEV, + SAI_HOSTIF_TYPE_FD +}; + +DEFINE_ENUM_VALUES(sai_hostif_trap_id_t) +{ + SAI_HOSTIF_TRAP_ID_STP, + SAI_HOSTIF_TRAP_ID_LACP, + SAI_HOSTIF_TRAP_ID_EAPOL, + SAI_HOSTIF_TRAP_ID_LLDP, + SAI_HOSTIF_TRAP_ID_PVRST, + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_QUERY, + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_LEAVE, + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V1_REPORT, + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT, + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V3_REPORT, + SAI_HOSTIF_TRAP_ID_SAMPLEPACKET, + SAI_HOSTIF_TRAP_ID_ARP_REQUEST, + SAI_HOSTIF_TRAP_ID_ARP_RESPONSE, + SAI_HOSTIF_TRAP_ID_DHCP, + SAI_HOSTIF_TRAP_ID_OSPF, + SAI_HOSTIF_TRAP_ID_PIM, + SAI_HOSTIF_TRAP_ID_VRRP, + SAI_HOSTIF_TRAP_ID_BGP, + SAI_HOSTIF_TRAP_ID_DHCPV6, + SAI_HOSTIF_TRAP_ID_OSPFV6, + SAI_HOSTIF_TRAP_ID_VRRPV6, + SAI_HOSTIF_TRAP_ID_BGPV6, + SAI_HOSTIF_TRAP_ID_IPV6_NEIGHBOR_DISCOVERY, + SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_V2, + SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_REPORT, + SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_DONE, + SAI_HOSTIF_TRAP_ID_MLD_V2_REPORT, + SAI_HOSTIF_TRAP_ID_IP2ME, + SAI_HOSTIF_TRAP_ID_SSH, + SAI_HOSTIF_TRAP_ID_SNMP, + SAI_HOSTIF_TRAP_ID_L3_MTU_ERROR, + SAI_HOSTIF_TRAP_ID_TTL_ERROR +}; + +DEFINE_ENUM_VALUES(sai_hostif_trap_channel_t) +{ + SAI_HOSTIF_TRAP_CHANNEL_FD, + SAI_HOSTIF_TRAP_CHANNEL_CB, + SAI_HOSTIF_TRAP_CHANNEL_NETDEV +}; + +const sai_attr_metadata_t sai_hostintf_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_HOST_INTERFACE, + .attrid = SAI_HOSTIF_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_hostif_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_hostif_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_HOST_INTERFACE, + .attrid = SAI_HOSTIF_ATTR_RIF_OR_PORT_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_ROUTER_INTERFACE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_HOSTIF_ATTR_TYPE, SAI_HOSTIF_TYPE_NETDEV ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_HOST_INTERFACE, + .attrid = SAI_HOSTIF_ATTR_NAME, + .serializationtype = SAI_SERIALIZATION_TYPE_CHARDATA, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_HOSTIF_ATTR_TYPE, SAI_HOSTIF_TYPE_NETDEV ) }, + + // TODO extra logic on name validation is needed + }, + + { + .objecttype = SAI_OBJECT_TYPE_HOST_INTERFACE, + .attrid = SAI_HOSTIF_ATTR_OPER_STATUS, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_hostintf_attr_metadata_count = sizeof(sai_hostintf_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_TRAP_GROUP + +const sai_attr_metadata_t sai_hostintf_trap_group_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_TRAP_GROUP, + .attrid = SAI_HOSTIF_TRAP_GROUP_ATTR_ADMIN_STATE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = true }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TRAP_GROUP, + .attrid = SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO this can be tricky since this QUEUE is queue INDEX + // indirect depenency, by default there are 8 queues, but + // user can create extra one, so there may be 10, and what + // happens when this points to queue 10 and user remove this queue? + // on queue remove we should queue index on trap group and + // not allow to remove then + }, + + { + .objecttype = SAI_OBJECT_TYPE_TRAP_GROUP, + .attrid = SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_POLICER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_hostintf_trap_group_attr_metadata_count = sizeof(sai_hostintf_trap_group_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_TRAP + +const sai_attr_metadata_t sai_hostintf_trap_attr_metadata[] = { + + //{ + // .objecttype = SAI_OBJECT_TYPE_TRAP, + // .attrid = SAI_HOSTIF_TRAP_ATTR_TRAP_TYPE, + // .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET | SAI_ATTR_FLAGS_KEY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + // .defaultvalue = { }, + // .enumtypestr = StringifyEnum ( sai_hostif_trap_type_t ), + // .enumallowedvalues = ENUM_VALUES ( sai_hostif_trap_type_f ), + // .conditions = { }, + //}, + + { + .objecttype = SAI_OBJECT_TYPE_TRAP, + .attrid = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, // TODO check if this is right one + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + // TODO below attributes are valid only when: + // (those are not mandatory, but only valid, default action is assumed) + // SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION == SAI_PACKET_ACTION_TRAP or + // SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION == SAI_PACKET_ACTION_LOG + + // { COND_ENUM ( SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION, SAI_PACKET_ACTION_TRAP ) }, + // { COND_ENUM ( SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION, SAI_PACKET_ACTION_LOG ) }, + + // if attribute is not set, but is "valid" then default value is used + + { + .objecttype = SAI_OBJECT_TYPE_TRAP, + .attrid = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO default value is provided by SAI_SWITCH_ATTR_ACL_ENTRY_MINIMUM_PRIORITY + }, + + { + .objecttype = SAI_OBJECT_TYPE_TRAP, + .attrid = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, // mandatory + crete_only + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_HOSTIF_TRAP_CHANNEL_CB }, + .enumtypestr = StringifyEnum ( sai_hostif_trap_channel_t ), + .enumallowedvalues = ENUM_VALUES ( sai_hostif_trap_channel_t ), + .conditions = { }, + }, + + //{ + // .objecttype = SAI_OBJECT_TYPE_TRAP, + // .attrid = SAI_HOSTIF_TRAP_ATTR_FD, + // .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + // .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, // TODO what kind of object ? + // .allownullobjectid = true, + // .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + // .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { } + + // TODO condition is more complex here since trap/log and this (extra logic needed) + // // * Valid only when SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL == SAI_HOSTIF_TRAP_CHANNEL_FD + // // * Must be set before set SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL to SAI_HOSTIF_TRAP_CHANNEL_FD + //}, + + { + .objecttype = SAI_OBJECT_TYPE_TRAP, + .attrid = SAI_HOSTIF_TRAP_ATTR_PORT_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, // TODO default is to all ports + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { } + + // TODO extra logic is needed here since default is to all ports, we need more explanation + }, + + { + .objecttype = SAI_OBJECT_TYPE_TRAP, + .attrid = SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, // create only ? + .allowedobjecttypes = { SAI_OBJECT_TYPE_TRAP_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { } + + // TODO default value points to SAI_SWITCH_ATTR_DEFAULT_TRAP_GROUP + + // TODO should null point to default trap group or should actual explicit object should be used + // TODO extra logic is needed here + }, +}; + +const size_t sai_hostintf_trap_attr_metadata_count = sizeof(sai_hostintf_trap_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_lag.cpp b/meta/sai_meta_lag.cpp new file mode 100644 index 000000000000..b1c98866678d --- /dev/null +++ b/meta/sai_meta_lag.cpp @@ -0,0 +1,85 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_LAG + +const sai_attr_metadata_t sai_lag_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_LAG, + .attrid = SAI_LAG_ATTR_PORT_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_LAG_MEMBER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_lag_attr_metadata_count = sizeof(sai_lag_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_LAG_MEMBER + +const sai_attr_metadata_t sai_lag_member_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_LAG_MEMBER, + .attrid = SAI_LAG_MEMBER_ATTR_LAG_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_LAG }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_LAG_MEMBER, + .attrid = SAI_LAG_MEMBER_ATTR_PORT_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_LAG_MEMBER, + .attrid = SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_LAG_MEMBER, + .attrid = SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_lag_member_attr_metadata_count = sizeof(sai_lag_member_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_mirror.cpp b/meta/sai_meta_mirror.cpp new file mode 100644 index 000000000000..2f9302deb75e --- /dev/null +++ b/meta/sai_meta_mirror.cpp @@ -0,0 +1,289 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_MIRROR + +DEFINE_ENUM_VALUES(sai_mirror_type_t) +{ + SAI_MIRROR_TYPE_LOCAL, + SAI_MIRROR_TYPE_REMOTE, + SAI_MIRROR_TYPE_ENHANCED_REMOTE +}; + +DEFINE_ENUM_VALUES(sai_erspan_encapsulation_type_t) +{ + SAI_MIRROR_L3_GRE_TUNNEL +}; + +const sai_attr_metadata_t sai_mirror_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_mirror_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_mirror_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_MONITOR_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + /*{ + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_TRUNCATE_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u16 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + },*/ + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_TC, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // TODO below attributes valid only when RSPAN or ERSPAN + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_VLAN_TPID, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ), + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_REMOTE), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ), + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_REMOTE), + }, + + // TODO extra logic will be required to check if vlan exists + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_VLAN_PRI, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ), + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_REMOTE), + }, + + // TODO extra logic will be required to check if vlan exists + }, + + /*{ + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_VLAN_CFI, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ), + COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_REMOTE), + }, + },*/ + + // TODO valid only for ERSPAN + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_erspan_encapsulation_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_erspan_encapsulation_type_t ), + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + + // TODO extra logic to check version + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_TOS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_TTL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 255 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO valid only when + // .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + // TODO what happen when we change IP header version 4 vs 6 and + // don't change src/dst ip version? + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_SRC_IP_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_IP_ADDRESS, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_DST_IP_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_IP_ADDRESS, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_SRC_MAC_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_MAC, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_DST_MAC_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_MAC, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_MIRROR, + .attrid = SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_MIRROR_SESSION_ATTR_TYPE, SAI_MIRROR_TYPE_ENHANCED_REMOTE ) }, + + // TODO extra logic for checking value may be needed + }, + +}; + +const size_t sai_mirror_attr_metadata_count = sizeof(sai_mirror_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_neighbor.cpp b/meta/sai_meta_neighbor.cpp new file mode 100644 index 000000000000..2e362da66d8b --- /dev/null +++ b/meta/sai_meta_neighbor.cpp @@ -0,0 +1,66 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_NEIGHBOR + +const sai_attr_metadata_t sai_neighbor_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_NEIGHBOR, + .attrid = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_MAC, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEIGHBOR, + .attrid = SAI_NEIGHBOR_ATTR_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEIGHBOR, + .attrid = SAI_NEIGHBOR_ATTR_NO_HOST_ROUTE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEIGHBOR, + .attrid = SAI_NEIGHBOR_ATTR_META_DATA, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO value range is SAI_SWITCH_ATTR_NEIGHBOR_DST_USER_META_DATA_RANGE + }, +}; + +const size_t sai_neighbor_attr_metadata_count = sizeof(sai_neighbor_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_nexthop.cpp b/meta/sai_meta_nexthop.cpp new file mode 100644 index 000000000000..da256f3a92ce --- /dev/null +++ b/meta/sai_meta_nexthop.cpp @@ -0,0 +1,71 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_NEXT_HOP + +DEFINE_ENUM_VALUES(sai_next_hop_type_t) +{ + SAI_NEXT_HOP_IP, + SAI_NEXT_HOP_TUNNEL_ENCAP, + // SAI_NEXT_HOP_MPLS, // not supported yet +}; + +const sai_attr_metadata_t sai_nexthop_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP, + .attrid = SAI_NEXT_HOP_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_next_hop_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_next_hop_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP, + .attrid = SAI_NEXT_HOP_ATTR_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_IP_ADDRESS, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_NEXT_HOP_ATTR_TYPE, SAI_NEXT_HOP_IP ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP, + .attrid = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ROUTER_INTERFACE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP, + .attrid = SAI_NEXT_HOP_ATTR_TUNNEL_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_TUNNEL }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_NEXT_HOP_ATTR_TYPE, SAI_NEXT_HOP_TUNNEL_ENCAP ) }, + }, +}; + +const size_t sai_nexthop_attr_metadata_count = sizeof(sai_nexthop_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_nexthopgroup.cpp b/meta/sai_meta_nexthopgroup.cpp new file mode 100644 index 000000000000..f30cad627d38 --- /dev/null +++ b/meta/sai_meta_nexthopgroup.cpp @@ -0,0 +1,55 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_NEXT_HOP_GROUP + +DEFINE_ENUM_VALUES(sai_next_hop_group_type_t) +{ + SAI_NEXT_HOP_GROUP_ECMP +}; + +const sai_attr_metadata_t sai_nexthopgroup_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP_GROUP, + .attrid = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP_GROUP, + .attrid = SAI_NEXT_HOP_GROUP_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_next_hop_group_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_next_hop_group_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_NEXT_HOP_GROUP, + .attrid = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_NEXT_HOP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_nexthopgroup_attr_metadata_count = sizeof(sai_nexthopgroup_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_policer.cpp b/meta/sai_meta_policer.cpp new file mode 100644 index 000000000000..fb58736b69c4 --- /dev/null +++ b/meta/sai_meta_policer.cpp @@ -0,0 +1,181 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_POLICER + +DEFINE_ENUM_VALUES(sai_meter_type_t) +{ + SAI_METER_TYPE_PACKETS, + SAI_METER_TYPE_BYTES +}; + +DEFINE_ENUM_VALUES(sai_policer_mode_t) +{ + SAI_POLICER_MODE_Sr_TCM, + SAI_POLICER_MODE_Tr_TCM, + SAI_POLICER_MODE_STORM_CONTROL +}; + +DEFINE_ENUM_VALUES(sai_policer_color_source_t) +{ + SAI_POLICER_COLOR_SOURCE_BLIND, + SAI_POLICER_COLOR_SOURCE_AWARE +}; + +const sai_attr_metadata_t sai_policer_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_METER_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_meter_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_meter_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_policer_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_policer_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_COLOR_SOURCE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_POLICER_COLOR_SOURCE_AWARE }, + .enumtypestr = StringifyEnum ( sai_policer_color_source_t ), + .enumallowedvalues = ENUM_VALUES ( sai_policer_color_source_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_CBS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_CIR, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_PBS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_PIR, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_POLICER_ATTR_METER_TYPE, SAI_POLICER_MODE_Tr_TCM ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_GREEN_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_YELLOW_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_RED_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_POLICER, + .attrid = SAI_POLICER_ATTR_ENABLE_COUNTER_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, +}; + +const size_t sai_policer_attr_metadata_count = sizeof(sai_policer_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_port.cpp b/meta/sai_meta_port.cpp new file mode 100644 index 000000000000..33832c5577e1 --- /dev/null +++ b/meta/sai_meta_port.cpp @@ -0,0 +1,1194 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_PORT + +DEFINE_ENUM_VALUES(sai_port_type_t) +{ + SAI_PORT_TYPE_LOGICAL, + SAI_PORT_TYPE_CPU +}; + +DEFINE_ENUM_VALUES(sai_port_oper_status_t) +{ + SAI_PORT_OPER_STATUS_UNKNOWN, + SAI_PORT_OPER_STATUS_UP, + SAI_PORT_OPER_STATUS_DOWN, + SAI_PORT_OPER_STATUS_TESTING, + SAI_PORT_OPER_STATUS_NOT_PRESENT +}; + +DEFINE_ENUM_VALUES(sai_port_breakout_mode_type_t) +{ + SAI_PORT_BREAKOUT_MODE_1_LANE, + SAI_PORT_BREAKOUT_MODE_2_LANE, + SAI_PORT_BREAKOUT_MODE_4_LANE +}; + +DEFINE_ENUM_VALUES(sai_port_flow_control_mode_t) +{ + SAI_PORT_FLOW_CONTROL_DISABLE, + SAI_PORT_FLOW_CONTROL_TX_ONLY, + SAI_PORT_FLOW_CONTROL_RX_ONLY, + SAI_PORT_FLOW_CONTROL_BOTH_ENABLE +}; + +DEFINE_ENUM_VALUES(sai_port_media_type_t) +{ + SAI_PORT_MEDIA_TYPE_NOT_PRESENT, + SAI_PORT_MEDIA_TYPE_UNKNONWN, + //SAI_PORT_MEDIA_TYPE_FIBER, + //SAI_PORT_MEDIA_TYPE_COPPER +}; + +DEFINE_ENUM_VALUES(sai_port_internal_loopback_mode_t) +{ + SAI_PORT_INTERNAL_LOOPBACK_NONE, + SAI_PORT_INTERNAL_LOOPBACK_PHY, + SAI_PORT_INTERNAL_LOOPBACK_MAC +}; + +DEFINE_ENUM_VALUES(sai_port_fdb_learning_mode_t) +{ + SAI_PORT_LEARN_MODE_DROP, + SAI_PORT_LEARN_MODE_DISABLE, + SAI_PORT_LEARN_MODE_HW, + SAI_PORT_LEARN_MODE_CPU_TRAP, + SAI_PORT_LEARN_MODE_CPU_LOG +}; + +const sai_attr_metadata_t sai_port_attr_metadata[] = { + + // READ-ONLY + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_OPER_STATUS, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_oper_status_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_oper_status_t ), + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_BREAKOUT_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_CURRENT_BREAKOUT_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_breakout_mode_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_breakout_mode_type_t ), + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_NUMBER_OF_QUEUES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_QUEUE_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QUEUE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SCHEDULER_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +/* + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_HALF_DUPLEX_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_FLOW_CONTROL, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_flow_control_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_flow_control_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_ASYMMETRIC_PAUSE_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SUPPORTED_MEDIA_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_media_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_media_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_SUPPORTED_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_SUPPORTED_HALF_DUPLEX_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_SUPPORTED_AUTO_NEG_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_SUPPORTED_FLOW_CONTROL, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_flow_control_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_flow_control_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_SUPPORTED_ASYMMETRIC_PAUSE_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_SUPPORTED_MEDIA_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_media_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_media_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_ADVERTISED_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_ADVERTISED_HALF_DUPLEX_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_ADVERTISED_AUTO_NEG_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_ADVERTISED_FLOW_CONTROL, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_flow_control_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_flow_control_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_ADVERTISED_ASYMMETRIC_PAUSE_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_REMOTE_ADVERTISED_MEDIA_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_port_media_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_media_type_t ), + .conditions = { }, + }, +*/ + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_NUMBER_OF_PRIORITY_GROUPS, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_PRIORITY_GROUP_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PRIORITY_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + // READ-WRITE + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_HW_LANE_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_SPEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_FULL_DUPLEX_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = true }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_AUTO_NEG_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_ADMIN_STATE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_MEDIA_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PORT_MEDIA_TYPE_NOT_PRESENT }, + .enumtypestr = StringifyEnum ( sai_port_media_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_media_type_t ), + .conditions = { }, + }, + + // TODO what is default value ? + + // { + // .objecttype = SAI_OBJECT_TYPE_PORT, + // .attrid = SAI_PORT_ATTR_ADVERTISED_SPEED, + // .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvalue = { }, // TODO default + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { }, + // }, + + // { + // .objecttype = SAI_OBJECT_TYPE_PORT, + // .attrid = SAI_PORT_ATTR_ADVERTISED_HALF_DUPLEX_SPEED, + // .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvalue = { }, // TODO default + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { }, + // }, + + // { + // .objecttype = SAI_OBJECT_TYPE_PORT, + // .attrid = SAI_PORT_ATTR_ADVERTISED_AUTO_NEG_MODE, + // .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvalue = { }, // TODO default + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { }, + // }, + + // { + // .objecttype = SAI_OBJECT_TYPE_PORT, + // .attrid = SAI_PORT_ATTR_ADVERTISED_FLOW_CONTROL, + // .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvalue = { }, // TODO default + // .enumtypestr = StringifyEnum ( sai_port_flow_control_mode_t ), + // .enumallowedvalues = ENUM_VALUES ( sai_port_flow_control_mode_t ), + // .conditions = { }, + // }, + + // { + // .objecttype = SAI_OBJECT_TYPE_PORT, + // .attrid = SAI_PORT_ATTR_ADVERTISED_ASYMMETRIC_PAUSE_MODE, + // .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvalue = { }, // TODO default + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { }, + // }, + + // { + // .objecttype = SAI_OBJECT_TYPE_PORT, + // .attrid = SAI_PORT_ATTR_ADVERTISED_MEDIA_TYPE, + // .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + // .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + // .allowedobjecttypes = { }, + // .allownullobjectid = false, + // .defaultvalue = { }, + // .enumtypestr = StringifyEnum ( sai_port_media_type_t ), + // .enumallowedvalues = ENUM_VALUES ( sai_port_media_type_t ), + // .conditions = { }, + // }, + + // Continue + + // TODO this is inconsistent, since we have vlan member, so why this param is read/write? + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_PORT_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u16 = DEFAULT_VLAN_NUMBER }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO extra logic needed to check if vlan exist + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_DEFAULT_VLAN_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_INGRESS_FILTERING, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_DROP_UNTAGGED, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_DROP_TAGGED, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_INTERNAL_LOOPBACK, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PORT_INTERNAL_LOOPBACK_NONE }, + .enumtypestr = StringifyEnum ( sai_port_internal_loopback_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_internal_loopback_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_FDB_LEARNING, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PORT_LEARN_MODE_HW }, + .enumtypestr = StringifyEnum ( sai_port_fdb_learning_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_fdb_learning_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_UPDATE_DSCP, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_MTU, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = DEFAULT_LAYER2_FRAME_SIZE }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO extra check for range will be needed + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_FLOOD_STORM_CONTROL_POLICER_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_POLICER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // TODO switch may have default value assigned + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_BROADCAST_STORM_CONTROL_POLICER_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_POLICER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // TODO switch may have default value assigned + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_MULTICAST_STORM_CONTROL_POLICER_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_POLICER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // TODO switch may have default value assigned + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_GLOBAL_FLOW_CONTROL, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PORT_FLOW_CONTROL_DISABLE }, + .enumtypestr = StringifyEnum ( sai_port_flow_control_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_port_flow_control_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_MAX_LEARNED_ADDRESSES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_FDB_LEARNING_LIMIT_VIOLATION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_DROP }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_INGRESS_MIRROR_SESSION, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_MIRROR }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_EGRESS_MIRROR_SESSION, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_MIRROR }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_INGRESS_SAMPLEPACKET_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SAMPLEPACKET }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_EGRESS_SAMPLEPACKET_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SAMPLEPACKET }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_POLICER_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_POLICER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // TODO by default port may have policer assigned ? + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // QOS + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_DEFAULT_TC, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_DOT1P_TO_TC_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_DOT1P_TO_COLOR_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_DSCP_TO_COLOR_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_TC_TO_PRIORITY_GROUP_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_PFC_PRIORITY_TO_QUEUE_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_WRED_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_WRED }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_SCHEDULER_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SCHEDULER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // TODO by default port may have scheduler + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_INGRESS_BUFFER_PROFILE_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_BUFFER_PROFILE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, // TODO by default port may have ingress buffer profile + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_QOS_EGRESS_BUFFER_PROFILE_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_BUFFER_PROFILE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, // TODO by default port may have egress buffer profile + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_META_DATA, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + /*{ + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_EGRESS_BLOCK_PORT_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_BUFFER_PROFILE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_PORT, + .attrid = SAI_PORT_ATTR_HW_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + },*/ +}; + +const size_t sai_port_attr_metadata_count = sizeof(sai_port_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_qosmaps.cpp b/meta/sai_meta_qosmaps.cpp new file mode 100644 index 000000000000..d6d7ac83e99c --- /dev/null +++ b/meta/sai_meta_qosmaps.cpp @@ -0,0 +1,57 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_QOS_MAPS + +DEFINE_ENUM_VALUES(sai_qos_map_type_t) +{ + SAI_QOS_MAP_DOT1P_TO_TC, + SAI_QOS_MAP_DOT1P_TO_COLOR, + SAI_QOS_MAP_DSCP_TO_TC, + SAI_QOS_MAP_DSCP_TO_COLOR, + SAI_QOS_MAP_TC_TO_QUEUE, + SAI_QOS_MAP_TC_AND_COLOR_TO_DSCP, + SAI_QOS_MAP_TC_AND_COLOR_TO_DOT1P, + SAI_QOS_MAP_TC_TO_PRIORITY_GROUP, + SAI_QOS_MAP_PFC_PRIORITY_TO_PRIORITY_GROUP, + SAI_QOS_MAP_PFC_PRIORITY_TO_QUEUE +}; + +const sai_attr_metadata_t sai_qos_maps_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_QOS_MAPS, + .attrid = SAI_QOS_MAP_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_qos_map_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_qos_map_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_QOS_MAPS, + .attrid = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_QOS_MAP_LIST, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO all defaults? what means all? + // TODO special handling is needed + // * Defaults: + // * All Dot1p/DSCP maps to traffic class 0 + // * All Dot1p/DSCP maps to color SAI_PACKET_COLOR_GREEN + // * All traffic class maps to queue 0. + }, +}; + +const size_t sai_qos_maps_attr_metadata_count = sizeof(sai_qos_maps_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_queue.cpp b/meta/sai_meta_queue.cpp new file mode 100644 index 000000000000..bd93e2eaa90a --- /dev/null +++ b/meta/sai_meta_queue.cpp @@ -0,0 +1,92 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_QUEUE + +#ifndef SAI_QUEUE_ATTR_INDEX +#define SAI_QUEUE_ATTR_INDEX 0x100 // TODO remove on new SAI +#endif + +DEFINE_ENUM_VALUES(sai_queue_type_t) +{ + SAI_QUEUE_TYPE_ALL, + SAI_QUEUE_TYPE_UNICAST, + SAI_QUEUE_TYPE_MULTICAST +}; + +const sai_attr_metadata_t sai_queue_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_QUEUE, + .attrid = SAI_QUEUE_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_queue_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_queue_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_QUEUE, + .attrid = SAI_QUEUE_ATTR_INDEX, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + + .conditions = { }, + + // TODO extra validation may be needed on queue index + }, + + { + .objecttype = SAI_OBJECT_TYPE_QUEUE, + .attrid = SAI_QUEUE_ATTR_WRED_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_WRED }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // there may be default wred + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_QUEUE, + .attrid = SAI_QUEUE_ATTR_BUFFER_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_BUFFER_PROFILE }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // there may be default wred + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_QUEUE, + .attrid = SAI_QUEUE_ATTR_SCHEDULER_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SCHEDULER }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, // there may be default wred + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_queue_attr_metadata_count = sizeof(sai_queue_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_route.cpp b/meta/sai_meta_route.cpp new file mode 100644 index 000000000000..48d0ef6086dc --- /dev/null +++ b/meta/sai_meta_route.cpp @@ -0,0 +1,68 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_ROUTE + +const sai_attr_metadata_t sai_route_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_ROUTE, + .attrid = SAI_ROUTE_ATTR_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTE, + .attrid = SAI_ROUTE_ATTR_TRAP_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTE, + .attrid = SAI_ROUTE_ATTR_NEXT_HOP_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_NEXT_HOP, SAI_OBJECT_TYPE_NEXT_HOP_GROUP, SAI_OBJECT_TYPE_ROUTER_INTERFACE, SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO may require some extra logic for CPU port + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTE, + .attrid = SAI_ROUTE_ATTR_META_DATA, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO range in SAI_SWITCH_ATTR_ROUTE_USER_META_DATA_RANGE + }, +}; + +const size_t sai_route_attr_metadata_count = sizeof(sai_route_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_router.cpp b/meta/sai_meta_router.cpp new file mode 100644 index 000000000000..4d18d6e7bc44 --- /dev/null +++ b/meta/sai_meta_router.cpp @@ -0,0 +1,83 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_VIRTUAL_ROUTER + +const sai_attr_metadata_t sai_router_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, + .attrid = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = true }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, + .attrid = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V6_STATE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = true }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, + .attrid = SAI_VIRTUAL_ROUTER_ATTR_SRC_MAC_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO equal to the SAI_SWITCH_ATTR_SRC_MAC_ADDRESS by default + // when not specified it will use default mac address which is swich default + // which is writtable and can be changed + // TODO then metadata sanity must check that this attrib exist, is readonly and + }, + + { + .objecttype = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, + .attrid = SAI_VIRTUAL_ROUTER_ATTR_VIOLATION_TTL1_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_TRAP }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, + .attrid = SAI_VIRTUAL_ROUTER_ATTR_VIOLATION_IP_OPTIONS, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_TRAP }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, +}; + +const size_t sai_router_attr_metadata_count = sizeof(sai_router_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_routerintf.cpp b/meta/sai_meta_routerintf.cpp new file mode 100644 index 000000000000..40adaaae7d96 --- /dev/null +++ b/meta/sai_meta_routerintf.cpp @@ -0,0 +1,151 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_ROUTER_INTERFACE + +DEFINE_ENUM_VALUES(sai_router_interface_type_t) +{ + SAI_ROUTER_INTERFACE_TYPE_PORT, + SAI_ROUTER_INTERFACE_TYPE_VLAN, + SAI_ROUTER_INTERFACE_TYPE_LOOPBACK +}; + +const sai_attr_metadata_t sai_routerintf_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_VIRTUAL_ROUTER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_router_interface_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_router_interface_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_PORT_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_LAG }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_ROUTER_INTERFACE_ATTR_TYPE, SAI_ROUTER_INTERFACE_TYPE_PORT ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_ROUTER_INTERFACE_ATTR_TYPE, SAI_ROUTER_INTERFACE_TYPE_VLAN ) }, + + // TODO extra check needed if vlan existsm and increase reference then + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { } + + // TODO equal to the SAI_SWITCH_ATTR_SRC_MAC_ADDRESS by default + // we need a way to provide attr type and attr id, type must match + + // TODO extra check: not valid when SAI_ROUTER_INTERFACE_ATTR_TYPE == SAI_ROUTER_INTERFACE_TYPE_LOOPBACK) + // or valid only when: + // { COND_ENUM ( SAI_ROUTER_INTERFACE_ATTR_TYPE, SAI_ROUTER_INTERFACE_TYPE_VLAN ) }, + // { COND_ENUM ( SAI_ROUTER_INTERFACE_ATTR_TYPE, SAI_ROUTER_INTERFACE_TYPE_PORT ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = true }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { } + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = true }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { } + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_MTU, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = DEFAULT_LAYER2_FRAME_SIZE }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { } + }, + + { + .objecttype = SAI_OBJECT_TYPE_ROUTER_INTERFACE, + .attrid = SAI_ROUTER_INTERFACE_ATTR_NEIGHBOR_MISS_PACKET_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_TRAP }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { } + }, +}; + +const size_t sai_routerintf_attr_metadata_count = sizeof(sai_routerintf_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_samplepacket.cpp b/meta/sai_meta_samplepacket.cpp new file mode 100644 index 000000000000..75faea05c2da --- /dev/null +++ b/meta/sai_meta_samplepacket.cpp @@ -0,0 +1,61 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_SAMPLEPACKET + +DEFINE_ENUM_VALUES(sai_samplepacket_type_t) +{ + SAI_SAMPLEPACKET_SLOW_PATH +}; + +DEFINE_ENUM_VALUES(sai_samplepacket_mode_t) +{ + //SAI_SAMPLEPACKET_MODE_EXCLUSIVE, + //SAI_SAMPLEPACKET_MODE_SHARED +}; + +const sai_attr_metadata_t sai_samplepacket_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_SAMPLEPACKET, + .attrid = SAI_SAMPLEPACKET_ATTR_SAMPLE_RATE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SAMPLEPACKET, + .attrid = SAI_SAMPLEPACKET_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_SAMPLEPACKET_SLOW_PATH }, + .enumtypestr = StringifyEnum ( sai_samplepacket_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_samplepacket_type_t ), + .conditions = { }, + }, + + /*{ + .objecttype = SAI_OBJECT_TYPE_SAMPLEPACKET, + .attrid = SAI_SAMPLEPACKET_ATTR_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_SAMPLEPACKET_MODE_EXCLUSIVE }, + .enumtypestr = StringifyEnum ( sai_samplepacket_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_samplepacket_mode_t ), + .conditions = { }, + },*/ +}; + +const size_t sai_samplepacket_attr_metadata_count = sizeof(sai_samplepacket_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_sanity.cpp b/meta/sai_meta_sanity.cpp new file mode 100644 index 000000000000..44abf5d5432c --- /dev/null +++ b/meta/sai_meta_sanity.cpp @@ -0,0 +1,1529 @@ +#include "sai_meta.h" +#include + +// TODO needs to be moved to SAI + +// NOTE: since enum is a key we need size, hence HashForEnum +std::unordered_map, HashForEnum> AttributesMetadata; + +// Serialization type name resolve + +std::unordered_map get_serialization_type_map() +{ + std::unordered_map map; + +#define SER_MAP_SET(x) map[(int32_t)SAI_SERIALIZATION_TYPE_ ## x] = # x + + // TODO must be generated from headers + + SER_MAP_SET(BOOL); + SER_MAP_SET(CHARDATA); + SER_MAP_SET(UINT8); + SER_MAP_SET(INT8); + SER_MAP_SET(UINT16); + SER_MAP_SET(INT16); + SER_MAP_SET(UINT32); + SER_MAP_SET(INT32); + SER_MAP_SET(UINT64); + SER_MAP_SET(INT64); + SER_MAP_SET(MAC); + SER_MAP_SET(IP4); + SER_MAP_SET(IP6); + SER_MAP_SET(IP_ADDRESS); + SER_MAP_SET(OBJECT_ID); + SER_MAP_SET(OBJECT_LIST); + SER_MAP_SET(UINT8_LIST); + SER_MAP_SET(INT8_LIST); + SER_MAP_SET(UINT16_LIST); + SER_MAP_SET(INT16_LIST); + SER_MAP_SET(UINT32_LIST); + SER_MAP_SET(INT32_LIST); + SER_MAP_SET(UINT32_RANGE); + SER_MAP_SET(INT32_RANGE); + SER_MAP_SET(VLAN_LIST); + + SER_MAP_SET(ACL_FIELD_DATA_BOOL); + SER_MAP_SET(ACL_FIELD_DATA_UINT8); + SER_MAP_SET(ACL_FIELD_DATA_INT8); + SER_MAP_SET(ACL_FIELD_DATA_UINT16); + SER_MAP_SET(ACL_FIELD_DATA_INT16); + SER_MAP_SET(ACL_FIELD_DATA_INT32); + SER_MAP_SET(ACL_FIELD_DATA_UINT32); + SER_MAP_SET(ACL_FIELD_DATA_MAC); + SER_MAP_SET(ACL_FIELD_DATA_IP4); + SER_MAP_SET(ACL_FIELD_DATA_IP6); + SER_MAP_SET(ACL_FIELD_DATA_OBJECT_ID); + SER_MAP_SET(ACL_FIELD_DATA_OBJECT_LIST); + SER_MAP_SET(ACL_FIELD_DATA_UINT8_LIST); + + SER_MAP_SET(ACL_ACTION_DATA_UINT8); + SER_MAP_SET(ACL_ACTION_DATA_INT8); + SER_MAP_SET(ACL_ACTION_DATA_UINT16); + SER_MAP_SET(ACL_ACTION_DATA_INT16); + SER_MAP_SET(ACL_ACTION_DATA_UINT32); + SER_MAP_SET(ACL_ACTION_DATA_INT32); + SER_MAP_SET(ACL_ACTION_DATA_MAC); + SER_MAP_SET(ACL_ACTION_DATA_IPV4); + SER_MAP_SET(ACL_ACTION_DATA_IPV6); + SER_MAP_SET(ACL_ACTION_DATA_OBJECT_ID); + SER_MAP_SET(ACL_ACTION_DATA_OBJECT_LIST); + + SER_MAP_SET(PORT_BREAKOUT); + SER_MAP_SET(QOS_MAP_LIST); + + return map; +} + +const std::unordered_map g_serialization_type_map = get_serialization_type_map(); + +const char* c_unknown_serialization_type = "UNKNOWN_SERIALIZATION_TYPE"; + +const char* get_serialization_type_name(sai_attr_serialization_type_t s) +{ + auto it = g_serialization_type_map.find((int32_t)s); + + if (it != g_serialization_type_map.end()) + { + return it->second.c_str(); + } + + SWSS_LOG_ERROR("serialization type %d not found in map!", s); + + return c_unknown_serialization_type; +} + +// Object type name resolve + +std::unordered_map get_object_type_map() +{ + std::unordered_map map; + +#define OBJ_MAP_SET(x) map[(int32_t)SAI_OBJECT_TYPE_ ## x] = # x + + // TODO must be generated from headers + + OBJ_MAP_SET(NULL); + OBJ_MAP_SET(PORT); + OBJ_MAP_SET(LAG); + OBJ_MAP_SET(VIRTUAL_ROUTER); + OBJ_MAP_SET(NEXT_HOP); + OBJ_MAP_SET(NEXT_HOP_GROUP); + OBJ_MAP_SET(ROUTER_INTERFACE); + OBJ_MAP_SET(ACL_TABLE); + OBJ_MAP_SET(ACL_ENTRY); + OBJ_MAP_SET(ACL_COUNTER); + OBJ_MAP_SET(ACL_RANGE); + OBJ_MAP_SET(HOST_INTERFACE); + OBJ_MAP_SET(MIRROR); + OBJ_MAP_SET(SAMPLEPACKET); + OBJ_MAP_SET(STP_INSTANCE); + OBJ_MAP_SET(TRAP_GROUP); + OBJ_MAP_SET(ACL_TABLE_GROUP); + OBJ_MAP_SET(POLICER); + OBJ_MAP_SET(WRED); + OBJ_MAP_SET(QOS_MAPS); + OBJ_MAP_SET(QUEUE); + OBJ_MAP_SET(SCHEDULER); + OBJ_MAP_SET(SCHEDULER_GROUP); + OBJ_MAP_SET(BUFFER_POOL); + OBJ_MAP_SET(BUFFER_PROFILE); + OBJ_MAP_SET(PRIORITY_GROUP); + OBJ_MAP_SET(LAG_MEMBER); + OBJ_MAP_SET(HASH); + OBJ_MAP_SET(UDF); + OBJ_MAP_SET(UDF_MATCH); + OBJ_MAP_SET(UDF_GROUP); + OBJ_MAP_SET(FDB); + OBJ_MAP_SET(SWITCH); + OBJ_MAP_SET(TRAP); + OBJ_MAP_SET(TRAP_USER_DEF); + OBJ_MAP_SET(NEIGHBOR); + OBJ_MAP_SET(ROUTE); + OBJ_MAP_SET(VLAN); + OBJ_MAP_SET(VLAN_MEMBER); + OBJ_MAP_SET(PACKET); + OBJ_MAP_SET(TUNNEL_MAP); + OBJ_MAP_SET(TUNNEL); + OBJ_MAP_SET(TUNNEL_TABLE_ENTRY); + OBJ_MAP_SET(MAX); + + return map; +} + +const std::unordered_map g_object_type_map_name = get_object_type_map(); + +const char* c_unknown_object_type = "UNKNOWN_OBJECT_TYPE"; + +const char* get_object_type_name(sai_object_type_t o) +{ + auto it = g_object_type_map_name.find((int32_t)o); + + if (it != g_object_type_map_name.end()) + { + return it->second.c_str(); + } + + SWSS_LOG_ERROR("object type %d not found in map!", o); + + return c_unknown_object_type; +} + +// Attribute name resolve + +std::unordered_map> get_attr_name_map() +{ + std::unordered_map> map; + +#define ATTR_MAP_SET(x,y) map[(int32_t)SAI_OBJECT_TYPE_ ## x][(int32_t)y] = # y + + // TODO must be generated from headers + + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_STAGE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_PRIORITY); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_SIZE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_GROUP_ID); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_STAGE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_PRIORITY); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_SIZE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_GROUP_ID); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_END); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_SRC_IPv6); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_DST_IPv6); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_SRC_MAC); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_DST_MAC); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_SRC_IP); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_DST_IP); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_OUT_PORTS); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IN_PORT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_OUT_PORT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_SRC_PORT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_PRI); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_CFI); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_INNER_VLAN_ID); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_INNER_VLAN_PRI); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_INNER_VLAN_CFI); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_L4_DST_PORT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_DSCP); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ECN); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_TTL); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_TOS); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IP_FLAGS); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IP_TYPE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IP_FRAG); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_IPv6_FLOW_LABEL); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_TC); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ICMP_TYPE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ICMP_CODE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_VLAN_TAGS); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_FDB_DST_USER_META); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ROUTE_DST_USER_META); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_NEIGHBOR_DST_USER_META); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_PORT_USER_META); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_VLAN_USER_META); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ACL_USER_META); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_FDB_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_ROUTE_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_FIELD_RANGE); + ATTR_MAP_SET(ACL_TABLE,SAI_ACL_TABLE_ATTR_ACTION_LIST); + + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_TABLE_ID); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_PRIORITY); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_RANGE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_PACKET_ACTION); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_SRC_IPv6); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_DST_IPv6); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_SRC_MAC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_DST_MAC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_DST_IP); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_PRI); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_CFI); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_PRI); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_CFI); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_L4_SRC_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_L4_DST_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_DSCP); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ECN); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_TTL); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_TOS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IP_FLAGS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IP_TYPE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IP_FRAG); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_IPv6_FLOW_LABEL); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_TC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ICMP_TYPE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ICMP_CODE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_VLAN_TAGS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_FDB_DST_USER_META); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST_USER_META); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_USER_META); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_PORT_USER_META); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_VLAN_USER_META); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ACL_USER_META); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_FDB_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_RANGE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_COUNTER); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_DECREMENT_TTL); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_TC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_TC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_COLOR); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_ID); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_PRI); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_ID); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_PRI); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_MAC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_MAC); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IP); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IP); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IPv6); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IPv6); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_DSCP); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_ECN); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_SRC_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_DST_PORT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_CPU_QUEUE); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_ACL_META_DATA); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_BLOCK_PORT_LIST); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_FDB_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT); + ATTR_MAP_SET(ACL_ENTRY,SAI_ACL_ENTRY_ATTR_ACTION_FLOOD); + + ATTR_MAP_SET(ACL_COUNTER,SAI_ACL_COUNTER_ATTR_TABLE_ID); + ATTR_MAP_SET(ACL_COUNTER,SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT); + ATTR_MAP_SET(ACL_COUNTER,SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT); + ATTR_MAP_SET(ACL_COUNTER,SAI_ACL_COUNTER_ATTR_PACKETS); + ATTR_MAP_SET(ACL_COUNTER,SAI_ACL_COUNTER_ATTR_BYTES); + ATTR_MAP_SET(BUFFER_POOL,SAI_BUFFER_POOL_ATTR_SHARED_SIZE); + ATTR_MAP_SET(BUFFER_POOL,SAI_BUFFER_POOL_ATTR_TYPE); + ATTR_MAP_SET(BUFFER_POOL,SAI_BUFFER_POOL_ATTR_SIZE); + ATTR_MAP_SET(BUFFER_POOL,SAI_BUFFER_POOL_ATTR_TH_MODE); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_POOL_ID); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_TH_MODE); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_XOFF_TH); + ATTR_MAP_SET(BUFFER_PROFILE,SAI_BUFFER_PROFILE_ATTR_XON_TH); + ATTR_MAP_SET(FDB,SAI_FDB_ENTRY_ATTR_TYPE); + ATTR_MAP_SET(FDB,SAI_FDB_ENTRY_ATTR_PORT_ID); + ATTR_MAP_SET(FDB,SAI_FDB_ENTRY_ATTR_PACKET_ACTION); + ATTR_MAP_SET(FDB,SAI_FDB_ENTRY_ATTR_META_DATA); + ATTR_MAP_SET(HASH,SAI_HASH_ATTR_NATIVE_FIELD_LIST); + ATTR_MAP_SET(HASH,SAI_HASH_ATTR_UDF_GROUP_LIST); + ATTR_MAP_SET(HOST_INTERFACE,SAI_HOSTIF_ATTR_TYPE); + ATTR_MAP_SET(HOST_INTERFACE,SAI_HOSTIF_ATTR_RIF_OR_PORT_ID); + ATTR_MAP_SET(HOST_INTERFACE,SAI_HOSTIF_ATTR_NAME); + ATTR_MAP_SET(HOST_INTERFACE,SAI_HOSTIF_ATTR_OPER_STATUS); + ATTR_MAP_SET(TRAP_GROUP,SAI_HOSTIF_TRAP_GROUP_ATTR_ADMIN_STATE); + ATTR_MAP_SET(TRAP_GROUP,SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE); + ATTR_MAP_SET(TRAP_GROUP,SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER); + ATTR_MAP_SET(TRAP,SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION); + ATTR_MAP_SET(TRAP,SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY); + ATTR_MAP_SET(TRAP,SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL); + ATTR_MAP_SET(TRAP,SAI_HOSTIF_TRAP_ATTR_PORT_LIST); + ATTR_MAP_SET(TRAP,SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP); + ATTR_MAP_SET(LAG,SAI_LAG_ATTR_PORT_LIST); + ATTR_MAP_SET(LAG_MEMBER,SAI_LAG_MEMBER_ATTR_LAG_ID); + ATTR_MAP_SET(LAG_MEMBER,SAI_LAG_MEMBER_ATTR_PORT_ID); + ATTR_MAP_SET(LAG_MEMBER,SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE); + ATTR_MAP_SET(LAG_MEMBER,SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_TYPE); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_MONITOR_PORT); + //ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_TRUNCATE_SIZE); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_TC); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_VLAN_TPID); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_VLAN_ID); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_VLAN_PRI); + //ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_VLAN_CFI); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_TOS); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_TTL); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_SRC_IP_ADDRESS); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_DST_IP_ADDRESS); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_SRC_MAC_ADDRESS); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_DST_MAC_ADDRESS); + ATTR_MAP_SET(MIRROR,SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE); + ATTR_MAP_SET(NEIGHBOR,SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS); + ATTR_MAP_SET(NEIGHBOR,SAI_NEIGHBOR_ATTR_PACKET_ACTION); + ATTR_MAP_SET(NEIGHBOR,SAI_NEIGHBOR_ATTR_NO_HOST_ROUTE); + ATTR_MAP_SET(NEIGHBOR,SAI_NEIGHBOR_ATTR_META_DATA); + ATTR_MAP_SET(NEXT_HOP,SAI_NEXT_HOP_ATTR_TYPE); + ATTR_MAP_SET(NEXT_HOP,SAI_NEXT_HOP_ATTR_IP); + ATTR_MAP_SET(NEXT_HOP,SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID); + ATTR_MAP_SET(NEXT_HOP,SAI_NEXT_HOP_ATTR_TUNNEL_ID); + ATTR_MAP_SET(NEXT_HOP_GROUP,SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT); + ATTR_MAP_SET(NEXT_HOP_GROUP,SAI_NEXT_HOP_GROUP_ATTR_TYPE); + ATTR_MAP_SET(NEXT_HOP_GROUP,SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_METER_TYPE); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_MODE); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_COLOR_SOURCE); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_CBS); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_CIR); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_PBS); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_PIR); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_GREEN_PACKET_ACTION); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_YELLOW_PACKET_ACTION); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_RED_PACKET_ACTION); + ATTR_MAP_SET(POLICER,SAI_POLICER_ATTR_ENABLE_COUNTER_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_TYPE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_OPER_STATUS); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_BREAKOUT_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_CURRENT_BREAKOUT_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_NUMBER_OF_QUEUES); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_QUEUE_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_SPEED); +/* + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_HALF_DUPLEX_SPEED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_FLOW_CONTROL); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_ASYMMETRIC_PAUSE_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SUPPORTED_MEDIA_TYPE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_SUPPORTED_SPEED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_SUPPORTED_HALF_DUPLEX_SPEED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_SUPPORTED_AUTO_NEG_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_SUPPORTED_FLOW_CONTROL); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_SUPPORTED_ASYMMETRIC_PAUSE_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_SUPPORTED_MEDIA_TYPE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_ADVERTISED_SPEED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_ADVERTISED_HALF_DUPLEX_SPEED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_ADVERTISED_AUTO_NEG_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_ADVERTISED_FLOW_CONTROL); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_ADVERTISED_ASYMMETRIC_PAUSE_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_REMOTE_ADVERTISED_MEDIA_TYPE); +*/ + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_NUMBER_OF_PRIORITY_GROUPS); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_PRIORITY_GROUP_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_HW_LANE_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_SPEED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_FULL_DUPLEX_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_AUTO_NEG_MODE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_ADMIN_STATE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_MEDIA_TYPE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_PORT_VLAN_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_DEFAULT_VLAN_PRIORITY); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_INGRESS_FILTERING); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_DROP_UNTAGGED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_DROP_TAGGED); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_INTERNAL_LOOPBACK); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_UPDATE_DSCP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_MTU); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_FLOOD_STORM_CONTROL_POLICER_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_BROADCAST_STORM_CONTROL_POLICER_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_MULTICAST_STORM_CONTROL_POLICER_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_GLOBAL_FLOW_CONTROL); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_MAX_LEARNED_ADDRESSES); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_FDB_LEARNING_LIMIT_VIOLATION); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_INGRESS_MIRROR_SESSION); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_EGRESS_MIRROR_SESSION); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_INGRESS_SAMPLEPACKET_ENABLE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_EGRESS_SAMPLEPACKET_ENABLE); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_POLICER_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_DEFAULT_TC); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_DOT1P_TO_TC_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_DOT1P_TO_COLOR_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_DSCP_TO_COLOR_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_TC_TO_PRIORITY_GROUP_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_PFC_PRIORITY_TO_QUEUE_MAP); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_WRED_PROFILE_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_SCHEDULER_PROFILE_ID); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_INGRESS_BUFFER_PROFILE_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_QOS_EGRESS_BUFFER_PROFILE_LIST); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_PRIORITY_FLOW_CONTROL); + ATTR_MAP_SET(PORT,SAI_PORT_ATTR_META_DATA); + //ATTR_MAP_SET(PORT,SAI_PORT_ATTR_EGRESS_BLOCK_PORT_LIST); + //ATTR_MAP_SET(PORT,SAI_PORT_ATTR_HW_PROFILE_ID); + ATTR_MAP_SET(QOS_MAPS,SAI_QOS_MAP_ATTR_TYPE); + ATTR_MAP_SET(QOS_MAPS,SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST); + ATTR_MAP_SET(QUEUE,SAI_QUEUE_ATTR_TYPE); + ATTR_MAP_SET(QUEUE,SAI_QUEUE_ATTR_WRED_PROFILE_ID); + ATTR_MAP_SET(QUEUE,SAI_QUEUE_ATTR_BUFFER_PROFILE_ID); + ATTR_MAP_SET(QUEUE,SAI_QUEUE_ATTR_SCHEDULER_PROFILE_ID); + ATTR_MAP_SET(ROUTE,SAI_ROUTE_ATTR_PACKET_ACTION); + ATTR_MAP_SET(ROUTE,SAI_ROUTE_ATTR_TRAP_PRIORITY); + ATTR_MAP_SET(ROUTE,SAI_ROUTE_ATTR_NEXT_HOP_ID); + ATTR_MAP_SET(ROUTE,SAI_ROUTE_ATTR_META_DATA); + ATTR_MAP_SET(VIRTUAL_ROUTER,SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE); + ATTR_MAP_SET(VIRTUAL_ROUTER,SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V6_STATE); + ATTR_MAP_SET(VIRTUAL_ROUTER,SAI_VIRTUAL_ROUTER_ATTR_SRC_MAC_ADDRESS); + ATTR_MAP_SET(VIRTUAL_ROUTER,SAI_VIRTUAL_ROUTER_ATTR_VIOLATION_TTL1_ACTION); + ATTR_MAP_SET(VIRTUAL_ROUTER,SAI_VIRTUAL_ROUTER_ATTR_VIOLATION_IP_OPTIONS); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_TYPE); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_PORT_ID); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_VLAN_ID); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_MTU); + ATTR_MAP_SET(ROUTER_INTERFACE,SAI_ROUTER_INTERFACE_ATTR_NEIGHBOR_MISS_PACKET_ACTION); + ATTR_MAP_SET(SAMPLEPACKET,SAI_SAMPLEPACKET_ATTR_SAMPLE_RATE); + ATTR_MAP_SET(SAMPLEPACKET,SAI_SAMPLEPACKET_ATTR_TYPE); + //ATTR_MAP_SET(SAMPLEPACKET,SAI_SAMPLEPACKET_ATTR_MODE); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_SCHEDULING_ALGORITHM); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_SHAPER_TYPE); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_RATE); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_BURST_RATE); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_RATE); + ATTR_MAP_SET(SCHEDULER,SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_BURST_RATE); + ATTR_MAP_SET(SCHEDULER_GROUP,SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT); + ATTR_MAP_SET(SCHEDULER_GROUP,SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST); + ATTR_MAP_SET(SCHEDULER_GROUP,SAI_SCHEDULER_GROUP_ATTR_PORT_ID); + ATTR_MAP_SET(SCHEDULER_GROUP,SAI_SCHEDULER_GROUP_ATTR_LEVEL); + ATTR_MAP_SET(SCHEDULER_GROUP,SAI_SCHEDULER_GROUP_ATTR_MAX_CHILDS); + ATTR_MAP_SET(SCHEDULER_GROUP,SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID); + ATTR_MAP_SET(STP_INSTANCE,SAI_STP_ATTR_VLAN_LIST); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_PORT_NUMBER); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_PORT_LIST); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_PORT_MAX_MTU); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_CPU_PORT); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_MAX_VIRTUAL_ROUTERS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_FDB_TABLE_SIZE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_L3_NEIGHBOR_TABLE_SIZE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_L3_ROUTE_TABLE_SIZE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_MEMBERS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NUMBER_OF_LAGS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_MEMBERS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NUMBER_OF_ECMP_GROUPS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NUMBER_OF_UNICAST_QUEUES); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NUMBER_OF_MULTICAST_QUEUES); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NUMBER_OF_QUEUES); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NUMBER_OF_CPU_QUEUES); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_OPER_STATUS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_MAX_TEMP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ACL_TABLE_MINIMUM_PRIORITY); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ACL_TABLE_MAXIMUM_PRIORITY); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ACL_ENTRY_MINIMUM_PRIORITY); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ACL_ENTRY_MAXIMUM_PRIORITY); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_FDB_DST_USER_META_DATA_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ROUTE_DST_USER_META_DATA_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NEIGHBOR_DST_USER_META_DATA_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_PORT_USER_META_DATA_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_VLAN_USER_META_DATA_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ACL_USER_META_DATA_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ACL_USER_TRAP_ID_RANGE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_DEFAULT_STP_INST_ID); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_TRAFFIC_CLASSES); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_SCHEDULER_GROUP_HIERARCHY_LEVELS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_SCHEDULER_GROUPS_PER_HIERARCHY_LEVEL); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_TOTAL_BUFFER_SIZE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_INGRESS_BUFFER_POOL_NUM); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_EGRESS_BUFFER_POOL_NUM); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_DEFAULT_TRAP_GROUP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_HASH); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_HASH); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_RESTART_TYPE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_MIN_PLANNED_RESTART_INTERVAL); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_NV_STORAGE_SIZE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_MAX_ACL_ACTION_COUNT); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_SWITCHING_MODE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_MCAST_CPU_FLOOD_ENABLE); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_SRC_MAC_ADDRESS); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_MAX_LEARNED_ADDRESSES); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_FDB_AGING_TIME); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_FDB_UNICAST_MISS_ACTION); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_FDB_BROADCAST_MISS_ACTION); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_FDB_MULTICAST_MISS_ACTION); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_SEED); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_DEFAULT_SYMMETRIC_HASH); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_HASH_IPV4); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_HASH_IPV4_IN_IPV4); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_ECMP_HASH_IPV6); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_ALGORITHM); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_SEED); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_DEFAULT_SYMMETRIC_HASH); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_HASH_IPV4); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_HASH_IPV4_IN_IPV4); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_LAG_HASH_IPV6); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_COUNTER_REFRESH_INTERVAL); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_DEFAULT_TC); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_DOT1P_TO_COLOR_MAP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_DSCP_TO_TC_MAP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_DSCP_TO_COLOR_MAP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_TC_TO_QUEUE_MAP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP); + ATTR_MAP_SET(SWITCH,SAI_SWITCH_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_TYPE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_OVERLAY_INTERFACE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_SRC_IP); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_TTL_MODE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_TTL_VAL); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_DSCP_MODE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_DSCP_VAL); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_GRE_KEY_VALID); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_GRE_KEY); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_ECN_MODE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_ENCAP_MAPPERS); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_DECAP_ECN_MODE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_DECAP_MAPPERS); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_DECAP_TTL_MODE); + ATTR_MAP_SET(TUNNEL,SAI_TUNNEL_ATTR_DECAP_DSCP_MODE); + ATTR_MAP_SET(TUNNEL_MAP,SAI_TUNNEL_MAP_ATTR_TYPE); + ATTR_MAP_SET(TUNNEL_TABLE_ENTRY,SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_VR_ID); + ATTR_MAP_SET(TUNNEL_TABLE_ENTRY,SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TYPE); + ATTR_MAP_SET(TUNNEL_TABLE_ENTRY,SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP); + ATTR_MAP_SET(TUNNEL_TABLE_ENTRY,SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_SRC_IP); + ATTR_MAP_SET(TUNNEL_TABLE_ENTRY,SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TUNNEL_TYPE); + ATTR_MAP_SET(TUNNEL_TABLE_ENTRY,SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID); + ATTR_MAP_SET(UDF,SAI_UDF_ATTR_MATCH_ID); + ATTR_MAP_SET(UDF,SAI_UDF_ATTR_GROUP_ID); + ATTR_MAP_SET(UDF,SAI_UDF_ATTR_BASE); + ATTR_MAP_SET(UDF,SAI_UDF_ATTR_OFFSET); + ATTR_MAP_SET(UDF,SAI_UDF_ATTR_HASH_MASK); + ATTR_MAP_SET(UDF_MATCH,SAI_UDF_MATCH_ATTR_L2_TYPE); + ATTR_MAP_SET(UDF_MATCH,SAI_UDF_MATCH_ATTR_L3_TYPE); + ATTR_MAP_SET(UDF_MATCH,SAI_UDF_MATCH_ATTR_GRE_TYPE); + ATTR_MAP_SET(UDF_MATCH,SAI_UDF_MATCH_ATTR_PRIORITY); + ATTR_MAP_SET(UDF_GROUP,SAI_UDF_GROUP_ATTR_UDF_LIST); + ATTR_MAP_SET(UDF_GROUP,SAI_UDF_GROUP_ATTR_TYPE); + ATTR_MAP_SET(UDF_GROUP,SAI_UDF_GROUP_ATTR_LENGTH); + ATTR_MAP_SET(VLAN,SAI_VLAN_ATTR_MEMBER_LIST); + ATTR_MAP_SET(VLAN,SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES); + ATTR_MAP_SET(VLAN,SAI_VLAN_ATTR_STP_INSTANCE); + ATTR_MAP_SET(VLAN,SAI_VLAN_ATTR_LEARN_DISABLE); + ATTR_MAP_SET(VLAN,SAI_VLAN_ATTR_META_DATA); + ATTR_MAP_SET(VLAN_MEMBER,SAI_VLAN_MEMBER_ATTR_VLAN_ID); + ATTR_MAP_SET(VLAN_MEMBER,SAI_VLAN_MEMBER_ATTR_PORT_ID); + ATTR_MAP_SET(VLAN_MEMBER,SAI_VLAN_MEMBER_ATTR_TAGGING_MODE); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_ECN_MARK_MODE); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_GREEN_ENABLE); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_GREEN_MIN_THRESHOLD); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_GREEN_MAX_THRESHOLD); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_GREEN_DROP_PROBABILITY); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_YELLOW_ENABLE); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_YELLOW_MIN_THRESHOLD); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_YELLOW_MAX_THRESHOLD); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_YELLOW_DROP_PROBABILITY); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_RED_ENABLE); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_RED_MIN_THRESHOLD); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_RED_MAX_THRESHOLD); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_RED_DROP_PROBABILITY); + ATTR_MAP_SET(WRED,SAI_WRED_ATTR_WEIGHT); + + return map; +} + +const std::unordered_map> g_attr_name_map_name = get_attr_name_map(); + +const char* c_unknown_attr_name = "UNKNOWN_ATTR_NAME"; + +const char* get_attr_name(sai_object_type_t o, sai_attr_id_t a) +{ + auto it = g_attr_name_map_name.find((int32_t)o); + + if (it == g_attr_name_map_name.end()) + { + SWSS_LOG_ERROR("object type %d not found in map!", o); + + return c_unknown_attr_name; + } + + auto ita = it->second.find((int32_t)a); + + if (ita != it->second.end()) + { + return ita->second.c_str(); + } + + SWSS_LOG_ERROR("object type %d attr id %d not found in map!", o, a); + + return c_unknown_attr_name; +} + +#define META_LOG_THROW(md, format, ...) \ +{ \ + SWSS_LOG_ERROR("%s, %s (%s) " format, \ + get_object_type_name(md.objecttype),\ + get_attr_name(md.objecttype,md.attrid),\ + get_serialization_type_name(md.serializationtype), \ +##__VA_ARGS__);\ + throw;\ +} + +std::string get_attr_info(const sai_attr_metadata_t& md) +{ + return std::string(get_object_type_name(md.objecttype)) + ":" + + std::string(get_attr_name(md.objecttype,md.attrid)) + ":" + + std::string(get_serialization_type_name(md.serializationtype)); +} + +void metadata_sanity_check(const sai_attr_metadata_t& md) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_INFO("performing metadata sanity check: object type %d, attr id: %d", md.objecttype, md.attrid); + + // check if object type is inside allowed range + + if ((md.objecttype <= SAI_OBJECT_TYPE_NULL) || + (md.objecttype >= SAI_OBJECT_TYPE_MAX)) + { + META_LOG_THROW(md, "invalid object type value"); + } + + auto &attrset = AttributesMetadata[md.objecttype]; + + if (attrset.find(md.attrid) != attrset.end()) + { + META_LOG_THROW(md, "this attribute id is already defined"); + } + + SWSS_LOG_INFO("working on: %s", get_attr_info(md).c_str()); + + // TODO since we have valid object type we could validate + // attributte id range, but that requires extra meta data + // problem can be when we add custom attributes or attributes + // have offset ranges like acl flags/action. + + // TODO we could also validate serialization type values + + // check creation flags + + // NOTE: cast is made to prevent warning -Wswitch on combined flags + // error: case value 'x' not in enumerated type + switch ((int)md.flags) + { + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY: + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY: + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET: + + if (md.serializationtype == SAI_SERIALIZATION_TYPE_UINT32 && + md.defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE) + { + break; + } + + if (md.defaultvaluetype != SAI_DEFAULT_VALUE_TYPE_NONE) + { + META_LOG_THROW(md, "no default value expected, but type provided: %d", md.defaultvaluetype); + } + + break; + + case SAI_ATTR_FLAGS_CREATE_ONLY: + case SAI_ATTR_FLAGS_CREATE_AND_SET: + + if (md.defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_NONE) + { + META_LOG_THROW(md, "expected no default value, but type provided: %d", md.defaultvaluetype); + } + + break; + + case SAI_ATTR_FLAGS_READ_ONLY: + + if (md.defaultvaluetype != SAI_DEFAULT_VALUE_TYPE_NONE) + { + META_LOG_THROW(md, "no default value expected, but type provided: %d", md.defaultvaluetype); + } + + if (md.isconditional()) + { + META_LOG_THROW(md, "read only can't be conditional"); + } + + break; + + default: + + META_LOG_THROW(md, "invalid creation flags: 0x%u", md.flags); + } + + // check if enum is set only on INT32 serialization type + + if (md.isenum() && + (md.serializationtype != SAI_SERIALIZATION_TYPE_INT32) && + (md.serializationtype != SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32) && + (md.serializationtype != SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32)) + { + META_LOG_THROW(md, "marked as enum but has invalid serialization type"); + } + + // check if required object type is provided for object expected objects + + switch (md.serializationtype) + { + // TODO some acl field/data may require object type + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + + if (md.allowedobjecttypes.size() == 0) + { + META_LOG_THROW(md, "object types list is required but it's empty"); + } + + break; + + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_INT8: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + case SAI_SERIALIZATION_TYPE_INT32_LIST: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_VLAN_LIST: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + case SAI_SERIALIZATION_TYPE_CHARDATA: + case SAI_SERIALIZATION_TYPE_UINT32_RANGE: + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + + // allowed object types list is not needed here + break; + + default: + META_LOG_THROW(md, "serialization type not supported yet"); + } + + // check object types + + if (md.allowedobjecttypes.size() > 0) + { + switch (md.serializationtype) + { + // ACL also may apply field/data + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + // ok + break; + + default: + + META_LOG_THROW(md, "allowed object types should be empty on this serialization type"); + } + + // check if allowed object types are in range + // they may repeat, but we can also check that + + for (auto& oid: md.allowedobjecttypes) + { + if ((oid <= SAI_OBJECT_TYPE_NULL) || + (oid >= SAI_OBJECT_TYPE_MAX)) + { + META_LOG_THROW(md, "invalid allowed object type: %d", oid); + } + } + } + + bool requiredefault = (!HAS_FLAG_MANDATORY_ON_CREATE(md.flags)) && + (HAS_FLAG_CREATE_ONLY(md.flags) || HAS_FLAG_CREATE_AND_SET(md.flags)); + + // check for default list not null + + // TODO should default be a pointer? then we could explicitly check if it was set + if (requiredefault) + { + if (md.defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_NONE) + { + META_LOG_THROW(md, "expected no default value, but type provided: %d", md.defaultvaluetype); + } + + // default value is required, should default be a pointer? to force explicit assignment? + + switch (md.serializationtype) + { + + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + //case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_BOOL: + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT8: + case SAI_SERIALIZATION_TYPE_UINT16: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_UINT64: + case SAI_SERIALIZATION_TYPE_MAC: + case SAI_SERIALIZATION_TYPE_IP_ADDRESS: + // primitive type, ok + break; + + case SAI_SERIALIZATION_TYPE_INT32_LIST: + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + + if (md.defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST) + { + break; + } + + META_LOG_THROW(md, "default value list is needed on this serialization type but list is NULL"); + + break; + + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + + if (md.defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST) + { + break; + } + + if (md.defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_CONST && + md.defaultvalue.u8list.list != NULL) + { + break; + } + + META_LOG_THROW(md, "default value list is needed on this serialization type but list is NULL"); + + break; + + default: + + META_LOG_THROW(md, "default value is required but this serialization type is not supported yet"); + } + } + + if (md.enumtypestr == NULL && !md.enumallowedvalues.empty()) + { + META_LOG_THROW(md, "enum type string missing, but enum values defined"); + } + + if (md.enumtypestr != NULL && md.enumallowedvalues.empty()) + { + META_LOG_THROW(md, "enum type string defined, but allowed values are empty"); + } + + if (md.isenum() && md.isenumlist()) + { + META_LOG_THROW(md, "marked as enum and enumlist, not possible"); + } + + // check enum type string + + if ((md.isenum() || md.isenumlist()) && md.enumtypestr == NULL) + { + META_LOG_THROW(md, "is marked enum but missing enum type string"); + } + + if (!(md.isenum() || md.isenumlist()) && md.enumtypestr != NULL) + { + META_LOG_THROW(md, "is not marked enum but has defined enum type string"); + } + + // check enum defined values + + if ((md.isenum() || md.isenumlist()) && md.enumallowedvalues.size() == 0) + { + META_LOG_THROW(md, "is marked enum but missing enum allowed values"); + } + + if (!(md.isenum() || md.isenumlist()) && md.enumallowedvalues.size() != 0) + { + META_LOG_THROW(md, "is not marked enum but has defined enum allowed values"); + } + + if (requiredefault && md.isenum()) + { + int32_t enumdefault = md.defaultvalue.s32; + + bool found = false; + + for (auto& val: md.enumallowedvalues) + { + if (val == enumdefault) + { + found = true; + break; + } + } + + if (!found) + { + META_LOG_THROW(md, "default enum value %d is not present on enum allowed values (%s)", enumdefault, md.enumtypestr); + } + } + + if (requiredefault && md.isenumlist()) + { + + for (uint32_t i = 0 ; i < md.defaultvalue.s32list.count; ++i) + { + int32_t item = md.defaultvalue.s32list.list[i]; + + bool found = false; + + for (auto& val: md.enumallowedvalues) + { + if (val == item) + { + found = true; + break; + } + } + + if (!found) + { + META_LOG_THROW(md, "default enum value %d is not present on enum allowed values (%s)", item, md.enumtypestr); + } + } + } + + //switch (md.conditiontype) + //{ + // case SAI_ATTR_CONDITION_TYPE_NONE: + // case SAI_ATTR_CONDITION_TYPE_OR: + // // ok + // break; + + // default: + + // META_LOG_THROW(md, "invalid condition type specified: %d", md.conditiontype); + //} + + switch (md.defaultvaluetype) + { + case SAI_DEFAULT_VALUE_TYPE_NONE: + case SAI_DEFAULT_VALUE_TYPE_CONST: + + // TODO should we check conditions/cretion flags ? + break; + + case SAI_DEFAULT_VALUE_TYPE_INHERIT: + + // TODO does it make sense to make it inherit + if (md.objecttype == SAI_OBJECT_TYPE_BUFFER_PROFILE && + md.attrid == SAI_BUFFER_PROFILE_ATTR_TH_MODE) + { + // ok + break; + } + + META_LOG_THROW(md, "inherit default value type not allowed"); + + case SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE: + // TODO we need to check to which attribute this point's (we may need second run) + break; + + case SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE: + + // TODO we need to check to which attribute this point's (we may need second run) + break; + + case SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST: + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_INT32_LIST: + case SAI_SERIALIZATION_TYPE_UINT8_LIST: + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + break; + + default: + + META_LOG_THROW(md, "default empty list specified, but attribute is not list"); + } + + break; + + case SAI_DEFAULT_VALUE_TYPE_VENDOR_SPECIFIC: + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_MAC: + break; + + default: + + META_LOG_THROW(md, "vendor specific not allowed on this type"); + } + + break; + + + default: + + META_LOG_THROW(md, "invalid default value type specified: %d", md.defaultvaluetype); + } + + bool conditional = md.isconditional(); + + if (!conditional && md.conditions.size() > 0) + { + META_LOG_THROW(md, "not conditional but conditions specified"); + } + + if (conditional) + { + if (md.conditions.size() == 0) + { + META_LOG_THROW(md, "marked as conditional but no conditions specified"); + } + + switch ((int)md.flags) + { + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET: + + // if object is mandatory_on_create and create_and_set then it can't + // be marked as conditional because?? TODO i forgot why + // some ohter object may depend on it but this attribute can change? + // this would be caught by below condition on condition + + if (md.objecttype != SAI_OBJECT_TYPE_MIRROR) + { + META_LOG_THROW(md, "marked as conditional on non mirror session, but invalid creation flags: 0x%u", md.flags); + } + + break; + + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY: + case SAI_ATTR_FLAGS_CREATE_ONLY: // will require default value, on some cases may be dynamic + // ok + break; + + default: + + META_LOG_THROW(md, "marked as conditional, but invalid creation flags: 0x%u", md.flags); + } + + // condition must be the same object type as attribue we check + + auto &hash = AttributesMetadata[md.objecttype]; + + for (auto &c: md.conditions) + { + if (c.attrid == md.attrid) + { + META_LOG_THROW(md, "conditional attr id %d is the same as condition attribute", c.attrid); + } + + auto it = hash.find(c.attrid); + + if (it == hash.end()) + { + META_LOG_THROW(md,"conditional attribute id %d was not defined yet in metadata", c.attrid); + } + + const sai_attr_metadata_t &cmd = *it->second; + + switch (cmd.serializationtype) + { + case SAI_SERIALIZATION_TYPE_BOOL: + + SWSS_LOG_DEBUG("attr id: %d cond.bool: %d", c.attrid, c.condition.booldata); + + break; + + case SAI_SERIALIZATION_TYPE_INT32: + + if (!cmd.isenum()) + { + META_LOG_THROW(md, "conditional attribute %d is not enum type", cmd.attrid); + } + + SWSS_LOG_DEBUG("attr id: %d cond.s32: %d ", c.attrid, c.condition.s32); + + // check if condition enum is in condition attribute range + + { + bool found = false; + + for (auto& val: cmd.enumallowedvalues) + { + if (val == c.condition.s32) + { + found = true; + break; + } + } + + if (!found) + { + META_LOG_THROW(md, "condition enum %d not found on condition attribute enum range", c.condition.s32); + } + } + + break; + + default: + + META_LOG_THROW(md, "serialization type %d of conditional attribute is not supported yet", cmd.serializationtype); + + } + + if (cmd.isconditional()) // cmd.conditiontype != SAI_ATTR_CONDITION_TYPE_NONE) + { + if (cmd.flags == SAI_ATTR_FLAGS_CREATE_ONLY && + cmd.serializationtype == SAI_SERIALIZATION_TYPE_BOOL) + { + // ok, that means there is default value (it may be depending on switch intenal) + } + else + { + META_LOG_THROW(md, "conditional attibute is also conditional, not allowed"); + } + } + + switch ((int)cmd.flags) + { + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY: + case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY: + case SAI_ATTR_FLAGS_CREATE_ONLY: + // condition attribute must be create only since + // if it could change then other object may be required to pass + // on creation time that was not passed + break; + + default: + + META_LOG_THROW(md, "conditional attribute must be create only"); + } + } + } + + if (md.isenumlist()) + { + if (md.serializationtype != SAI_SERIALIZATION_TYPE_INT32_LIST) + { + META_LOG_THROW(md, "marked as enum list but wrong serialization type"); + } + + if (conditional) + { + META_LOG_THROW(md, "conditional enum list not supported yet"); + } + + // TODO what we need to check more? + } + + if (md.allownullobjectid) + { + switch (md.serializationtype) + { + // there may be other types in acl field/data that accept object id + case SAI_SERIALIZATION_TYPE_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_OBJECT_LIST: + // ok + break; + + default: + + META_LOG_THROW(md, "allow null object is set but serialization type is wrong"); + } + + if (md.allowedobjecttypes.size() == 0) + { + META_LOG_THROW(md, "allow null object is set but allowed object types is empty"); + } + } + + if (HAS_FLAG_KEY(md.flags)) + { + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_UINT32_LIST: + + if (md.objecttype == SAI_OBJECT_TYPE_PORT && md.attrid == SAI_PORT_ATTR_HW_LANE_LIST) + { + break; + } + + // list as key is so far supported only on port hw lane list, and it will + // need to have special handling anyway since lanes may not be reused + META_LOG_THROW(md, "marked as key, but have invalid serialization type (list)"); + + case SAI_SERIALIZATION_TYPE_INT32: + case SAI_SERIALIZATION_TYPE_UINT32: + case SAI_SERIALIZATION_TYPE_UINT8: + // ok + break; + + default: + + META_LOG_THROW(md, "marked as key, but have invalid serialization type"); + } + } + + // acl field / action may only be defined on acl entry + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + + if (md.objecttype != SAI_OBJECT_TYPE_ACL_ENTRY || + md.attrid < SAI_ACL_ENTRY_ATTR_FIELD_START || + md.attrid > SAI_ACL_ENTRY_ATTR_FIELD_END) + { + // TODO verify if it is correct? + if (md.objecttype != SAI_OBJECT_TYPE_UDF_MATCH) + { + META_LOG_THROW(md, "acl field may only be set on acl field"); + } + } + + break; + + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + + if (md.objecttype != SAI_OBJECT_TYPE_ACL_ENTRY || + md.attrid < SAI_ACL_ENTRY_ATTR_ACTION_START || + md.attrid > SAI_ACL_ENTRY_ATTR_ACTION_END) + { + META_LOG_THROW(md, "acl action may only be set on acl action"); + } + + break; + + default: + break; + } + + if (md.objecttype == SAI_OBJECT_TYPE_ACL_ENTRY) + { + if (md.attrid >= SAI_ACL_ENTRY_ATTR_FIELD_START && + md.attrid <= SAI_ACL_ENTRY_ATTR_FIELD_END) + { + // serialization type must be correct + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_BOOL: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP4: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_IP6: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: + case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: + break; + + default: + META_LOG_THROW(md, "invalid serialization type for acl field"); + } + } + + if (md.attrid >= SAI_ACL_ENTRY_ATTR_ACTION_START && + md.attrid <= SAI_ACL_ENTRY_ATTR_ACTION_END) + { + // serialization type must be correct + + switch (md.serializationtype) + { + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT8: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT16: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_INT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_UINT32: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_MAC: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV4: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_IPV6: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_ID: + case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: + break; + + default: + META_LOG_THROW(md, "invalid serialization type for acl action"); + } + } + } + + if (md.isvlan()) + { + if (md.serializationtype != SAI_SERIALIZATION_TYPE_UINT16) + { + META_LOG_THROW(md, "marked as vlan, but fiels has wrong serialization type"); + } + } + + // TODO check serialization + creation flags type and check default value type + + // success, add attribute to valid set + attrset[md.attrid] = &md; + + // we could have metadata automatic created for object types like: + // bool haveMandatoryAttribytes + // bool haveMandatoryContitionalAttributes +} + +void meta_init() +{ + SWSS_LOG_ENTER(); + + static bool initialized = false; + + if (initialized) + { + return; + } + + initialized = true; + + for (int type = SAI_OBJECT_TYPE_NULL + 1; type < SAI_OBJECT_TYPE_MAX; ++type) + { + // declare empty attribute list for each object type + // TODO we could collect those types from metadata directly + AttributesMetadata[(sai_object_type_t)type] = {}; + + SWSS_LOG_INFO("create placeholder for object type %d", type); + } + +#define CHECK(x) \ + for (size_t i = 0; i < sai_ ## x ## _attr_metadata_count; ++i) \ + metadata_sanity_check(sai_ ## x ## _attr_metadata[i]); + + CHECK(acl_counter); + CHECK(acl_entry); + CHECK(acl_range); + CHECK(acl_table); + CHECK(buffer_pool); + CHECK(buffer_profile); + CHECK(fdb); + CHECK(hash); + CHECK(hostintf); + CHECK(hostintf_trap); + CHECK(hostintf_trap_group); + CHECK(lag); + CHECK(lag_member); + CHECK(mirror); + CHECK(neighbor); + CHECK(nexthop); + CHECK(nexthopgroup); + CHECK(policer); + CHECK(port); + CHECK(qos_maps); + CHECK(queue); + CHECK(route); + CHECK(router); + CHECK(routerintf); + CHECK(samplepacket); + CHECK(scheduler); + CHECK(scheduler_group); + CHECK(stp); + CHECK(switch); + CHECK(tunnel); + CHECK(tunnel_map); + CHECK(tunnel_table_entry); + CHECK(udf); + CHECK(udf_group); + CHECK(udf_match); + CHECK(vlan); + CHECK(vlan_member); + CHECK(wred); +} diff --git a/meta/sai_meta_scheduler.cpp b/meta/sai_meta_scheduler.cpp new file mode 100644 index 000000000000..7ab37bb7d166 --- /dev/null +++ b/meta/sai_meta_scheduler.cpp @@ -0,0 +1,116 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_SCHEDULER + +DEFINE_ENUM_VALUES(sai_scheduling_type_t) +{ + SAI_SCHEDULING_STRICT, + SAI_SCHEDULING_WRR, + SAI_SCHEDULING_DWRR +}; + +const sai_attr_metadata_t sai_scheduler_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_SCHEDULING_ALGORITHM, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_SCHEDULING_WRR }, + .enumtypestr = StringifyEnum ( sai_scheduling_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_scheduling_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 1 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO valid only when SAI_SCHEDULER_ATTR_SCHEDULING_ALGORITHM = SAI_SCHEDULING_DWRR + // TODO need to check range Range [1 - 100] + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_SHAPER_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_METER_TYPE_BYTES }, + .enumtypestr = StringifyEnum ( sai_meter_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_meter_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_RATE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_BURST_RATE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_RATE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER, + .attrid = SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_BURST_RATE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u64 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_scheduler_attr_metadata_count = sizeof(sai_scheduler_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_schedulergroup.cpp b/meta/sai_meta_schedulergroup.cpp new file mode 100644 index 000000000000..d9c234e45a2b --- /dev/null +++ b/meta/sai_meta_schedulergroup.cpp @@ -0,0 +1,100 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_SCHEDULER_GROUP + +const sai_attr_metadata_t sai_scheduler_group_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER_GROUP, + .attrid = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER_GROUP, + .attrid = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SCHEDULER }, // TODO there may be different types like QUEUE or PORT here + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO extra check may be needed here + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER_GROUP, + .attrid = SAI_SCHEDULER_GROUP_ATTR_PORT_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER_GROUP, + .attrid = SAI_SCHEDULER_GROUP_ATTR_LEVEL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO validate range 0..16 + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER_GROUP, + .attrid = SAI_SCHEDULER_GROUP_ATTR_MAX_CHILDS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO validate range 0..64 ? + }, + + { + .objecttype = SAI_OBJECT_TYPE_SCHEDULER_GROUP, + .attrid = SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_SCHEDULER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO SET ONLY, special, not supported yet, must change api design + }, +}; + +const size_t sai_scheduler_group_attr_metadata_count = sizeof(sai_scheduler_group_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_stp.cpp b/meta/sai_meta_stp.cpp new file mode 100644 index 000000000000..aa450cfb93db --- /dev/null +++ b/meta/sai_meta_stp.cpp @@ -0,0 +1,25 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_STP_INSTANCE + +// TODO QUAD API needed, need STP_MEMBER object + +const sai_attr_metadata_t sai_stp_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_STP_INSTANCE, + .attrid = SAI_STP_ATTR_VLAN_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_VLAN_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + +}; + +const size_t sai_stp_attr_metadata_count = sizeof(sai_stp_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_switch.cpp b/meta/sai_meta_switch.cpp new file mode 100644 index 000000000000..93bf1239c221 --- /dev/null +++ b/meta/sai_meta_switch.cpp @@ -0,0 +1,1200 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_SWITCH + +DEFINE_ENUM_VALUES(sai_packet_action_t) +{ + SAI_PACKET_ACTION_DROP, + SAI_PACKET_ACTION_FORWARD, + SAI_PACKET_ACTION_COPY, + SAI_PACKET_ACTION_COPY_CANCEL, + SAI_PACKET_ACTION_TRAP, + SAI_PACKET_ACTION_LOG, + SAI_PACKET_ACTION_DENY, + SAI_PACKET_ACTION_TRANSIT +}; + +DEFINE_ENUM_VALUES(sai_switch_oper_status_t) +{ + SAI_SWITCH_OPER_STATUS_UNKNOWN, + SAI_SWITCH_OPER_STATUS_UP, + SAI_SWITCH_OPER_STATUS_DOWN, + SAI_SWITCH_OPER_STATUS_FAILED +}; + +DEFINE_ENUM_VALUES(sai_switch_restart_type_t) +{ + SAI_RESTART_TYPE_NONE, + SAI_RESTART_TYPE_PLANNED, + SAI_RESTART_TYPE_ANY +}; + +DEFINE_ENUM_VALUES(sai_switch_switching_mode_t) +{ + SAI_SWITCHING_MODE_CUT_THROUGH, + SAI_SWITCHING_MODE_STORE_AND_FORWARD +}; + +DEFINE_ENUM_VALUES(sai_hash_algorithm_t) +{ + SAI_HASH_ALGORITHM_CRC, + SAI_HASH_ALGORITHM_XOR, + SAI_HASH_ALGORITHM_RANDOM +}; + +const sai_attr_metadata_t sai_switch_attr_metadata[] = { + + // READ-ONLY + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_PORT_NUMBER, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_PORT_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_PORT_MAX_MTU, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_CPU_PORT, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_MAX_VIRTUAL_ROUTERS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_FDB_TABLE_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_L3_NEIGHBOR_TABLE_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_L3_ROUTE_TABLE_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_MEMBERS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NUMBER_OF_LAGS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_MEMBERS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NUMBER_OF_ECMP_GROUPS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NUMBER_OF_UNICAST_QUEUES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NUMBER_OF_MULTICAST_QUEUES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NUMBER_OF_QUEUES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NUMBER_OF_CPU_QUEUES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_OPER_STATUS, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_switch_oper_status_t ), + .enumallowedvalues = ENUM_VALUES ( sai_switch_oper_status_t ), + .conditions = { }, + + // dynamic + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_MAX_TEMP, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ACL_TABLE_MINIMUM_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ACL_TABLE_MAXIMUM_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ACL_ENTRY_MINIMUM_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ACL_ENTRY_MAXIMUM_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_FDB_DST_USER_META_DATA_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ROUTE_DST_USER_META_DATA_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NEIGHBOR_DST_USER_META_DATA_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_PORT_USER_META_DATA_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_VLAN_USER_META_DATA_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ACL_USER_META_DATA_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ACL_USER_TRAP_ID_RANGE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_RANGE, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_DEFAULT_STP_INST_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_STP_INSTANCE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_VIRTUAL_ROUTER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_TRAFFIC_CLASSES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_SCHEDULER_GROUP_HIERARCHY_LEVELS, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_SCHEDULER_GROUPS_PER_HIERARCHY_LEVEL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_TOTAL_BUFFER_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_INGRESS_BUFFER_POOL_NUM, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_EGRESS_BUFFER_POOL_NUM, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_DEFAULT_TRAP_GROUP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_TRAP_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + /* + * (default value after switch initialization + * SAI_HOSTIF_TRAP_GROUP_ATTR_ADMIN_STATE = true + * SAI_HOSTIF_TRAP_GROUP_ATTR_PRIO = SAI_SWITCH_ATTR_ACL_TABLE_MINIMUM_PRIORITY, + * SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE = 0, + * SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER = SAI_NULL_OBJECT_ID) + * The group handle is read only, while the group attributes, such as queue and policer, + * may be modified + */ + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_HASH, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + /* + * (default value after switch initialization + * SAI_HASH_NATIVE_FIELD_LIST = [SAI_NATIVE_HASH_FIELD_SRC_MAC, + * SAI_NATIVE_HASH_FIELD_DST_MAC, SAI_NATIVE_HASH_FIELD_IN_PORT, + * SAI_NATIVE_HASH_FIELD_ETHERTYPE] + * SAI_HASH_UDF_GROUP_LIST empty list) + * The object id is read only, while the object attributes can be modified + */ + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_HASH, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + /* + * (default value after switch initialization + * SAI_HASH_NATIVE_FIELD_LIST = [SAI_NATIVE_HASH_FIELD_SRC_MAC, + * SAI_NATIVE_HASH_FIELD_DST_MAC, SAI_NATIVE_HASH_FIELD_IN_PORT, + * SAI_NATIVE_HASH_FIELD_ETHERTYPE] + * SAI_HASH_UDF_GROUP_LIST empty list) + * The object id is read only, while the object attributes can be modified + */ + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_RESTART_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_switch_restart_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_switch_restart_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_MIN_PLANNED_RESTART_INTERVAL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_NV_STORAGE_SIZE, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT64, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_MAX_ACL_ACTION_COUNT, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + +// { +// .objecttype = SAI_OBJECT_TYPE_SWITCH, +// .attrid = SAI_SWITCH_ATTR_ACL_CAPABILITY, +// .serializationtype = SAI_SERIALIZATION_TYPE_ACL_CAPABILITY, // not supported yet +// .flags = SAI_ATTR_FLAGS_READ_ONLY, +// .allowedobjecttypes = { }, +// .allownullobjectid = false, +// .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, +// .defaultvalue = { }, +// .enumtypestr = NULL, +// .enumallowedvalues = { }, +// .conditions = { }, +// }, + + // READ-WRITE + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_SWITCHING_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_SWITCHING_MODE_STORE_AND_FORWARD }, + .enumtypestr = StringifyEnum ( sai_switch_switching_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_switch_switching_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO what is default value? switch dependent? + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_MCAST_CPU_FLOOD_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS, + .serializationtype = SAI_SERIALIZATION_TYPE_MAC, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_VENDOR_SPECIFIC, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // NOTE: Default value is switch dependent + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_MAX_LEARNED_ADDRESSES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_FDB_AGING_TIME, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_FDB_UNICAST_MISS_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_FDB_BROADCAST_MISS_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_FDB_MULTICAST_MISS_ACTION, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_PACKET_ACTION_FORWARD }, + .enumtypestr = StringifyEnum ( sai_packet_action_t ), + .enumallowedvalues = ENUM_VALUES ( sai_packet_action_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_HASH_ALGORITHM_CRC }, + .enumtypestr = StringifyEnum ( sai_hash_algorithm_t ), + .enumallowedvalues = ENUM_VALUES ( sai_hash_algorithm_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_SEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_DEFAULT_SYMMETRIC_HASH, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_HASH_IPV4, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO there may exist internal hash (vendor specific / switch internal) + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_HASH_IPV4_IN_IPV4, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO there may exist internal hash + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_ECMP_HASH_IPV6, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO there may exist internal hash + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_ALGORITHM, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_HASH_ALGORITHM_CRC }, + .enumtypestr = StringifyEnum ( sai_hash_algorithm_t ), + .enumallowedvalues = ENUM_VALUES ( sai_hash_algorithm_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_SEED, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_DEFAULT_SYMMETRIC_HASH, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_HASH_IPV4, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + + .conditions = { }, + + // TODO there may exist internal hash + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_HASH_IPV4_IN_IPV4, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO there may exist internal hash + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_LAG_HASH_IPV6, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_HASH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + + .conditions = { }, + + // TODO there may exist internal hash + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_COUNTER_REFRESH_INTERVAL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 1 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // QOS attributes + // extra validation may be needed against PORT and map on ports + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_DEFAULT_TC, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_DOT1P_TO_COLOR_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_DSCP_TO_TC_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_DSCP_TO_COLOR_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_TC_TO_QUEUE_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_SWITCH, + .attrid = SAI_SWITCH_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_QOS_MAPS }, + .allownullobjectid = true, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + //{ + // .objecttype = SAI_OBJECT_TYPE_SWITCH, + // .attrid = SAI_SWITCH_ATTR_SWITCH_SHELL_ENABLE, + // .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + // .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + // .allowedobjecttypes = { }, + // .allownullobjectid = true, + // .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + // .defaultvalue = { .booldata = false }, + // .enumtypestr = NULL, + // .enumallowedvalues = { }, + // .conditions = { }, + //}, +}; + +const size_t sai_switch_attr_metadata_count = sizeof(sai_switch_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_tunnel.cpp b/meta/sai_meta_tunnel.cpp new file mode 100644 index 000000000000..6612d78a01e1 --- /dev/null +++ b/meta/sai_meta_tunnel.cpp @@ -0,0 +1,452 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_TUNNEL + +DEFINE_ENUM_VALUES(sai_tunnel_type_t) +{ + SAI_TUNNEL_IPINIP, + SAI_TUNNEL_IPINIP_GRE, + SAI_TUNNEL_VXLAN, + SAI_TUNNEL_MPLS +}; + +DEFINE_ENUM_VALUES(sai_tunnel_ttl_mode_t) +{ + SAI_TUNNEL_TTL_UNIFORM_MODEL, + SAI_TUNNEL_TTL_PIPE_MODEL +}; + +DEFINE_ENUM_VALUES(sai_tunnel_dscp_mode_t) +{ + SAI_TUNNEL_DSCP_UNIFORM_MODEL, + SAI_TUNNEL_DSCP_PIPE_MODEL +}; + +DEFINE_ENUM_VALUES(sai_tunnel_encap_ecn_mode_t) +{ + SAI_TUNNEL_ENCAP_ECN_MODE_STANDARD, + SAI_TUNNEL_ENCAP_ECN_MODE_USER_DEFINED +}; + +DEFINE_ENUM_VALUES(sai_tunnel_decap_ecn_mode_t) +{ + SAI_TUNNEL_DECAP_ECN_MODE_STANDARD, + SAI_TUNNEL_DECAP_ECN_MODE_COPY_FROM_OUTER, + SAI_TUNNEL_DECAP_ECN_MODE_USER_DEFINED +}; + +DEFINE_ENUM_VALUES(sai_tunnel_map_type_t) +{ + SAI_TUNNEL_MAP_OECN_TO_UECN, + SAI_TUNNEL_MAP_UECN_OECN_TO_OECN, + SAI_TUNNEL_MAP_VNI_TO_VLAN_ID, + SAI_TUNNEL_MAP_VLAN_ID_TO_VNI +}; + +DEFINE_ENUM_VALUES(sai_tunnel_term_table_entry_type_t) +{ + SAI_TUNNEL_TERM_TABLE_ENTRY_P2P, + SAI_TUNNEL_TERM_TABLE_ENTRY_P2MP +}; + +const sai_attr_metadata_t sai_tunnel_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_tunnel_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ROUTER_INTERFACE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP ), + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP_GRE ), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_OVERLAY_INTERFACE, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_ROUTER_INTERFACE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP ), + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP_GRE ), + }, + }, + + // TUNNEL ENCAP ATTRIBUTES + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_SRC_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_IP_ADDRESS, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_TTL_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_TUNNEL_TTL_UNIFORM_MODEL }, + .enumtypestr = StringifyEnum ( sai_tunnel_ttl_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_ttl_mode_t ), + .conditions = { }, + + // TODO some extra checks may be needed + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_TTL_VAL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_TUNNEL_ATTR_ENCAP_TTL_MODE, SAI_TUNNEL_TTL_PIPE_MODEL ) }, + + // TODO valid only and MANDATORY_ON_CREATE when SAI_TUNNEL_ENCAP_TTL_MODE = SAI_TUNNEL_TTL_PIPE_MODEL + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_DSCP_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_TUNNEL_DSCP_UNIFORM_MODEL }, + .enumtypestr = StringifyEnum ( sai_tunnel_dscp_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_dscp_mode_t ), + .conditions = { } + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_DSCP_VAL, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_TUNNEL_ATTR_ENCAP_DSCP_MODE, SAI_TUNNEL_DSCP_PIPE_MODEL ) }, + + // TODO only 6 bits, additional check is needed + // TODO valid only and MANDATORY_ON_CREATE when SAI_TUNNEL_ENCAP_DSCP_MODE = SAI_TUNNEL_DSCP_PIPE_MODEL + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_GRE_KEY_VALID, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP_GRE ) }, + + // valid only on that condition + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_GRE_KEY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_BOOL ( SAI_TUNNEL_ATTR_ENCAP_GRE_KEY_VALID, true) }, + + // valid only on that condition + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_ECN_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_TUNNEL_ENCAP_ECN_MODE_STANDARD }, + .enumtypestr = StringifyEnum ( sai_tunnel_encap_ecn_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_encap_ecn_mode_t ), + .conditions = { }, + + // TODO Need to provide SAI_TUNNEL_MAP_OECN_TO_UECN in SAI_TUNNEL_ATTR_ENCAP_MAPPERS + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_ENCAP_MAPPERS, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_TUNNEL_MAP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_TUNNEL_ATTR_ENCAP_ECN_MODE, SAI_TUNNEL_ENCAP_ECN_MODE_USER_DEFINED ) }, + + // TODO extra logic will be needed on mappers + // TODO valid only on that condition + }, + + // TUNNEL DECAP ATTRIBUTES + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_DECAP_ECN_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_TUNNEL_DECAP_ECN_MODE_STANDARD }, + .enumtypestr = StringifyEnum ( sai_tunnel_decap_ecn_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_decap_ecn_mode_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_DECAP_MAPPERS, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_TUNNEL_MAP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_TUNNEL_ATTR_DECAP_ECN_MODE, SAI_TUNNEL_DECAP_ECN_MODE_USER_DEFINED ) }, + + // TODO extra logic will be needed on mappers + // valid only on that condition + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_DECAP_TTL_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, //{ .s32 = SAI_TUNNEL_TTL_UNIFORM_MODEL }, + .enumtypestr = StringifyEnum ( sai_tunnel_ttl_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_ttl_mode_t ), + .conditions = { + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP ), + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP_GRE ), + }, + + // TODO condition is more complex since once is valid and once is mandatory + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL, + .attrid = SAI_TUNNEL_ATTR_DECAP_DSCP_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, // { .s32 = SAI_TUNNEL_DSCP_UNIFORM_MODEL }, + .enumtypestr = StringifyEnum ( sai_tunnel_dscp_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_dscp_mode_t ), + .conditions = { + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP ), + COND_ENUM ( SAI_TUNNEL_ATTR_TYPE, SAI_TUNNEL_IPINIP_GRE ), + }, + + // TODO condition is more complex since once is valid and once is mandatory + }, + +}; + +const size_t sai_tunnel_attr_metadata_count = sizeof(sai_tunnel_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_TUNNEL_MAP + +const sai_attr_metadata_t sai_tunnel_map_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_MAP, + .attrid = SAI_TUNNEL_MAP_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_tunnel_map_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_map_type_t ), + .conditions = { }, + + // TODO some extra logic may be needed + }, + +// { +// .objecttype = SAI_OBJECT_TYPE_TUNNEL_MAP, +// .attrid = SAI_TUNNEL_MAP_ATTR_MAP_TO_VALUE_LIST, +// .serializationtype = SAI_SERIALIZATION_TYPE_TUNNEL_MAP_LIST, // TODO declare +// .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, +// .allowedobjecttypes = { }, +// .allownullobjectid = false, +// .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, +// .defaultvalue = { }, +// .enumtypestr = NULL, +// .enumallowedvalues = { }, +// .conditions = { }, +// +// // TODO some extra logic may be needed on map +// }, + +}; + +const size_t sai_tunnel_map_attr_metadata_count = sizeof(sai_tunnel_map_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY + +const sai_attr_metadata_t sai_tunnel_table_entry_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, + .attrid = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_VR_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_VIRTUAL_ROUTER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, + .attrid = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_tunnel_term_table_entry_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_term_table_entry_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, + .attrid = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_IP_ADDRESS, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, + .attrid = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_SRC_IP, + .serializationtype = SAI_SERIALIZATION_TYPE_IP_ADDRESS, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { COND_ENUM ( SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TYPE, SAI_TUNNEL_TERM_TABLE_ENTRY_P2P ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, + .attrid = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TUNNEL_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = StringifyEnum ( sai_tunnel_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_tunnel_type_t ), + .conditions = { COND_ENUM ( SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_TYPE, SAI_TUNNEL_TERM_TABLE_ENTRY_P2P ) }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY, + .attrid = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_TUNNEL }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO some additional logic may be needed for tunnel type IPinIP etc + }, +}; + +const size_t sai_tunnel_table_entry_attr_metadata_count = sizeof(sai_tunnel_table_entry_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_udf.cpp b/meta/sai_meta_udf.cpp new file mode 100644 index 000000000000..16fc98c6a1db --- /dev/null +++ b/meta/sai_meta_udf.cpp @@ -0,0 +1,215 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_UDF + +uint32_t hash_mask_default_length = 2; +uint8_t hash_mask_default_list[] = { 0xFF, 0xFF }; + +const sai_attribute_value_t hash_mask_default_value = { + .u8list = { + .count = hash_mask_default_length, + .list = hash_mask_default_list + } +}; + +DEFINE_ENUM_VALUES(sai_udf_base_t) +{ + SAI_UDF_BASE_L2, + SAI_UDF_BASE_L3, + SAI_UDF_BASE_L4 +}; + +DEFINE_ENUM_VALUES(sai_udf_group_type_t) +{ + SAI_UDF_GROUP_GENERIC, + SAI_UDF_GROUP_HASH +}; + +const sai_attr_metadata_t sai_udf_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_UDF, + .attrid = SAI_UDF_ATTR_MATCH_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_UDF_MATCH }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF, + .attrid = SAI_UDF_ATTR_GROUP_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_UDF_GROUP }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF, + .attrid = SAI_UDF_ATTR_BASE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_UDF_BASE_L2 }, + .enumtypestr = StringifyEnum ( sai_udf_base_t ), + .enumallowedvalues = ENUM_VALUES ( sai_udf_base_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF, + .attrid = SAI_UDF_ATTR_OFFSET, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF, + .attrid = SAI_UDF_ATTR_HASH_MASK, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8_LIST, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = hash_mask_default_value, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO extra logic is needed here to validate list length (create and set) + }, +}; + +const size_t sai_udf_attr_metadata_count = sizeof(sai_udf_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_UDF_MATCH + +const sai_attr_metadata_t sai_udf_match_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_UDF_MATCH, + .attrid = SAI_UDF_MATCH_ATTR_L2_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, // default to none + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF_MATCH, + .attrid = SAI_UDF_MATCH_ATTR_L3_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, // default to none + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF_MATCH, + .attrid = SAI_UDF_MATCH_ATTR_GRE_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT16, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { }, // default to none + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF_MATCH, + .attrid = SAI_UDF_MATCH_ATTR_PRIORITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_udf_match_attr_metadata_count = sizeof(sai_udf_match_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_UDF_GROUP + +const sai_attr_metadata_t sai_udf_group_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_UDF_GROUP, + .attrid = SAI_UDF_GROUP_ATTR_UDF_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_UDF }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF_GROUP, + .attrid = SAI_UDF_GROUP_ATTR_TYPE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_UDF_GROUP_GENERIC }, + .enumtypestr = StringifyEnum ( sai_udf_group_type_t ), + .enumallowedvalues = ENUM_VALUES ( sai_udf_group_type_t ), + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_UDF_GROUP, + .attrid = SAI_UDF_GROUP_ATTR_LENGTH, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, +}; + +const size_t sai_udf_group_attr_metadata_count = sizeof(sai_udf_group_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_vlan.cpp b/meta/sai_meta_vlan.cpp new file mode 100644 index 000000000000..03789f0124b4 --- /dev/null +++ b/meta/sai_meta_vlan.cpp @@ -0,0 +1,138 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_VLAN + +DEFINE_ENUM_VALUES(sai_vlan_tagging_mode_t) +{ + SAI_VLAN_PORT_UNTAGGED, + SAI_VLAN_PORT_TAGGED, + SAI_VLAN_PORT_PRIORITY_TAGGED +}; + +const sai_attr_metadata_t sai_vlan_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_VLAN, + .attrid = SAI_VLAN_ATTR_MEMBER_LIST, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_LIST, + .flags = SAI_ATTR_FLAGS_READ_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_VLAN_MEMBER }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VLAN, + .attrid = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VLAN, + .attrid = SAI_VLAN_ATTR_STP_INSTANCE, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { SAI_OBJECT_TYPE_STP_INSTANCE }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .oid = SAI_NULL_OBJECT_ID }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO default to default STP + }, + + { + .objecttype = SAI_OBJECT_TYPE_VLAN, + .attrid = SAI_VLAN_ATTR_LEARN_DISABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VLAN, + .attrid = SAI_VLAN_ATTR_META_DATA, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_ATTR_RANGE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO default value inside SAI_SWITCH_ATTR_VLAN_USER_META_DATA_RANGE + }, +}; + +const size_t sai_vlan_attr_metadata_count = sizeof(sai_vlan_attr_metadata)/sizeof(sai_attr_metadata_t); + +// METADATA for SAI_OBJECT_TYPE_VLAN_MEMBER + +const sai_attr_metadata_t sai_vlan_member_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_VLAN_MEMBER, + .attrid = SAI_VLAN_MEMBER_ATTR_VLAN_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT16, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VLAN_MEMBER, + .attrid = SAI_VLAN_MEMBER_ATTR_PORT_ID, + .serializationtype = SAI_SERIALIZATION_TYPE_OBJECT_ID, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { SAI_OBJECT_TYPE_PORT }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_VLAN_MEMBER, + .attrid = SAI_VLAN_MEMBER_ATTR_TAGGING_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_VLAN_PORT_UNTAGGED }, + .enumtypestr = StringifyEnum ( sai_vlan_tagging_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_vlan_tagging_mode_t ), + .conditions = { }, + }, +}; + +const size_t sai_vlan_member_attr_metadata_count = sizeof(sai_vlan_member_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/sai_meta_wred.cpp b/meta/sai_meta_wred.cpp new file mode 100644 index 000000000000..4535b5bc78c6 --- /dev/null +++ b/meta/sai_meta_wred.cpp @@ -0,0 +1,269 @@ +#include "sai_meta.h" + +// METADATA for SAI_OBJECT_TYPE_WRED + +DEFINE_ENUM_VALUES(sai_ecn_mark_mode_t) +{ + SAI_ECN_MARK_MODE_NONE, + SAI_ECN_MARK_MODE_GREEN, + SAI_ECN_MARK_MODE_YELLOW, + SAI_ECN_MARK_MODE_RED, + SAI_ECN_MARK_MODE_GREEN_YELLOW, + SAI_ECN_MARK_MODE_GREEN_RED, + SAI_ECN_MARK_MODE_YELLOW_RED, + SAI_ECN_MARK_MODE_ALL +}; + +const sai_attr_metadata_t sai_wred_attr_metadata[] = { + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_ECN_MARK_MODE, + .serializationtype = SAI_SERIALIZATION_TYPE_INT32, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .s32 = SAI_ECN_MARK_MODE_NONE }, + .enumtypestr = StringifyEnum ( sai_ecn_mark_mode_t ), + .enumallowedvalues = ENUM_VALUES ( sai_ecn_mark_mode_t ), + .conditions = { }, + + // NOTE: attribute is CREATE_ONLY since when type will change it may impact thresholds + }, + + // GREEN + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_GREEN_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // NOTE: attribute is CREATE_ONLY since when type will change it may impact thresholds + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_GREEN_MIN_THRESHOLD, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_BOOL ( SAI_WRED_ATTR_GREEN_ENABLE, true ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_YELLOW ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_ALL ), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_GREEN_MAX_THRESHOLD, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_BOOL ( SAI_WRED_ATTR_GREEN_ENABLE, true ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_YELLOW ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_ALL ), + }, + + // TODO range check 1.. max + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_GREEN_DROP_PROBABILITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 100 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + + // YELLOW + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_YELLOW_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_YELLOW_MIN_THRESHOLD, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_BOOL ( SAI_WRED_ATTR_YELLOW_ENABLE, true ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_YELLOW ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_YELLOW ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_YELLOW_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_ALL ), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_YELLOW_MAX_THRESHOLD, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_BOOL ( SAI_WRED_ATTR_YELLOW_ENABLE, true ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_YELLOW ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_YELLOW ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_YELLOW_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_ALL ), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_YELLOW_DROP_PROBABILITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 100 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // RED + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_RED_ENABLE, + .serializationtype = SAI_SERIALIZATION_TYPE_BOOL, + .flags = SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .booldata = false }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_RED_MIN_THRESHOLD, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_BOOL ( SAI_WRED_ATTR_RED_ENABLE, true ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_YELLOW_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_ALL ), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_RED_MAX_THRESHOLD, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_NONE, + .defaultvalue = { }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { + COND_BOOL ( SAI_WRED_ATTR_RED_ENABLE, true ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_GREEN_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_YELLOW_RED ), + COND_ENUM ( SAI_WRED_ATTR_ECN_MARK_MODE, SAI_ECN_MARK_MODE_ALL ), + }, + }, + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_RED_DROP_PROBABILITY, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT32, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u32 = 100 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + }, + + // RED END + + { + .objecttype = SAI_OBJECT_TYPE_WRED, + .attrid = SAI_WRED_ATTR_WEIGHT, + .serializationtype = SAI_SERIALIZATION_TYPE_UINT8, + .flags = SAI_ATTR_FLAGS_CREATE_AND_SET, + .allowedobjecttypes = { }, + .allownullobjectid = false, + .defaultvaluetype = SAI_DEFAULT_VALUE_TYPE_CONST, + .defaultvalue = { .u8 = 0 }, + .enumtypestr = NULL, + .enumallowedvalues = { }, + .conditions = { }, + + // TODO validte range 0 .. 15 + }, +}; + +const size_t sai_wred_attr_metadata_count = sizeof(sai_wred_attr_metadata)/sizeof(sai_attr_metadata_t); diff --git a/meta/tests.cpp b/meta/tests.cpp new file mode 100644 index 000000000000..8120c7be27d7 --- /dev/null +++ b/meta/tests.cpp @@ -0,0 +1,3335 @@ +#include "sai_meta.h" +#include "sai_extra.h" + +#include + +#include +#include + +class SaiAttrWrapper; +extern std::unordered_map>> ObjectAttrHash; +extern bool is_ipv6_mask_valid(const uint8_t* mask); +extern bool object_exists(const std::string& key); +extern bool object_reference_exists(sai_object_id_t oid); +extern void object_reference_inc(sai_object_id_t oid); +extern void object_reference_dec(sai_object_id_t oid); +extern void object_reference_dec(const sai_object_list_t& list); +extern void object_reference_insert(sai_object_id_t oid); +extern int32_t object_reference_count(sai_object_id_t oid); +extern std::string get_object_meta_key_string( + _In_ const sai_object_meta_key_t& meta_key); + +std::string construct_key( + _In_ const sai_object_meta_key_t& meta_key, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t* attr_list); + +sai_object_id_t create_dummy_object_id( + _In_ sai_object_type_t objecttype) +{ + SWSS_LOG_ENTER(); + + if ((objecttype <= SAI_OBJECT_TYPE_NULL) || + (objecttype >= SAI_OBJECT_TYPE_MAX)) + { + SWSS_LOG_ERROR("invalid objcttype: %d", objecttype); + + return SAI_OBJECT_TYPE_NULL; + } + + static uint64_t index = 0; + + sai_object_id_t oid = (((sai_object_id_t)objecttype) << 48) | ++index; + + SWSS_LOG_DEBUG("created oid 0x%llx", oid); + + return oid; +} + +sai_object_type_t sai_object_type_query( + _In_ sai_object_id_t oid) +{ + sai_object_type_t objecttype = (sai_object_type_t)(oid >> 48); + + if ((objecttype <= SAI_OBJECT_TYPE_NULL) || + (objecttype >= SAI_OBJECT_TYPE_MAX)) + { + SWSS_LOG_ERROR("invalid oid %d", oid); + + return SAI_OBJECT_TYPE_NULL; + } + + return objecttype; +} + +// SWITCH DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_switch( + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_switch( + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_switch( + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_switch( + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// FDB ENTRY DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_create_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_create_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_remove_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_remove_fdb_entry( + _In_ const sai_fdb_entry_t* fdb_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// NEIGHBOR ENTRY DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_create_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_create_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_remove_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_remove_neighbor_entry( + _In_ const sai_neighbor_entry_t* neighbor_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// VLAN DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_vlan_id( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_vlan_id( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_vlan_id( + _In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_vlan_id( + _In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_create_vlan_id( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_create_vlan_id( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_remove_vlan_id( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_remove_vlan_id_entry( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// ROUTE ENTRY DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_create_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_create_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_remove_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_remove_route_entry( + _In_ const sai_unicast_route_entry_t* unicast_route_entry) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// TRAP DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_trap( + _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// GENERIC DUMMY FUNCTIONS + +sai_status_t dummy_success_sai_set_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t oid, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_set_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t oid, + _In_ const sai_attribute_t *attr) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_get_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t oid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_get_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t oid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_create_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t* oid, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + *oid = create_dummy_object_id(object_type); + + if (*oid == SAI_NULL_OBJECT_ID) + { + return SAI_STATUS_FAILURE; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_create_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t* oid, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +sai_status_t dummy_success_sai_remove_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t dummy_failure_sai_remove_oid( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t oid) +{ + SWSS_LOG_ENTER(); + + return SAI_STATUS_FAILURE; +} + +// META ASSERTS + +#define META_ASSERT_SUCCESS(x) \ + if (x != SAI_STATUS_SUCCESS) \ +{\ + SWSS_LOG_ERROR("expected success");\ + throw;\ +} + +#define META_ASSERT_FAIL(x) \ + if (x == SAI_STATUS_SUCCESS) \ +{\ + SWSS_LOG_ERROR("expected failure");\ + throw;\ +} + +#define META_ASSERT_TRUE(x) \ + if (!(x)) \ +{\ + SWSS_LOG_ERROR("assert true failed '%s'", # x);\ + throw;\ +} + +// SWITCH TESTS + +sai_status_t switch_get_virtual_router_id( + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + attr_list[0].value.u32 = 32; + attr_list[1].value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + + return SAI_STATUS_SUCCESS; +}; + +void test_switch_set() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + status = meta_sai_set_switch(NULL, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + status = meta_sai_set_switch(&attr, NULL); + META_ASSERT_FAIL(status); + + // id outside range + attr.id = -1; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = meta_sai_set_switch(&attr, &dummy_failure_sai_set_switch); + META_ASSERT_FAIL(status); + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + attr.value.s32 = 0x1000; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + // enum + attr.id = SAI_SWITCH_ATTR_SWITCHING_MODE; + attr.value.s32 = SAI_SWITCHING_MODE_STORE_AND_FORWARD; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + // bool + attr.id = SAI_SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE; + attr.value.booldata = SAI_SWITCHING_MODE_STORE_AND_FORWARD; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + // mac + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; + memcpy(attr.value.mac, mac, sizeof(mac)); + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + // uint8 + attr.id = SAI_SWITCH_ATTR_QOS_DEFAULT_TC; + attr.value.u8 = 0x11; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + // object id with not allowed null + + // null oid + attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + // wrong object type + attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_LAG); + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + // valid object (object must exist) + attr.id = SAI_SWITCH_ATTR_LAG_HASH_IPV6; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + + object_reference_insert(attr.value.oid); + + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + META_ASSERT_TRUE(object_reference_count(attr.value.oid) == 1); + + // object id with allowed null + + // null oid + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + // wrong object + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_LAG); + + object_reference_insert(attr.value.oid); + + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_FAIL(status); + + // good object + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_QOS_MAPS); + + sai_object_id_t oid = attr.value.oid; + + object_reference_insert(attr.value.oid); + + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + META_ASSERT_TRUE(object_reference_count(attr.value.oid) == 1); + + attr.id = SAI_SWITCH_ATTR_QOS_DOT1P_TO_TC_MAP; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = meta_sai_set_switch(&attr, &dummy_success_sai_set_switch); + META_ASSERT_SUCCESS(status); + + // check if it was decreased + META_ASSERT_TRUE(object_reference_count(oid) == 0); +} + +void test_switch_get() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = meta_sai_get_switch(0, &attr, &dummy_success_sai_get_switch); + META_ASSERT_FAIL(status); + + status = meta_sai_get_switch(1000, &attr, &dummy_success_sai_get_switch); + META_ASSERT_FAIL(status); + + status = meta_sai_get_switch(1, NULL, &dummy_success_sai_get_switch); + META_ASSERT_FAIL(status); + + status = meta_sai_get_switch(1, NULL, &dummy_success_sai_get_switch); + META_ASSERT_FAIL(status); + + status = meta_sai_get_switch(1, &attr, NULL); + META_ASSERT_FAIL(status); + + attr.id = -1; + status = meta_sai_get_switch(1, &attr, &dummy_success_sai_get_switch); + META_ASSERT_FAIL(status); + + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + attr.value.u32 = 0; + status = meta_sai_get_switch(1, &attr, &dummy_success_sai_get_switch); + META_ASSERT_SUCCESS(status); + + sai_attribute_t attr1; + attr1.id = SAI_SWITCH_ATTR_PORT_NUMBER; + + sai_attribute_t attr2; + attr2.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + sai_attribute_t list[2] = { attr1, attr2 }; + + status = meta_sai_get_switch(2, list, &switch_get_virtual_router_id); + META_ASSERT_SUCCESS(status); +} + +// FDB TESTS + +sai_status_t fdb_entry_get_port_id( + _In_ const sai_fdb_entry_t* fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + attr_list[0].value.s32 = SAI_FDB_ENTRY_STATIC; + attr_list[1].value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + + return SAI_STATUS_SUCCESS; +}; + +void test_fdb_entry_create() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.vlan_id = 1; + + sai_object_id_t port = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + object_reference_insert(port); + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + status = meta_sai_create_fdb_entry(&fdb_entry, 0, &attr, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_create_fdb_entry(&fdb_entry, 1, NULL, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("fdb entry is null"); + status = meta_sai_create_fdb_entry(NULL, 1, &attr, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + sai_attribute_t list1[4] = { }; + + sai_attribute_t &attr1 = list1[0]; + sai_attribute_t &attr2 = list1[1]; + sai_attribute_t &attr3 = list1[2]; + sai_attribute_t &attr4 = list1[3]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_PORT_ID; + attr2.value.oid = port; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr4.id = -1; + + SWSS_LOG_NOTICE("create function is null"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list1, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("invalid attribute id"); + status = meta_sai_create_fdb_entry(&fdb_entry, 4, list1, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("missing mandatory attribute"); + status = meta_sai_create_fdb_entry(&fdb_entry, 2, list1, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + attr2.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + + SWSS_LOG_NOTICE("invalid attribute value on oid"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list1, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + attr2.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + + SWSS_LOG_NOTICE("non existing object on oid"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list1, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + attr2.value.oid = port; + attr3.value.s32 = 0x100; + + SWSS_LOG_NOTICE("invalid attribute value on enum"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list1, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_attribute_t list2[4] = { attr1, attr2, attr3, attr3 }; + + SWSS_LOG_NOTICE("repeated attribute id"); + status = meta_sai_create_fdb_entry(&fdb_entry, 4, list2, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list2, &dummy_success_sai_create_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("already exists"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list2, &dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); +} + +void test_fdb_entry_remove() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.vlan_id = 1; + + sai_object_id_t port = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + object_reference_insert(port); + + sai_attribute_t list1[3] = { }; + + sai_attribute_t &attr1 = list1[0]; + sai_attribute_t &attr2 = list1[1]; + sai_attribute_t &attr3 = list1[2]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_PORT_ID; + attr2.value.oid = port; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("creating fdb entry"); + status = meta_sai_create_fdb_entry(&fdb_entry, 3, list1, &dummy_success_sai_create_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("fdb_entry is null"); + status = meta_sai_remove_fdb_entry(NULL, &dummy_success_sai_remove_fdb_entry); + META_ASSERT_FAIL(status); + + fdb_entry.vlan_id = 2; + + SWSS_LOG_NOTICE("invalid vlan"); + status = meta_sai_remove_fdb_entry(&fdb_entry, &dummy_success_sai_remove_fdb_entry); + META_ASSERT_FAIL(status); + + fdb_entry.vlan_id = 1; + fdb_entry.mac_address[0] = 1; + + SWSS_LOG_NOTICE("invalid mac"); + status = meta_sai_remove_fdb_entry(&fdb_entry, &dummy_success_sai_remove_fdb_entry); + META_ASSERT_FAIL(status); + + fdb_entry.mac_address[0] = 0x11; + + sai_object_meta_key_t meta = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = fdb_entry } }; + + std::string key = get_object_meta_key_string(meta); + + META_ASSERT_TRUE(object_exists(key)); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_fdb_entry(&fdb_entry, &dummy_success_sai_remove_fdb_entry); + META_ASSERT_SUCCESS(status); + + META_ASSERT_TRUE(!object_exists(key)); +} + +void test_fdb_entry_set() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.vlan_id = 1; + + // TODO we should use CREATE for this + sai_object_meta_key_t meta_key_fdb = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = fdb_entry } }; + std::string fdb_key = get_object_meta_key_string(meta_key_fdb); + ObjectAttrHash[fdb_key] = { }; + + // attr is null + status = meta_sai_set_fdb_entry(&fdb_entry, NULL, &dummy_success_sai_set_fdb_entry); + META_ASSERT_FAIL(status); + + // fdb entry is null + status = meta_sai_set_fdb_entry(NULL, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_FAIL(status); + + // setting read only object + attr.id = SAI_FDB_ENTRY_ATTR_PORT_ID; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_FAIL(status); + + // setting invalid attrib id + attr.id = -1; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_FAIL(status); + + // invalid vlan + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_STATIC; + fdb_entry.vlan_id = 2; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_FAIL(status); + + // vlan outside range + fdb_entry.vlan_id = MAXIMUM_VLAN_NUMBER + 1; + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_STATIC; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_FAIL(status); + + // correct + fdb_entry.vlan_id = 1; + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_STATIC; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_SUCCESS(status); + + // TODO check references ? +} + +void test_fdb_entry_get() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.vlan_id = 1; + + // TODO we should use CREATE for this + sai_object_meta_key_t meta_key_fdb = { .object_type = SAI_OBJECT_TYPE_FDB, .key = { .fdb_entry = fdb_entry } }; + std::string fdb_key = get_object_meta_key_string(meta_key_fdb); + ObjectAttrHash[fdb_key] = { }; + + fdb_entry.vlan_id = 1; + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_STATIC; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get test"); + + // zero attribute count + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + status = meta_sai_get_fdb_entry(&fdb_entry, 0, &attr, &dummy_success_sai_get_fdb_entry); + META_ASSERT_FAIL(status); + + // attr is null + status = meta_sai_get_fdb_entry(&fdb_entry, 1, NULL, &dummy_success_sai_get_fdb_entry); + META_ASSERT_FAIL(status); + + // fdb entry is null + status = meta_sai_get_fdb_entry(NULL, 1, &attr, &dummy_success_sai_get_fdb_entry); + META_ASSERT_FAIL(status); + + // get function is null + status = meta_sai_get_fdb_entry(&fdb_entry, 1, &attr, NULL); + META_ASSERT_FAIL(status); + + // attr id out of range + attr.id = -1; + status = meta_sai_get_fdb_entry(&fdb_entry, 1, &attr, &dummy_success_sai_get_fdb_entry); + META_ASSERT_FAIL(status); + + // correct single valid attribute + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + status = meta_sai_get_fdb_entry(&fdb_entry, 1, &attr, &dummy_success_sai_get_fdb_entry); + META_ASSERT_SUCCESS(status); + + // correct 2 attributes + sai_attribute_t attr1; + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + + sai_attribute_t attr2; + attr2.id = SAI_FDB_ENTRY_ATTR_PORT_ID; + sai_attribute_t list[2] = { attr1, attr2 }; + + status = meta_sai_get_fdb_entry(&fdb_entry, 2, list, &fdb_entry_get_port_id); + META_ASSERT_SUCCESS(status); +} + +void test_fdb_entry_flow() +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_TIMER("fdb flow"); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_fdb_entry_t fdb_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + memcpy(fdb_entry.mac_address, mac, sizeof(mac)); + fdb_entry.vlan_id = 1; + + sai_object_id_t lag = create_dummy_object_id(SAI_OBJECT_TYPE_LAG); + object_reference_insert(lag); + + sai_attribute_t list[4] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[2]; + sai_attribute_t &attr4 = list[3]; + + attr1.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr1.value.s32 = SAI_FDB_ENTRY_STATIC; + + attr2.id = SAI_FDB_ENTRY_ATTR_PORT_ID; + attr2.value.oid = lag; + + attr3.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; + attr3.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr4.id = SAI_FDB_ENTRY_ATTR_META_DATA; + attr4.value.u32 = 0x12345678; + + SWSS_LOG_NOTICE("create"); + status = meta_sai_create_fdb_entry(&fdb_entry, 4, list, dummy_success_sai_create_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("create existing"); + status = meta_sai_create_fdb_entry(&fdb_entry, 4, list, dummy_success_sai_create_fdb_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("set"); + attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + attr.value.s32 = SAI_FDB_ENTRY_DYNAMIC; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set"); + attr.id = SAI_FDB_ENTRY_ATTR_META_DATA; + attr.value.u32 = SAI_FDB_ENTRY_DYNAMIC; + status = meta_sai_set_fdb_entry(&fdb_entry, &attr, &dummy_success_sai_set_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get"); + status = meta_sai_get_fdb_entry(&fdb_entry, 4, list, &dummy_success_sai_get_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove"); + status = meta_sai_remove_fdb_entry(&fdb_entry, &dummy_success_sai_remove_fdb_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove non existing"); + status = meta_sai_remove_fdb_entry(&fdb_entry, &dummy_success_sai_remove_fdb_entry); + META_ASSERT_FAIL(status); +} + +// NEIGHBOR TESTS + +void test_neighbor_entry_create() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_neighbor_entry_t neighbor_entry; + + // TODO we should use create + sai_object_id_t rif = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + object_reference_insert(rif); + sai_object_meta_key_t meta_key_rif = { .object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE, .key = { .object_id = rif } }; + std::string rif_key = get_object_meta_key_string(meta_key_rif); + ObjectAttrHash[rif_key] = { }; + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 0, &attr, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 1, NULL, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("neighbor entry is null"); + status = meta_sai_create_neighbor_entry(NULL, 1, &attr, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[2]; + + attr1.id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr3.id = -1; + + SWSS_LOG_NOTICE("create function is null"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("invalid attribute id"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 3, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD + 0x100; + SWSS_LOG_NOTICE("invalid attribute value on enum"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_attribute_t list2[4] = { attr1, attr2, attr2 }; + + SWSS_LOG_NOTICE("repeated attribute id"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 3, list2, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct ipv4"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list2, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list2, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("already exists"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list2, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); +} + +void test_neighbor_entry_remove() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[2] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + // TODO we should use create + sai_object_id_t rif = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + object_reference_insert(rif); + sai_object_meta_key_t meta_key_rif = { .object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE, .key = { .object_id = rif } }; + std::string rif_key = get_object_meta_key_string(meta_key_rif); + ObjectAttrHash[rif_key] = { }; + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("neighbor_entry is null"); + status = meta_sai_remove_neighbor_entry(NULL, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_FAIL(status); + + neighbor_entry.rif_id = SAI_NULL_OBJECT_ID; + + SWSS_LOG_NOTICE("invalid object id null"); + status = meta_sai_remove_neighbor_entry(&neighbor_entry, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_FAIL(status); + + neighbor_entry.rif_id = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + + SWSS_LOG_NOTICE("invalid object id hash"); + status = meta_sai_remove_neighbor_entry(&neighbor_entry, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_FAIL(status); + + neighbor_entry.rif_id = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + + SWSS_LOG_NOTICE("invalid object id router"); + status = meta_sai_remove_neighbor_entry(&neighbor_entry, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_FAIL(status); + + neighbor_entry.rif_id = rif; + + sai_object_meta_key_t meta = { .object_type = SAI_OBJECT_TYPE_NEIGHBOR, .key = { .neighbor_entry = neighbor_entry } }; + + std::string key = get_object_meta_key_string(meta); + + META_ASSERT_TRUE(object_exists(key)); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_neighbor_entry(&neighbor_entry, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_SUCCESS(status); + + META_ASSERT_TRUE(!object_exists(key)); +} + +void test_neighbor_entry_set() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_attribute_t attr; + + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[2] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + // TODO we should use create + sai_object_id_t rif = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + object_reference_insert(rif); + sai_object_meta_key_t meta_key_rif = { .object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE, .key = { .object_id = rif } }; + std::string rif_key = get_object_meta_key_string(meta_key_rif); + ObjectAttrHash[rif_key] = { }; + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_set_neighbor_entry(&neighbor_entry, NULL, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("neighbor entry is null"); + status = meta_sai_set_neighbor_entry(NULL, &attr, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("setting invalid attrib id"); + attr.id = -1; + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("value outside range"); + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr.value.s32 = 0x100; + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_FAIL(status); + + // correct + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_SUCCESS(status); +} + +void test_neighbor_entry_get() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_attribute_t attr; + + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[2] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + // TODO we should use create + sai_object_id_t rif = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + object_reference_insert(rif); + sai_object_meta_key_t meta_key_rif = { .object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE, .key = { .object_id = rif } }; + std::string rif_key = get_object_meta_key_string(meta_key_rif); + ObjectAttrHash[rif_key] = { }; + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(neighbor_entry.ip_address.addr.ip6, ip6, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get test"); + + SWSS_LOG_NOTICE("zero attribute count"); + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + status = meta_sai_get_neighbor_entry(&neighbor_entry, 0, &attr, &dummy_success_sai_get_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_get_neighbor_entry(&neighbor_entry, 1, NULL, &dummy_success_sai_get_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("neighbor entry is null"); + status = meta_sai_get_neighbor_entry(NULL, 1, &attr, &dummy_success_sai_get_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("get function is null"); + status = meta_sai_get_neighbor_entry(&neighbor_entry, 1, &attr, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr id out of range"); + attr.id = -1; + status = meta_sai_get_neighbor_entry(&neighbor_entry, 1, &attr, &dummy_success_sai_get_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct single valid attribute"); + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + status = meta_sai_get_neighbor_entry(&neighbor_entry, 1, &attr, &dummy_success_sai_get_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct 2 attributes"); + + sai_attribute_t attr3; + sai_attribute_t attr4; + attr3.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr3.value.s32 = 1; + attr4.id = SAI_NEIGHBOR_ATTR_NO_HOST_ROUTE; + + sai_attribute_t list2[2] = { attr3, attr4 }; + status = meta_sai_get_neighbor_entry(&neighbor_entry, 2, list2, &dummy_success_sai_get_neighbor_entry); + META_ASSERT_SUCCESS(status); +} + +void test_neighbor_entry_flow() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_neighbor_entry_t neighbor_entry; + + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + sai_attribute_t list[4] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[1]; + sai_attribute_t &attr4 = list[1]; + + attr1.id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; + memcpy(attr1.value.mac, mac, 6); + + attr2.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr3.id = SAI_NEIGHBOR_ATTR_NO_HOST_ROUTE; + attr3.value.booldata = true; + + attr4.id = SAI_NEIGHBOR_ATTR_META_DATA; + attr4.value.u32 = 1; + + // TODO we should use create + sai_object_id_t rif = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + object_reference_insert(rif); + sai_object_meta_key_t meta_key_rif = { .object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE, .key = { .object_id = rif } }; + std::string rif_key = get_object_meta_key_string(meta_key_rif); + ObjectAttrHash[rif_key] = { }; + + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = htonl(0x0a00000f); + neighbor_entry.rif_id = rif; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct ipv4"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct ipv4 existing"); + status = meta_sai_create_neighbor_entry(&neighbor_entry, 2, list, &dummy_success_sai_create_neighbor_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("set"); + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr1, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set"); + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr2, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set"); + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr3, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set"); + status = meta_sai_set_neighbor_entry(&neighbor_entry, &attr4, &dummy_success_sai_set_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove"); + status = meta_sai_remove_neighbor_entry(&neighbor_entry, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove existing"); + status = meta_sai_remove_neighbor_entry(&neighbor_entry, &dummy_success_sai_remove_neighbor_entry); + META_ASSERT_FAIL(status); +} + +// VLAN TESTS + +void test_vlan_create() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_vlan_id_t vlan_id = 2; + + // TODO we should use create + sai_object_id_t stp = create_dummy_object_id(SAI_OBJECT_TYPE_STP_INSTANCE); + object_reference_insert(stp); + sai_object_meta_key_t meta_key_stp = { .object_type = SAI_OBJECT_TYPE_STP_INSTANCE, .key = { .object_id = stp } }; + std::string stp_key = get_object_meta_key_string(meta_key_stp); + ObjectAttrHash[stp_key] = { }; + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("existing vlan"); + status = meta_sai_create_vlan(1, &dummy_success_sai_create_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("vlan outside range"); + status = meta_sai_create_vlan(MAXIMUM_VLAN_NUMBER + 1, &dummy_success_sai_create_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("create is null"); + status = meta_sai_create_vlan(vlan_id, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("existing"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_FAIL(status); +} + +void test_vlan_remove() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_vlan_id_t vlan_id = 2; + + // TODO we should use create + sai_object_id_t stp = create_dummy_object_id(SAI_OBJECT_TYPE_STP_INSTANCE); + object_reference_insert(stp); + sai_object_meta_key_t meta_key_stp = { .object_type = SAI_OBJECT_TYPE_STP_INSTANCE, .key = { .object_id = stp } }; + std::string stp_key = get_object_meta_key_string(meta_key_stp); + ObjectAttrHash[stp_key] = { }; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("invalid vlan"); + status = meta_sai_remove_vlan(0, &dummy_success_sai_remove_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("default vlan"); + status = meta_sai_remove_vlan(DEFAULT_VLAN_NUMBER, &dummy_success_sai_remove_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("remove is null"); + status = meta_sai_remove_vlan(vlan_id, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_vlan(vlan_id, &dummy_success_sai_remove_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("non existing"); + status = meta_sai_remove_vlan(vlan_id, &dummy_success_sai_remove_vlan_id); + META_ASSERT_FAIL(status); +} + +void test_vlan_set() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_attribute_t attr; + + sai_vlan_id_t vlan_id = 2; + + // TODO we should use create + sai_object_id_t stp = create_dummy_object_id(SAI_OBJECT_TYPE_STP_INSTANCE); + object_reference_insert(stp); + sai_object_meta_key_t meta_key_stp = { .object_type = SAI_OBJECT_TYPE_STP_INSTANCE, .key = { .object_id = stp } }; + std::string stp_key = get_object_meta_key_string(meta_key_stp); + ObjectAttrHash[stp_key] = { }; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("invalid vlan"); + status = meta_sai_set_vlan(0, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("invalid vlan"); + status = meta_sai_set_vlan(3, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("set is null"); + status = meta_sai_set_vlan(vlan_id, &attr, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_set_vlan(vlan_id, NULL, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + attr.id = -1; + + SWSS_LOG_NOTICE("invalid attribute"); + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + + SWSS_LOG_NOTICE("read only"); + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + attr.value.u32 = 1; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("null stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("wrong type on stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("wrong type on stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_STP_INSTANCE); + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("good stp oid"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = stp; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + attr.value.booldata = false; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("metadat"); + attr.id = SAI_VLAN_ATTR_META_DATA; + attr.value.u32 = 1; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); +} + +void test_vlan_get() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_attribute_t attr; + + sai_vlan_id_t vlan_id = 2; + + // TODO we should use create + sai_object_id_t stp = create_dummy_object_id(SAI_OBJECT_TYPE_STP_INSTANCE); + object_reference_insert(stp); + sai_object_meta_key_t meta_key_stp = { .object_type = SAI_OBJECT_TYPE_STP_INSTANCE, .key = { .object_id = stp } }; + std::string stp_key = get_object_meta_key_string(meta_key_stp); + ObjectAttrHash[stp_key] = { }; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get tests"); + + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + + SWSS_LOG_NOTICE("invalid vlan"); + status = meta_sai_get_vlan(0, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("invalid vlan"); + status = meta_sai_get_vlan(3, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("get is null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_get_vlan(vlan_id, 1, NULL, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("zero attributes"); + status = meta_sai_get_vlan(vlan_id, 0, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); + + attr.id = -1; + + SWSS_LOG_NOTICE("invalid attribute"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + attr.value.objlist.count = 1; + attr.value.objlist.list = NULL; + + SWSS_LOG_NOTICE("read only null list"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); + + sai_object_id_t list[5] = { }; + + list[0] = SAI_NULL_OBJECT_ID; + list[1] = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + list[2] = create_dummy_object_id(SAI_OBJECT_TYPE_VLAN_MEMBER); + list[3] = stp; + + attr.value.objlist.count = 0; + attr.value.objlist.list = list; + + SWSS_LOG_NOTICE("readonly 0 count and not null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + attr.value.objlist.count = 5; + + SWSS_LOG_NOTICE("readonly count and not null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + attr.value.objlist.count = 0; + attr.value.objlist.list = NULL; + + SWSS_LOG_NOTICE("readonly count 0 and null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("metadata"); + attr.id = SAI_VLAN_ATTR_META_DATA; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); +} + +void test_vlan_flow() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_attribute_t attr; + + sai_status_t status; + + sai_vlan_id_t vlan_id = 2; + + // TODO we should use create + sai_object_id_t stp = create_dummy_object_id(SAI_OBJECT_TYPE_STP_INSTANCE); + object_reference_insert(stp); + sai_object_meta_key_t meta_key_stp = { .object_type = SAI_OBJECT_TYPE_STP_INSTANCE, .key = { .object_id = stp } }; + std::string stp_key = get_object_meta_key_string(meta_key_stp); + ObjectAttrHash[stp_key] = { }; + + SWSS_LOG_NOTICE("create"); + + SWSS_LOG_NOTICE("correct"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("existing"); + status = meta_sai_create_vlan(vlan_id, &dummy_success_sai_create_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("set"); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + attr.value.u32 = 1; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("good stp oid"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + attr.value.oid = stp; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + attr.value.booldata = false; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("metadat"); + attr.id = SAI_VLAN_ATTR_META_DATA; + attr.value.u32 = 1; + status = meta_sai_set_vlan(vlan_id, &attr, &dummy_success_sai_set_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get"); + + sai_object_id_t list[5] = { }; + + list[0] = SAI_NULL_OBJECT_ID; + list[1] = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + list[2] = create_dummy_object_id(SAI_OBJECT_TYPE_VLAN_MEMBER); + list[3] = stp; + + attr.value.objlist.count = 0; + attr.value.objlist.list = list; + + SWSS_LOG_NOTICE("readonly 0 count and not null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + attr.value.objlist.count = 5; + + SWSS_LOG_NOTICE("readonly count and not null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + attr.value.objlist.count = 0; + attr.value.objlist.list = NULL; + + SWSS_LOG_NOTICE("readonly count 0 and null"); + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("max learned addresses"); + attr.id = SAI_VLAN_ATTR_MAX_LEARNED_ADDRESSES; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("stp instance"); + attr.id = SAI_VLAN_ATTR_STP_INSTANCE; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("metadata"); + attr.id = SAI_VLAN_ATTR_META_DATA; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove"); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_vlan(vlan_id, &dummy_success_sai_remove_vlan_id); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("non existing"); + status = meta_sai_remove_vlan(vlan_id, &dummy_success_sai_remove_vlan_id); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("learn disable"); + attr.id = SAI_VLAN_ATTR_LEARN_DISABLE; + status = meta_sai_get_vlan(vlan_id, 1, &attr, &dummy_success_sai_get_vlan_id); + META_ASSERT_FAIL(status); +} + +// ROUTE TESTS + +void test_route_entry_create() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_unicast_route_entry_t route_entry; + + // TODO we should use create + sai_object_id_t vr = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + object_reference_insert(vr); + sai_object_meta_key_t meta_key_vr = { .object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, .key = { .object_id = vr } }; + std::string vr_key = get_object_meta_key_string(meta_key_vr); + ObjectAttrHash[vr_key] = { }; + + sai_object_id_t hop = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP); + object_reference_insert(hop); + sai_object_meta_key_t meta_key_hop = { .object_type = SAI_OBJECT_TYPE_NEXT_HOP, .key = { .object_id = hop } }; + std::string hop_key = get_object_meta_key_string(meta_key_hop); + ObjectAttrHash[hop_key] = { }; + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("zero attribute count (but there are mandatory attributes)"); + attr.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + status = meta_sai_create_route_entry(&route_entry, 0, &attr, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_create_route_entry(&route_entry, 1, NULL, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("route entry is null"); + status = meta_sai_create_route_entry(NULL, 1, &attr, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + sai_attribute_t &attr3 = list[2]; + + attr1.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + attr3.id = -1; + + SWSS_LOG_NOTICE("create function is null"); + status = meta_sai_create_route_entry(&route_entry, 2, list, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("invalid attribute id"); + status = meta_sai_create_route_entry(&route_entry, 3, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD + 0x100; + SWSS_LOG_NOTICE("invalid attribute value on enum"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + sai_attribute_t list2[4] = { attr1, attr2, attr2 }; + + SWSS_LOG_NOTICE("repeated attribute id"); + status = meta_sai_create_route_entry(&route_entry, 3, list2, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("wrong obejct type"); + attr1.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("non existing object"); + attr1.value.oid = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + int fam = 10; + attr1.value.oid = hop; + route_entry.destination.addr_family = (sai_ip_addr_family_t)fam; + + SWSS_LOG_NOTICE("wrong address family"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip62 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0x99}; + memcpy(route_entry.destination.addr.ip6, ip62, 16); + + sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xf7,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask2, 16); + + SWSS_LOG_NOTICE("invalid mask"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("already exists"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); +} + +void test_route_entry_remove() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_unicast_route_entry_t route_entry; + + // TODO we should use create + sai_object_id_t vr = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + object_reference_insert(vr); + sai_object_meta_key_t meta_key_vr = { .object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, .key = { .object_id = vr } }; + std::string vr_key = get_object_meta_key_string(meta_key_vr); + ObjectAttrHash[vr_key] = { }; + + sai_object_id_t hop = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP); + object_reference_insert(hop); + sai_object_meta_key_t meta_key_hop = { .object_type = SAI_OBJECT_TYPE_NEXT_HOP, .key = { .object_id = hop } }; + std::string hop_key = get_object_meta_key_string(meta_key_hop); + ObjectAttrHash[hop_key] = { }; + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("route_entry is null"); + status = meta_sai_remove_route_entry(NULL, &dummy_success_sai_remove_route_entry); + META_ASSERT_FAIL(status); + + route_entry.vr_id = SAI_NULL_OBJECT_ID; + + SWSS_LOG_NOTICE("invalid object id null"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_FAIL(status); + + route_entry.vr_id = create_dummy_object_id(SAI_OBJECT_TYPE_HASH); + + SWSS_LOG_NOTICE("invalid object id hash"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_FAIL(status); + + route_entry.vr_id = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + + SWSS_LOG_NOTICE("invalid object id router"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_FAIL(status); + + route_entry.vr_id = vr; + + sai_object_meta_key_t meta = { .object_type = SAI_OBJECT_TYPE_ROUTE, .key = { .route_entry = route_entry } }; + + std::string key = get_object_meta_key_string(meta); + + META_ASSERT_TRUE(object_exists(key)); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_SUCCESS(status); + + META_ASSERT_TRUE(!object_exists(key)); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_SUCCESS(status); +} + +void test_route_entry_set() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_unicast_route_entry_t route_entry; + + // TODO we should use create + sai_object_id_t vr = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + object_reference_insert(vr); + sai_object_meta_key_t meta_key_vr = { .object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, .key = { .object_id = vr } }; + std::string vr_key = get_object_meta_key_string(meta_key_vr); + ObjectAttrHash[vr_key] = { }; + + sai_object_id_t hop = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP); + object_reference_insert(hop); + sai_object_meta_key_t meta_key_hop = { .object_type = SAI_OBJECT_TYPE_NEXT_HOP, .key = { .object_id = hop } }; + std::string hop_key = get_object_meta_key_string(meta_key_hop); + ObjectAttrHash[hop_key] = { }; + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_set_route_entry(&route_entry, NULL, &dummy_success_sai_set_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("route entry is null"); + status = meta_sai_set_route_entry(NULL, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("setting invalid attrib id"); + attr.id = -1; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("value outside range"); + attr.id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr.value.s32 = 0x100; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct trap priority"); + attr.id = SAI_ROUTE_ATTR_TRAP_PRIORITY; + attr.value.u8 = 12; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr.value.oid = hop; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct metadata"); + attr.id = SAI_ROUTE_ATTR_META_DATA; + attr.value.u32 = 0x12345678; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); +} + +void test_route_entry_get() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_unicast_route_entry_t route_entry; + + // TODO we should use create + sai_object_id_t vr = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + object_reference_insert(vr); + sai_object_meta_key_t meta_key_vr = { .object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, .key = { .object_id = vr } }; + std::string vr_key = get_object_meta_key_string(meta_key_vr); + ObjectAttrHash[vr_key] = { }; + + sai_object_id_t hop = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP); + object_reference_insert(hop); + sai_object_meta_key_t meta_key_hop = { .object_type = SAI_OBJECT_TYPE_NEXT_HOP, .key = { .object_id = hop } }; + std::string hop_key = get_object_meta_key_string(meta_key_hop); + ObjectAttrHash[hop_key] = { }; + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("zero attribute count"); + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + status = meta_sai_get_route_entry(&route_entry, 0, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_get_route_entry(&route_entry, 1, NULL, &dummy_success_sai_get_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("route entry is null"); + status = meta_sai_get_route_entry(NULL, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("get function is null"); + status = meta_sai_get_route_entry(&route_entry, 1, &attr, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr id out of range"); + attr.id = -1; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_ROUTE_ATTR_PACKET_ACTION; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct trap prio"); + attr.id = SAI_ROUTE_ATTR_TRAP_PRIORITY; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct meta"); + attr.id = SAI_ROUTE_ATTR_META_DATA; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); +} + +void test_route_entry_flow() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_unicast_route_entry_t route_entry; + + // TODO we should use create + sai_object_id_t vr = create_dummy_object_id(SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + object_reference_insert(vr); + sai_object_meta_key_t meta_key_vr = { .object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER, .key = { .object_id = vr } }; + std::string vr_key = get_object_meta_key_string(meta_key_vr); + ObjectAttrHash[vr_key] = { }; + + sai_object_id_t hop = create_dummy_object_id(SAI_OBJECT_TYPE_NEXT_HOP); + object_reference_insert(hop); + sai_object_meta_key_t meta_key_hop = { .object_type = SAI_OBJECT_TYPE_NEXT_HOP, .key = { .object_id = hop } }; + std::string hop_key = get_object_meta_key_string(meta_key_hop); + ObjectAttrHash[hop_key] = { }; + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + route_entry.vr_id = vr; + + SWSS_LOG_NOTICE("create tests"); + + sai_attribute_t list[3] = { }; + + sai_attribute_t &attr1 = list[0]; + sai_attribute_t &attr2 = list[1]; + + attr1.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr1.value.oid = hop; + + attr2.id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr2.value.s32 = SAI_PACKET_ACTION_FORWARD; + + SWSS_LOG_NOTICE("correct ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("already exists ipv4"); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip62 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0x99}; + memcpy(route_entry.destination.addr.ip6, ip62, 16); + + sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xf7,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask2, 16); + + SWSS_LOG_NOTICE("invalid mask"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + sai_ip6_t ip6 = {0x00, 0x11, 0x22, 0x33,0x44, 0x55, 0x66,0x77, 0x88, 0x99, 0xaa, 0xbb,0xcc,0xdd,0xee,0xff}; + memcpy(route_entry.destination.addr.ip6, ip6, 16); + + sai_ip6_t ip6mask = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + memcpy(route_entry.destination.mask.ip6, ip6mask, 16); + + SWSS_LOG_NOTICE("correct ipv6"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("already exists"); + status = meta_sai_create_route_entry(&route_entry, 2, list, &dummy_success_sai_create_route_entry); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_NEIGHBOR_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_DROP; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct trap priority"); + attr.id = SAI_ROUTE_ATTR_TRAP_PRIORITY; + attr.value.u8 = 12; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr.value.oid = hop; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct metadata"); + attr.id = SAI_ROUTE_ATTR_META_DATA; + attr.value.u32 = 0x12345678; + status = meta_sai_set_route_entry(&route_entry, &attr, &dummy_success_sai_set_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get tests"); + + SWSS_LOG_NOTICE("correct packet action"); + attr.id = SAI_ROUTE_ATTR_PACKET_ACTION; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct trap prio"); + attr.id = SAI_ROUTE_ATTR_TRAP_PRIORITY; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct next hop"); + attr.id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("correct meta"); + attr.id = SAI_ROUTE_ATTR_META_DATA; + status = meta_sai_get_route_entry(&route_entry, 1, &attr, &dummy_success_sai_get_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove tests"); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("non existing"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_FAIL(status); + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = htonl(0x0a00000f); + route_entry.destination.mask.ip4 = htonl(0xffffff00); + + SWSS_LOG_NOTICE("success"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("non existing"); + status = meta_sai_remove_route_entry(&route_entry, &dummy_success_sai_remove_route_entry); + META_ASSERT_FAIL(status); +} + +// TRAP TESTS + +void test_trap_set() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_hostif_trap_id_t trapid = SAI_HOSTIF_TRAP_ID_LLDP; + + // TODO we should use create + sai_object_id_t group = create_dummy_object_id(SAI_OBJECT_TYPE_TRAP_GROUP); + object_reference_insert(group); + sai_object_meta_key_t meta_key_group = { .object_type = SAI_OBJECT_TYPE_TRAP_GROUP, .key = { .object_id = group } }; + std::string group_key = get_object_meta_key_string(meta_key_group); + ObjectAttrHash[group_key] = { }; + + sai_object_id_t port1 = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + object_reference_insert(port1); + sai_object_meta_key_t meta_key_port1 = { .object_type = SAI_OBJECT_TYPE_PORT, .key = { .object_id = port1 } }; + std::string port1_key = get_object_meta_key_string(meta_key_port1); + ObjectAttrHash[port1_key] = { }; + + sai_object_id_t port2 = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + object_reference_insert(port2); + sai_object_meta_key_t meta_key_port2 = { .object_type = SAI_OBJECT_TYPE_PORT, .key = { .object_id = port2 } }; + std::string port2_key = get_object_meta_key_string(meta_key_port2); + ObjectAttrHash[port2_key] = { }; + + SWSS_LOG_NOTICE("set tests"); + + SWSS_LOG_NOTICE("attr is null"); + status = meta_sai_set_trap(trapid, NULL, &dummy_success_sai_set_trap); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("set is null"); + status = meta_sai_set_trap(trapid, &attr, NULL); + META_ASSERT_FAIL(status); + + int id = 0x1000; + trapid = (sai_hostif_trap_id_t)id; + + SWSS_LOG_NOTICE("invalid trap id"); + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_FAIL(status); + + trapid = SAI_HOSTIF_TRAP_ID_LLDP; + + SWSS_LOG_NOTICE("success paceket action"); + attr.id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("success trap prio"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr.value.u32 = 12; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("success trap channel"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr.value.s32 = SAI_HOSTIF_TRAP_CHANNEL_NETDEV; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("success trap group"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP; + attr.value.oid = group; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("null trap group"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP; + attr.value.oid = SAI_NULL_OBJECT_ID; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_FAIL(status); + + sai_object_id_t list[2] = {}; + + list[0] = port1; + list[1] = port2; + + SWSS_LOG_NOTICE("success port list"); + attr.id = SAI_HOSTIF_TRAP_ATTR_PORT_LIST; + attr.value.objlist.count = 2; + attr.value.objlist.list = list; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_SUCCESS(status); + + list[0] = port1; + list[1] = port1; + + SWSS_LOG_NOTICE("port list reapats oids"); + attr.id = SAI_HOSTIF_TRAP_ATTR_PORT_LIST; + attr.value.objlist.count = 2; + attr.value.objlist.list = list; + status = meta_sai_set_trap(trapid, &attr, &dummy_success_sai_set_trap); + META_ASSERT_FAIL(status); +} + +void test_trap_get() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_attribute_t attr; + + sai_object_id_t port1 = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + object_reference_insert(port1); + sai_object_meta_key_t meta_key_port1 = { .object_type = SAI_OBJECT_TYPE_PORT, .key = { .object_id = port1 } }; + std::string port1_key = get_object_meta_key_string(meta_key_port1); + ObjectAttrHash[port1_key] = { }; + + sai_object_id_t port2 = create_dummy_object_id(SAI_OBJECT_TYPE_PORT); + object_reference_insert(port2); + sai_object_meta_key_t meta_key_port2 = { .object_type = SAI_OBJECT_TYPE_PORT, .key = { .object_id = port2 } }; + std::string port2_key = get_object_meta_key_string(meta_key_port2); + ObjectAttrHash[port2_key] = { }; + + sai_hostif_trap_id_t trapid = SAI_HOSTIF_TRAP_ID_LLDP; + + SWSS_LOG_NOTICE("get tests"); + + int id = 0x1000; + + trapid = (sai_hostif_trap_id_t)id; + + SWSS_LOG_NOTICE("invalid trap id"); + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_FAIL(status); + + trapid = (sai_hostif_trap_id_t)id; + + SWSS_LOG_NOTICE("too many args"); + status = meta_sai_get_trap(trapid, 1000, &attr, &dummy_success_sai_get_trap); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("attr is null"); + trapid = SAI_HOSTIF_TRAP_ID_LLDP; + status = meta_sai_get_trap(trapid, 1, NULL, &dummy_success_sai_get_trap); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("get is null"); + status = meta_sai_get_trap(trapid, 1, &attr, NULL); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("invalid attr id"); + attr.id = -1; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("success packet action"); + attr.id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr.value.oid = 0; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("success trap prio"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("success trap chanel"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("trap group"); + attr.id = SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_SUCCESS(status); + + sai_object_id_t list[2] = {}; + + list[0] = port1; + list[1] = port2; + + SWSS_LOG_NOTICE("success port list"); + attr.id = SAI_HOSTIF_TRAP_ATTR_PORT_LIST; + attr.value.objlist.count = 2; + attr.value.objlist.list = list; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("success port list"); + attr.id = SAI_HOSTIF_TRAP_ATTR_PORT_LIST; + attr.value.objlist.count = 0; + attr.value.objlist.list = NULL; + status = meta_sai_get_trap(trapid, 1, &attr, &dummy_success_sai_get_trap); + META_ASSERT_SUCCESS(status); +} + +// SERIALIZATION TYPES TESTS + +void test_serialization_type_vlan_list() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t stp; + + SWSS_LOG_NOTICE("create stp"); + + status = meta_sai_create_oid(SAI_OBJECT_TYPE_STP_INSTANCE, &stp, 0, NULL, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + sai_vlan_id_t list[2] = { 1, 2 }; + + sai_attribute_t attr; + + attr.id = SAI_STP_ATTR_VLAN_LIST; + attr.value.vlanlist.count = 2; + attr.value.vlanlist.list = list; + + SWSS_LOG_NOTICE("set vlan list"); + + status = meta_sai_set_oid(SAI_OBJECT_TYPE_STP_INSTANCE, stp, &attr, &dummy_success_sai_set_oid); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("get vlan list"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_STP_INSTANCE, stp, 1, &attr, &dummy_success_sai_get_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove stp"); + + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_STP_INSTANCE, stp, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); +} + +void test_serialization_type_bool() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t vr; + + SWSS_LOG_NOTICE("create stp"); + + sai_attribute_t attr; + + attr.id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE; + attr.value.booldata = true; + + status = meta_sai_create_oid(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &vr, 1, &attr, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set bool"); + + status = meta_sai_set_oid(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, &attr, &dummy_success_sai_set_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get bool"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, 1, &attr, &dummy_success_sai_get_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove vr"); + + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, vr, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); +} + +void test_serialization_type_char() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t hostif; + + SWSS_LOG_NOTICE("create rif"); + + // TODO we should use create + sai_object_id_t rif = create_dummy_object_id(SAI_OBJECT_TYPE_ROUTER_INTERFACE); + object_reference_insert(rif); + sai_object_meta_key_t meta_key_rif = { .object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE, .key = { .object_id = rif } }; + std::string rif_key = get_object_meta_key_string(meta_key_rif); + ObjectAttrHash[rif_key] = { }; + + sai_attribute_t attr, attr2, attr3; + + attr.id = SAI_HOSTIF_ATTR_TYPE; + attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV; + + attr2.id = SAI_HOSTIF_ATTR_RIF_OR_PORT_ID; + attr2.value.oid = rif; + + attr3.id = SAI_HOSTIF_ATTR_NAME; + + memcpy(attr3.value.chardata, "foo", sizeof("foo")); + + sai_attribute_t list[3] = { attr, attr2, attr3 }; + + // TODO we need to support conditions here + + SWSS_LOG_NOTICE("create hostif"); + + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, &hostif, 3, list, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set char"); + + status = meta_sai_set_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, hostif, &attr3, &dummy_success_sai_set_oid); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("get char"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, hostif, 1, &attr3, &dummy_success_sai_get_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove hostif"); + + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, hostif, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); + + attr.id = SAI_HOSTIF_ATTR_TYPE; + attr.value.s32 = SAI_HOSTIF_TYPE_FD; + + sai_attribute_t list2[1] = { attr }; + + SWSS_LOG_NOTICE("create hostif with non mandatory"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, &hostif, 1, list2, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get char"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, hostif, 1, &attr2, &dummy_success_sai_get_oid); + META_ASSERT_FAIL(status); + + attr.id = SAI_HOSTIF_ATTR_TYPE; + attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV; + + sai_attribute_t list3[1] = { attr }; + + SWSS_LOG_NOTICE("create hostif with mandatory missing"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HOST_INTERFACE, &hostif, 1, list3, &dummy_success_sai_create_oid); + META_ASSERT_FAIL(status); +} + +void test_serialization_type_int32_list() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t hash; + + sai_attribute_t attr; + + SWSS_LOG_NOTICE("create hash"); + + int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; + + attr.id = SAI_HASH_ATTR_NATIVE_FIELD_LIST; + attr.value.s32list.count = 2; + attr.value.s32list.list = list; + + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HASH, &hash, 1, &attr, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set hash"); + + status = meta_sai_set_oid(SAI_OBJECT_TYPE_HASH, hash, &attr, &dummy_success_sai_set_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get hash"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_HASH, hash, 1, &attr, &dummy_success_sai_get_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove hash"); + + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_HASH, hash, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); +} + +void test_serialization_type_uint32_list() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t hash; + + sai_attribute_t attr; + + SWSS_LOG_NOTICE("create hash"); + + int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; + + attr.id = SAI_HASH_ATTR_NATIVE_FIELD_LIST; + attr.value.s32list.count = 2; + attr.value.s32list.list = list; + + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HASH, &hash, 1, &attr, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("set hash"); + + status = meta_sai_set_oid(SAI_OBJECT_TYPE_HASH, hash, &attr, &dummy_success_sai_set_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("get hash"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_HASH, hash, 1, &attr, &dummy_success_sai_get_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove hash"); + + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_HASH, hash, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); +} + +// OTHER + +void test_mask() +{ + SWSS_LOG_ENTER(); + + sai_ip6_t ip6mask1 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x00}; + sai_ip6_t ip6mask2 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xff}; + sai_ip6_t ip6mask3 = {0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; + sai_ip6_t ip6mask4 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xfe}; + sai_ip6_t ip6mask5 = {0x80, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; + + sai_ip6_t ip6mask6 = {0x01, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00}; + sai_ip6_t ip6mask7 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x8f}; + sai_ip6_t ip6mask8 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0x8f}; + sai_ip6_t ip6mask9 = {0xff, 0xff, 0xff, 0xff,0xff, 0xff, 0xff,0xf1, 0xff, 0xff, 0xff, 0xff,0xff,0xff,0xff,0xff}; + + META_ASSERT_TRUE(is_ipv6_mask_valid(ip6mask1)); + META_ASSERT_TRUE(is_ipv6_mask_valid(ip6mask2)); + META_ASSERT_TRUE(is_ipv6_mask_valid(ip6mask3)); + META_ASSERT_TRUE(is_ipv6_mask_valid(ip6mask4)); + META_ASSERT_TRUE(is_ipv6_mask_valid(ip6mask5)); + + META_ASSERT_TRUE(!is_ipv6_mask_valid(ip6mask6)); + META_ASSERT_TRUE(!is_ipv6_mask_valid(ip6mask7)); + META_ASSERT_TRUE(!is_ipv6_mask_valid(ip6mask8)); + META_ASSERT_TRUE(!is_ipv6_mask_valid(ip6mask9)); +} + +sai_object_id_t insert_dummy_object(sai_object_type_t ot) +{ + // TODO we should use create + sai_object_id_t oid = create_dummy_object_id(ot); + object_reference_insert(oid); + sai_object_meta_key_t meta_key_oid = { .object_type = ot, .key = { .object_id = oid } }; + std::string oid_key = get_object_meta_key_string(meta_key_oid); + ObjectAttrHash[oid_key] = { }; + + return oid; +} + +void test_acl_entry_field_and_action() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t aclentry; + + int32_t ids[] = { + SAI_ACL_ENTRY_ATTR_TABLE_ID, + SAI_ACL_ENTRY_ATTR_PRIORITY, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_IPv6, + SAI_ACL_ENTRY_ATTR_FIELD_DST_IPv6, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_MAC, + SAI_ACL_ENTRY_ATTR_FIELD_DST_MAC, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP, + SAI_ACL_ENTRY_ATTR_FIELD_DST_IP, + SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS, + SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS, + SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_CFI, + SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_CFI, + SAI_ACL_ENTRY_ATTR_FIELD_L4_SRC_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_L4_DST_PORT, + SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE, + SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL, + SAI_ACL_ENTRY_ATTR_FIELD_DSCP, + SAI_ACL_ENTRY_ATTR_FIELD_ECN, + SAI_ACL_ENTRY_ATTR_FIELD_TTL, + SAI_ACL_ENTRY_ATTR_FIELD_TOS, + SAI_ACL_ENTRY_ATTR_FIELD_IP_FLAGS, + SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS, + SAI_ACL_ENTRY_ATTR_FIELD_IP_TYPE, + SAI_ACL_ENTRY_ATTR_FIELD_IP_FRAG, + SAI_ACL_ENTRY_ATTR_FIELD_IPv6_FLOW_LABEL, + SAI_ACL_ENTRY_ATTR_FIELD_TC, + SAI_ACL_ENTRY_ATTR_FIELD_ICMP_TYPE, + SAI_ACL_ENTRY_ATTR_FIELD_ICMP_CODE, + SAI_ACL_ENTRY_ATTR_FIELD_VLAN_TAGS, + SAI_ACL_ENTRY_ATTR_FIELD_FDB_DST_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_DST_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_PORT_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_VLAN_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_ACL_USER_META, + SAI_ACL_ENTRY_ATTR_FIELD_FDB_NPU_META_DST_HIT, + SAI_ACL_ENTRY_ATTR_FIELD_NEIGHBOR_NPU_META_DST_HIT, + SAI_ACL_ENTRY_ATTR_FIELD_ROUTE_NPU_META_DST_HIT, + SAI_ACL_ENTRY_ATTR_FIELD_RANGE, + SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT, + SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT_LIST, + SAI_ACL_ENTRY_ATTR_PACKET_ACTION, + SAI_ACL_ENTRY_ATTR_ACTION_FLOOD, + SAI_ACL_ENTRY_ATTR_ACTION_COUNTER, + SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS, + SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS, + SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER, + SAI_ACL_ENTRY_ATTR_ACTION_DECREMENT_TTL, + SAI_ACL_ENTRY_ATTR_ACTION_SET_TC, + SAI_ACL_ENTRY_ATTR_ACTION_SET_COLOR, + SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_ACTION_SET_INNER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_ID, + SAI_ACL_ENTRY_ATTR_ACTION_SET_OUTER_VLAN_PRI, + SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_MAC, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_MAC, + SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IP, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IP, + SAI_ACL_ENTRY_ATTR_ACTION_SET_SRC_IPv6, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DST_IPv6, + SAI_ACL_ENTRY_ATTR_ACTION_SET_DSCP, + SAI_ACL_ENTRY_ATTR_ACTION_SET_ECN, + SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_SRC_PORT, + SAI_ACL_ENTRY_ATTR_ACTION_SET_L4_DST_PORT, + SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE, + SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE, + SAI_ACL_ENTRY_ATTR_ACTION_SET_CPU_QUEUE, + SAI_ACL_ENTRY_ATTR_ACTION_SET_ACL_META_DATA, + SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_BLOCK_PORT_LIST, + SAI_ACL_ENTRY_ATTR_ACTION_SET_USER_TRAP_ID, + }; + + std::vector vattrs; + + // all lists are empty we need info if that is possible + + for (uint32_t i = 0; i < sizeof(ids)/sizeof(int32_t); ++i) + { + sai_attribute_t attr; + + memset(&attr,0,sizeof(attr)); + + attr.id = ids[i]; + + if (attr.id == SAI_ACL_ENTRY_ATTR_TABLE_ID) + attr.value.oid = insert_dummy_object(SAI_OBJECT_TYPE_ACL_TABLE); + + if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT) + attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT); + + if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT) + attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT); + + if (attr.id == SAI_ACL_ENTRY_ATTR_FIELD_SRC_PORT) + attr.value.aclfield.data.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_PORT); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_COUNTER) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_ACL_COUNTER); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_POLICER); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_INGRESS_SAMPLEPACKET_ENABLE) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_SAMPLEPACKET); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_EGRESS_SAMPLEPACKET_ENABLE) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_SAMPLEPACKET); + + if (attr.id == SAI_ACL_ENTRY_ATTR_ACTION_SET_CPU_QUEUE) + attr.value.aclaction.parameter.oid = insert_dummy_object(SAI_OBJECT_TYPE_QUEUE); + + vattrs.push_back(attr); + } + + SWSS_LOG_NOTICE("create acl entry"); + + status = meta_sai_create_oid(SAI_OBJECT_TYPE_ACL_ENTRY, &aclentry, (uint32_t)vattrs.size(), vattrs.data(), &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + for (uint32_t i = 0; i < sizeof(ids)/sizeof(int32_t); ++i) + { + if (vattrs[i].id == SAI_ACL_ENTRY_ATTR_TABLE_ID) + continue; + + SWSS_LOG_NOTICE("set aclentry %u %s", i, get_attr_name(SAI_OBJECT_TYPE_ACL_ENTRY, vattrs[i].id)); + + status = meta_sai_set_oid(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, &vattrs[i], &dummy_success_sai_set_oid); + META_ASSERT_SUCCESS(status); + } + + SWSS_LOG_NOTICE("get aclentry"); + + status = meta_sai_get_oid(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, (uint32_t)vattrs.size(), vattrs.data(), &dummy_success_sai_get_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("remove aclentry"); + + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_ACL_ENTRY, aclentry, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); +} + +void test_construct_key() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_attribute_t attr; + + uint32_t list[4] = {1,2,3,4}; + + attr.id = SAI_PORT_ATTR_HW_LANE_LIST; + attr.value.u32list.count = 4; + attr.value.u32list.list = list; + + sai_object_meta_key_t meta_key; + + meta_key.object_type = SAI_OBJECT_TYPE_PORT; + + std::string key = construct_key(meta_key, 1, &attr); + + SWSS_LOG_NOTICE("constructed key: %s", key.c_str()); + + META_ASSERT_TRUE(key == "SAI_PORT_ATTR_HW_LANE_LIST:1,2,3,4;"); +} + +void test_queue_create() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + sai_object_id_t queue; + + sai_attribute_t attr1; + sai_attribute_t attr2; + + attr1.id = SAI_QUEUE_ATTR_TYPE; + attr1.value.s32 = SAI_QUEUE_TYPE_UNICAST; + + attr2.id = SAI_QUEUE_ATTR_INDEX; + attr2.value.u8 = 7; + + sai_attribute_t list[2] = { attr1, attr2 }; + SWSS_LOG_NOTICE("create tests"); + + SWSS_LOG_NOTICE("create queue"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_QUEUE, &queue, 2, list, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("create queue but key exists"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_QUEUE, &queue, 2, list, &dummy_success_sai_create_oid); + META_ASSERT_FAIL(status); + + SWSS_LOG_NOTICE("remove queue"); + status = meta_sai_remove_oid(SAI_OBJECT_TYPE_QUEUE, queue, &dummy_success_sai_remove_oid); + META_ASSERT_SUCCESS(status); + + SWSS_LOG_NOTICE("create queue"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_QUEUE, &queue, 2, list, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); +} + +void test_null_list() +{ + SWSS_LOG_ENTER(); + + meta_init_db(); + + sai_status_t status; + + sai_object_id_t hash; + + sai_attribute_t attr; + + int32_t list[2] = { SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_VLAN_ID }; + + attr.id = SAI_HASH_ATTR_NATIVE_FIELD_LIST; + attr.value.s32list.count = 0; + attr.value.s32list.list = list; + + SWSS_LOG_NOTICE("0 count, not null list"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HASH, &hash, 1, &attr, &dummy_success_sai_create_oid); + META_ASSERT_FAIL(status); + + attr.value.s32list.list = NULL; + + SWSS_LOG_NOTICE("0 count, null list"); + status = meta_sai_create_oid(SAI_OBJECT_TYPE_HASH, &hash, 1, &attr, &dummy_success_sai_create_oid); + META_ASSERT_SUCCESS(status); +} + +int main() +{ + swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG); + + SWSS_LOG_ENTER(); + + test_switch_set(); + test_switch_get(); + + test_fdb_entry_create(); + test_fdb_entry_remove(); + test_fdb_entry_set(); + test_fdb_entry_get(); + test_fdb_entry_flow(); + + test_neighbor_entry_create(); + test_neighbor_entry_remove(); + test_neighbor_entry_set(); + test_neighbor_entry_get(); + test_neighbor_entry_flow(); + + test_vlan_create(); + test_vlan_remove(); + test_vlan_set(); + test_vlan_get(); + test_vlan_flow(); + + test_route_entry_create(); + test_route_entry_remove(); + test_route_entry_set(); + test_route_entry_get(); + test_route_entry_flow(); + + test_trap_set(); + test_trap_get(); + + test_serialization_type_vlan_list(); + test_serialization_type_bool(); + test_serialization_type_char(); + test_serialization_type_int32_list(); + test_serialization_type_uint32_list(); + + test_mask(); + test_acl_entry_field_and_action(); + test_construct_key(); + test_queue_create(); + test_null_list(); + + std::cout << "SUCCESS" << std::endl; +}