diff --git a/common/saiattribute.h b/common/saiattribute.h index 86033755f7b2..93af117970ec 100644 --- a/common/saiattribute.h +++ b/common/saiattribute.h @@ -34,7 +34,7 @@ class SaiAttribute sai_object_type_t m_objectType; sai_attribute_t m_attr; - + sai_attr_serialization_type_t m_serializationType; }; diff --git a/common/saiserialize.cpp b/common/saiserialize.cpp index c3f8ed452924..d134c86d2b6f 100644 --- a/common/saiserialize.cpp +++ b/common/saiserialize.cpp @@ -43,6 +43,7 @@ sai_serialization_map_t sai_get_serialization_map() map[SAI_OBJECT_TYPE_WRED][SAI_WRED_ATTR_WEIGHT] = SAI_SERIALIZATION_TYPE_UINT8; map[SAI_OBJECT_TYPE_WRED][SAI_WRED_ATTR_ECN_MARK_MODE] = SAI_SERIALIZATION_TYPE_INT32; + map[SAI_OBJECT_TYPE_PORT][SAI_PORT_ATTR_TYPE] = SAI_SERIALIZATION_TYPE_INT32; map[SAI_OBJECT_TYPE_PORT][SAI_PORT_ATTR_SPEED] = SAI_SERIALIZATION_TYPE_UINT32; map[SAI_OBJECT_TYPE_PORT][SAI_PORT_ATTR_ADMIN_STATE] = SAI_SERIALIZATION_TYPE_BOOL; map[SAI_OBJECT_TYPE_PORT][SAI_PORT_ATTR_OPER_STATUS] = SAI_SERIALIZATION_TYPE_INT32; @@ -244,6 +245,7 @@ sai_object_type_to_string_map_t sai_get_object_type_map() map[SAI_OBJECT_TYPE_NEIGHBOR] = TO_STR(SAI_OBJECT_TYPE_NEIGHBOR); map[SAI_OBJECT_TYPE_ROUTE] = TO_STR(SAI_OBJECT_TYPE_ROUTE); map[SAI_OBJECT_TYPE_VLAN] = TO_STR(SAI_OBJECT_TYPE_VLAN); + map[SAI_OBJECT_TYPE_VLAN_MEMBER] = TO_STR(SAI_OBJECT_TYPE_VLAN_MEMBER); map[SAI_OBJECT_TYPE_TUNNEL] = TO_STR(SAI_OBJECT_TYPE_TUNNEL); map[SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY] = TO_STR(SAI_OBJECT_TYPE_TUNNEL_TABLE_ENTRY); @@ -256,7 +258,7 @@ sai_status_t sai_get_object_type_string(sai_object_type_t object_type, std::stri if (it == g_object_type_map.end()) { - SWSS_LOG_ERROR("serialization object not found %x", object_type); + SWSS_LOG_ERROR("serialization object not found %d", object_type); return SAI_STATUS_NOT_IMPLEMENTED; } @@ -1347,6 +1349,13 @@ sai_status_t sai_deserialize_free_fdb_event_notification_data( return SAI_STATUS_SUCCESS; } +#define RETURN_ON_ERROR(x)\ +{\ + sai_status_t s = (x);\ + if (s != SAI_STATUS_SUCCESS)\ + return s;\ +} + sai_status_t transfer_attribute( _In_ sai_attr_serialization_type_t serialization_type, _In_ sai_attribute_t &src_attr, @@ -1416,31 +1425,31 @@ sai_status_t transfer_attribute( break; case SAI_SERIALIZATION_TYPE_OBJECT_LIST: - transfer_list(src_attr.value.objlist, dst_attr.value.objlist, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.objlist, dst_attr.value.objlist, countOnly)); break; case SAI_SERIALIZATION_TYPE_UINT8_LIST: - transfer_list(src_attr.value.u8list, dst_attr.value.u8list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.u8list, dst_attr.value.u8list, countOnly)); break; case SAI_SERIALIZATION_TYPE_INT8_LIST: - transfer_list(src_attr.value.s8list, dst_attr.value.s8list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.s8list, dst_attr.value.s8list, countOnly)); break; case SAI_SERIALIZATION_TYPE_UINT16_LIST: - transfer_list(src_attr.value.u16list, dst_attr.value.u16list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.u16list, dst_attr.value.u16list, countOnly)); break; case SAI_SERIALIZATION_TYPE_INT16_LIST: - transfer_list(src_attr.value.s16list, dst_attr.value.s16list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.s16list, dst_attr.value.s16list, countOnly)); break; case SAI_SERIALIZATION_TYPE_UINT32_LIST: - transfer_list(src_attr.value.u32list, dst_attr.value.u32list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.u32list, dst_attr.value.u32list, countOnly)); break; case SAI_SERIALIZATION_TYPE_INT32_LIST: - transfer_list(src_attr.value.s32list, dst_attr.value.s32list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.s32list, dst_attr.value.s32list, countOnly)); break; case SAI_SERIALIZATION_TYPE_UINT32_RANGE: @@ -1452,20 +1461,20 @@ sai_status_t transfer_attribute( break; case SAI_SERIALIZATION_TYPE_VLAN_LIST: - transfer_list(src_attr.value.vlanlist, dst_attr.value.vlanlist, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.vlanlist, dst_attr.value.vlanlist, countOnly)); break; case SAI_SERIALIZATION_TYPE_PORT_BREAKOUT: transfer_primitive(src_attr.value.portbreakout.breakout_mode, dst_attr.value.portbreakout.breakout_mode); - transfer_list(src_attr.value.portbreakout.port_list, dst_attr.value.portbreakout.port_list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.portbreakout.port_list, dst_attr.value.portbreakout.port_list, countOnly)); break; case SAI_SERIALIZATION_TYPE_QOS_MAP_LIST: - transfer_list(src_attr.value.qosmap, dst_attr.value.qosmap, countOnly); + RETURN_ON_ERROR(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); + RETURN_ON_ERROR(transfer_list(src_attr.value.tunnelmap, dst_attr.value.tunnelmap, countOnly)); break; /* ACL FIELD DATA */ @@ -1536,12 +1545,12 @@ sai_status_t transfer_attribute( case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_OBJECT_LIST: transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); - transfer_list(src_attr.value.aclfield.data.objlist, dst_attr.value.aclfield.data.objlist, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.aclfield.data.objlist, dst_attr.value.aclfield.data.objlist, countOnly)); break; case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: transfer_primitive(src_attr.value.aclfield.enable, dst_attr.value.aclfield.enable); - transfer_list(src_attr.value.aclfield.mask.u8list, dst_attr.value.aclfield.mask.u8list, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.aclfield.mask.u8list, dst_attr.value.aclfield.mask.u8list, countOnly)); transfer_list(src_attr.value.aclfield.data.u8list, dst_attr.value.aclfield.data.u8list, countOnly); break; @@ -1599,7 +1608,7 @@ sai_status_t transfer_attribute( case SAI_SERIALIZATION_TYPE_ACL_ACTION_DATA_OBJECT_LIST: transfer_primitive(src_attr.value.aclaction.enable, dst_attr.value.aclaction.enable); - transfer_list(src_attr.value.aclaction.parameter.objlist, dst_attr.value.aclaction.parameter.objlist, countOnly); + RETURN_ON_ERROR(transfer_list(src_attr.value.aclaction.parameter.objlist, dst_attr.value.aclaction.parameter.objlist, countOnly)); break; default: @@ -1609,7 +1618,7 @@ sai_status_t transfer_attribute( return SAI_STATUS_SUCCESS; } -void transfer_attributes( +sai_status_t transfer_attributes( _In_ sai_object_type_t object_type, _In_ uint32_t attr_count, _In_ sai_attribute_t *src_attr_list, @@ -1634,8 +1643,10 @@ void transfer_attributes( exit(EXIT_FAILURE); } - transfer_attribute(serialization_type, src_attr, dst_attr, countOnly); + RETURN_ON_ERROR(transfer_attribute(serialization_type, src_attr, dst_attr, countOnly)); } + + return SAI_STATUS_SUCCESS; } void sai_serialize_ip_address( diff --git a/common/saiserialize.h b/common/saiserialize.h index b45c2da0afe5..c4a0162b1409 100644 --- a/common/saiserialize.h +++ b/common/saiserialize.h @@ -18,7 +18,7 @@ extern "C" { #define TO_STR(x) #x -typedef enum _sai_attr_serialization_type_t +typedef enum _sai_attr_serialization_type_t { SAI_SERIALIZATION_TYPE_BOOL, SAI_SERIALIZATION_TYPE_CHARDATA, @@ -107,14 +107,14 @@ void sai_dealloc_array( void sai_deserialize_buffer( _In_ const std::string &s, _In_ int index, - _In_ size_t buffer_size, + _In_ size_t buffer_size, _In_ void *buffer); void sai_free_buffer(void * buffer); void sai_serialize_buffer( - _In_ const void *buffer, - _In_ size_t buffer_size, + _In_ const void *buffer, + _In_ size_t buffer_size, _Out_ std::string &s); template @@ -227,20 +227,40 @@ void transfer_primitive( } template -void transfer_list( +sai_status_t transfer_list( _In_ const T &src_element, _In_ T &dst_element, _In_ bool countOnly) { - transfer_primitive(src_element.count, dst_element.count); + if (countOnly || dst_element.count == 0) + { + transfer_primitive(src_element.count, dst_element.count); + return SAI_STATUS_SUCCESS; + } - if (countOnly) - return; + if (dst_element.list == NULL) + { + SWSS_LOG_ERROR("destination list is null, unable to transfer elements"); - for (size_t i = 0; i < src_element.count; i++) + return SAI_STATUS_FAILURE; + } + + if (dst_element.count >= src_element.count) { - transfer_primitive(src_element.list[i], dst_element.list[i]); + transfer_primitive(src_element.count, dst_element.count); + + for (size_t i = 0; i < src_element.count; i++) + { + transfer_primitive(src_element.list[i], dst_element.list[i]); + } + + return SAI_STATUS_SUCCESS; } + + // input buffer is too small to get all list elements, so return count only + transfer_primitive(src_element.count, dst_element.count); + + return SAI_STATUS_BUFFER_OVERFLOW; } void sai_serialize_ip_address( @@ -330,7 +350,7 @@ sai_status_t transfer_attribute( _In_ sai_attribute_t &dst_attr, _In_ bool countOnly); -void transfer_attributes( +sai_status_t transfer_attributes( _In_ sai_object_type_t object_type, _In_ uint32_t attr_count, _In_ sai_attribute_t *src_attr_list, diff --git a/lib/src/sai_redis_interfacequery.cpp b/lib/src/sai_redis_interfacequery.cpp index 198e0ab795b4..51588afe1b35 100644 --- a/lib/src/sai_redis_interfacequery.cpp +++ b/lib/src/sai_redis_interfacequery.cpp @@ -317,7 +317,5 @@ sai_status_t sai_api_uninitialize(void) g_apiInitialized = false; - SWSS_LOG_ERROR("not implemented"); - return SAI_STATUS_NOT_IMPLEMENTED; } diff --git a/meta/sai_meta.cpp b/meta/sai_meta.cpp index a02bf040dd6e..d30a75fb0934 100644 --- a/meta/sai_meta.cpp +++ b/meta/sai_meta.cpp @@ -353,6 +353,7 @@ class SaiAttrWrapper #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__) +#define META_LOG_INFO(md, format, ...) SWSS_LOG_INFO("%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, @@ -2164,28 +2165,19 @@ sai_status_t meta_generic_validation_get( 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; - } - + VALIDATION_LIST(md, value.objlist); break; case SAI_SERIALIZATION_TYPE_VLAN_LIST: { + if (value.vlanlist.count == 0 && value.vlanlist.list != NULL) + { + META_LOG_ERROR(md, "vlan list count is zero, but list not NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + 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); @@ -2222,26 +2214,8 @@ sai_status_t meta_generic_validation_get( 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; - } + VALIDATION_LIST(md, value.aclfield.data.objlist); + break; // case SAI_SERIALIZATION_TYPE_ACL_FIELD_DATA_UINT8_LIST: @@ -2263,26 +2237,8 @@ sai_status_t meta_generic_validation_get( 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; - } + VALIDATION_LIST(md, value.aclaction.parameter.objlist); + break; // ACL END @@ -3013,7 +2969,11 @@ void meta_generic_validation_post_get_objlist( 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); + // NOTE: there may happen that user will request multiple object lists + // and first list was retrived ok, but second failed with overflow + // then we may forget to snoop + + META_LOG_INFO(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 } }; diff --git a/meta/sai_meta_sanity.cpp b/meta/sai_meta_sanity.cpp index b218f750bec1..c7c596f85b02 100644 --- a/meta/sai_meta_sanity.cpp +++ b/meta/sai_meta_sanity.cpp @@ -445,6 +445,7 @@ std::unordered_map> get_attr_n 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); 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); diff --git a/syncd/syncd.cpp b/syncd/syncd.cpp index a73cbfa23c90..4acde6243e1d 100644 --- a/syncd/syncd.cpp +++ b/syncd/syncd.cpp @@ -78,6 +78,29 @@ sai_object_id_t redis_create_virtual_object_id( return vid; } +std::unordered_map local_rid_to_vid; +std::unordered_map local_vid_to_rid; + +void save_rid_and_vid_to_local( + _In_ sai_object_id_t rid, + _In_ sai_object_id_t vid) +{ + SWSS_LOG_ENTER(); + + local_rid_to_vid[rid] = vid; + local_vid_to_rid[vid] = rid; +} + +void remove_rid_and_vid_from_local( + _In_ sai_object_id_t rid, + _In_ sai_object_id_t vid) +{ + SWSS_LOG_ENTER(); + + local_rid_to_vid.erase(rid); + local_vid_to_rid.erase(vid); +} + sai_object_id_t translate_rid_to_vid( _In_ sai_object_id_t rid) { @@ -90,6 +113,13 @@ sai_object_id_t translate_rid_to_vid( return SAI_NULL_OBJECT_ID; } + auto it = local_rid_to_vid.find(rid); + + if (it != local_rid_to_vid.end()) + { + return it->second; + } + sai_object_id_t vid; std::string str_rid; @@ -131,6 +161,8 @@ sai_object_id_t translate_rid_to_vid( g_redisClient->hset(RIDTOVID, str_rid, str_vid); g_redisClient->hset(VIDTORID, str_vid, str_rid); + save_rid_and_vid_to_local(rid, vid); + return vid; } @@ -215,6 +247,13 @@ sai_object_id_t translate_vid_to_rid( return SAI_NULL_OBJECT_ID; } + auto it = local_vid_to_rid.find(vid); + + if (it != local_vid_to_rid.end()) + { + return it->second; + } + std::string str_vid; sai_serialize_primitive(vid, str_vid); @@ -468,6 +507,8 @@ sai_status_t handle_generic( g_redisClient->hset(VIDTORID, str_vid, str_rid); g_redisClient->hset(RIDTOVID, str_rid, str_vid); + save_rid_and_vid_to_local(real_object_id, object_id); + SWSS_LOG_INFO("saved VID %s to RID %s", str_vid.c_str(), str_rid.c_str()); } else @@ -501,6 +542,8 @@ sai_status_t handle_generic( g_redisClient->hdel(VIDTORID, str_vid); g_redisClient->hdel(RIDTOVID, str_rid); + remove_rid_and_vid_from_local(rid, object_id); + return remove(rid); } @@ -1180,21 +1223,21 @@ void handlePortMap(const std::string& portMapFile) std::cerr << "port map parsing: not found ' ' in line" << line.c_str() << std::endl; continue; } - - std::string fp_value = line.substr(0, pos); + + std::string fp_value = line.substr(0, pos); std::string lanes = line.substr(pos + 1); lanes.erase(lanes.begin(), std::find_if(lanes.begin(), lanes.end(), std::not1(std::ptr_fun(std::isspace)))); std::istringstream iss(lanes); std::string lane_str; std::set lane_set; - + while (getline(iss, lane_str, ',')) { int lane = stoi(lane_str); lane_set.insert(lane); - } + } - gPortMap.insert(std::pair,std::string>(lane_set,fp_value)); + gPortMap.insert(std::pair,std::string>(lane_set,fp_value)); } } #endif // SAITHRIFT diff --git a/syncd/syncd_hard_reinit.cpp b/syncd/syncd_hard_reinit.cpp index 0b71ee71febd..cd72bac6f84f 100644 --- a/syncd/syncd_hard_reinit.cpp +++ b/syncd/syncd_hard_reinit.cpp @@ -170,6 +170,7 @@ void saiRemoveDefaultVlanMembers() const auto& portList = saiGetPortList(); + // TODO we should query for actual list size not port size std::vector vlanMemberList; vlanMemberList.resize(portList.size()); @@ -198,7 +199,7 @@ void saiRemoveDefaultVlanMembers() if (status != SAI_STATUS_SUCCESS) { - SWSS_LOG_ERROR("Failed to remove vlan member 0x%llx from vland %d", vm, DEFAULT_VLAN_NUMBER); + SWSS_LOG_ERROR("Failed to remove vlan member 0x%llx from vlan %d", vm, DEFAULT_VLAN_NUMBER); exit_and_notify(EXIT_FAILURE); } diff --git a/vslib/inc/sai_vs.h b/vslib/inc/sai_vs.h index d01d8cbeef7f..752830d358d9 100644 --- a/vslib/inc/sai_vs.h +++ b/vslib/inc/sai_vs.h @@ -68,6 +68,11 @@ sai_status_t vs_generic_create_route_entry( sai_status_t vs_generic_create_vlan( _In_ sai_vlan_id_t vlan_id); +sai_status_t vs_generic_create_trap( + _In_ sai_hostif_trap_id_t hostif_trap_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + // REMOVE sai_status_t vs_generic_remove( diff --git a/vslib/inc/sai_vs_state.h b/vslib/inc/sai_vs_state.h index 79d276d08ede..346ab1820b0e 100644 --- a/vslib/inc/sai_vs_state.h +++ b/vslib/inc/sai_vs_state.h @@ -20,8 +20,15 @@ extern ObjectHash g_objectHash; extern void reset_id_counter(); -extern sai_object_id_t switch_object_id; +extern sai_object_id_t vs_create_real_object_id( + _In_ sai_object_type_t object_type); extern sai_status_t init_switch(); +extern sai_object_id_t switch_object_id; + +extern std::map> vlan_members_map; +extern void update_vlan_member_list_on_vlan( + _In_ sai_vlan_id_t vlan_id); + #endif // __SAI_VS_STATE__ diff --git a/vslib/src/sai_vs_generic_create.cpp b/vslib/src/sai_vs_generic_create.cpp index fef680c56c6c..c917512cfa94 100644 --- a/vslib/src/sai_vs_generic_create.cpp +++ b/vslib/src/sai_vs_generic_create.cpp @@ -3,15 +3,14 @@ ObjectHash g_objectHash; -uint64_t real_id = 0; uint64_t real_ids[SAI_OBJECT_TYPE_MAX]; +#define VS_OID_FLAG 0x8000000000000000 + void reset_id_counter() { SWSS_LOG_ENTER(); - real_id = 0; - memset(real_ids, 0, sizeof(real_ids)); } @@ -20,19 +19,39 @@ sai_object_id_t vs_create_real_object_id( { SWSS_LOG_ENTER(); - real_id++; + if (object_type <= SAI_OBJECT_TYPE_NULL || + object_type >= SAI_OBJECT_TYPE_MAX) + { + SWSS_LOG_ERROR("invalid object type %d for createing real id", object_type); + + return SAI_NULL_OBJECT_ID; + } + + // count from zero for each type separetly + uint64_t real_id = real_ids[object_type]++; - sai_object_id_t objectId = (((sai_object_id_t)object_type) << 48) | real_id; + sai_object_id_t object_id = (((sai_object_id_t)object_type) << 48) | real_id | VS_OID_FLAG; - SWSS_LOG_DEBUG("created RID %llx", objectId); + SWSS_LOG_DEBUG("created RID %llx", object_id); - return objectId; + return object_id; } -sai_object_type_t sai_object_type_query(_In_ sai_object_id_t sai_object_id) +sai_object_type_t sai_object_type_query(_In_ sai_object_id_t object_id) { - // TODO add flag for visibility that this is vs switch - return (sai_object_type_t)(sai_object_id >> 48); + object_id = object_id & ~VS_OID_FLAG; + + sai_object_type_t object_type = (sai_object_type_t)(object_id >> 48); + + if (object_type <= SAI_OBJECT_TYPE_NULL || + object_type >= SAI_OBJECT_TYPE_MAX) + { + SWSS_LOG_ERROR("invalid object type %d for createing real id", object_type); + + return SAI_OBJECT_TYPE_NULL; + } + + return object_type; } sai_status_t internal_vs_generic_create( @@ -158,6 +177,23 @@ sai_status_t vs_generic_create_route_entry( return status; } +sai_status_t vs_generic_create_trap( + _In_ sai_hostif_trap_id_t hostif_trap_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + std::string str_hostif_trap_id; + sai_serialize_primitive(hostif_trap_id, str_hostif_trap_id); + + return internal_vs_generic_create( + SAI_OBJECT_TYPE_TRAP, + str_hostif_trap_id, + attr_count, + attr_list); +} + sai_status_t vs_generic_create_vlan( _In_ sai_vlan_id_t vlan_id) { diff --git a/vslib/src/sai_vs_generic_get.cpp b/vslib/src/sai_vs_generic_get.cpp index bc32e57d497f..28e610d03626 100644 --- a/vslib/src/sai_vs_generic_get.cpp +++ b/vslib/src/sai_vs_generic_get.cpp @@ -21,9 +21,7 @@ sai_status_t internal_vs_get_process( SaiAttributeList list(object_type, values, false); - transfer_attributes(object_type, 1, list.get_attr_list(), attr, false); - - return SAI_STATUS_SUCCESS; + return transfer_attributes(object_type, 1, list.get_attr_list(), attr, false); } sai_status_t internal_vs_generic_get( @@ -53,6 +51,9 @@ sai_status_t internal_vs_generic_get( for (uint32_t i = 0; i < attr_count; ++i) { + // TODO we need to also support "0" for list types + // to return only number + const std::string &str_attr_id = fvField(values[i]); // actual count that user requests is in attr_value @@ -79,15 +80,28 @@ sai_status_t internal_vs_generic_get( str_attr_value, &attr_list[i]); + if (status == SAI_STATUS_BUFFER_OVERFLOW) + { + // this is considered partial success, since we get correct list length + + SWSS_LOG_NOTICE("Get returned BUFFER_OVERFLOW object type: %d: id: %s, attr_id: %s", + object_type, + serialized_object_id.c_str(), + str_attr_id.c_str()); + + return status; + } + if (status != SAI_STATUS_SUCCESS) { + // all other errors SWSS_LOG_ERROR("Get failed, attribute process failed, object type: %d: id: %s, attr_id: %s", object_type, serialized_object_id.c_str(), str_attr_id.c_str()); - return SAI_STATUS_FAILURE; + return status; } } @@ -200,15 +214,18 @@ sai_status_t vs_generic_get_vlan( } sai_status_t vs_generic_get_trap( - _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ sai_hostif_trap_id_t hostif_trap_id, _In_ uint32_t attr_count, _Out_ sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - return vs_generic_get( + std::string str_hostif_trap_id; + sai_serialize_primitive(hostif_trap_id, str_hostif_trap_id); + + return internal_vs_generic_get( SAI_OBJECT_TYPE_TRAP, - hostif_trapid, + str_hostif_trap_id, attr_count, attr_list); } @@ -232,4 +249,3 @@ sai_status_t vs_generic_get_switch( return status; } - diff --git a/vslib/src/sai_vs_generic_set.cpp b/vslib/src/sai_vs_generic_set.cpp index b8418cadab6f..855e42e4e7b8 100644 --- a/vslib/src/sai_vs_generic_set.cpp +++ b/vslib/src/sai_vs_generic_set.cpp @@ -130,14 +130,17 @@ sai_status_t vs_generic_set_vlan( } sai_status_t vs_generic_set_trap( - _In_ sai_hostif_trap_id_t hostif_trapid, + _In_ sai_hostif_trap_id_t hostif_trap_id, _In_ const sai_attribute_t *attr) { SWSS_LOG_ENTER(); - return vs_generic_set( + std::string str_hostif_trap_id; + sai_serialize_primitive(hostif_trap_id, str_hostif_trap_id); + + return internal_vs_generic_set( SAI_OBJECT_TYPE_TRAP, - hostif_trapid, + str_hostif_trap_id, attr); } diff --git a/vslib/src/sai_vs_init.cpp b/vslib/src/sai_vs_init.cpp index 154a6787e78b..e119a20bed0d 100644 --- a/vslib/src/sai_vs_init.cpp +++ b/vslib/src/sai_vs_init.cpp @@ -1,98 +1,95 @@ #include "sai_vs.h" #include "sai_vs_state.h" -sai_object_id_t switch_object_id = (sai_object_id_t)SAI_OBJECT_TYPE_SWITCH << 48; +sai_object_id_t switch_object_id; #define CHECK_STATUS(status) \ - if (status != SAI_STATUS_SUCCESS) \ - return status; +{\ + sai_status_t s = (status);\ + if (s != SAI_STATUS_SUCCESS) \ + return s;\ +} #define DEFAULT_VLAN_NUMBER 1 -sai_status_t initialize_default_objects() +// TODO extra work may be needed on GET api if N on list will be > then actual + +sai_status_t create_default_switch() { SWSS_LOG_ENTER(); - sai_status_t status; - SWSS_LOG_INFO("create internal switch object"); - { - sai_attribute_t attr; - - status = vs_generic_create( - SAI_OBJECT_TYPE_SWITCH, - &switch_object_id, - 0, - &attr); + return vs_generic_create( + SAI_OBJECT_TYPE_SWITCH, + &switch_object_id, + 0, + NULL); +} - CHECK_STATUS(status); - } +sai_status_t set_switch_mac_address() +{ + SWSS_LOG_ENTER(); SWSS_LOG_INFO("create switch src mac address"); - { - sai_attribute_t attr; + sai_attribute_t attr; - attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; - attr.value.mac[0] = 0x11; - attr.value.mac[1] = 0x22; - attr.value.mac[2] = 0x33; - attr.value.mac[3] = 0x44; - attr.value.mac[4] = 0x55; - attr.value.mac[5] = 0x66; + attr.id = SAI_SWITCH_ATTR_SRC_MAC_ADDRESS; - status = vs_generic_set_switch(&attr); + attr.value.mac[0] = 0x11; + attr.value.mac[1] = 0x22; + attr.value.mac[2] = 0x33; + attr.value.mac[3] = 0x44; + attr.value.mac[4] = 0x55; + attr.value.mac[5] = 0x66; - CHECK_STATUS(status); - } + return vs_generic_set_switch(&attr); +} + +sai_status_t create_default_vlan() +{ + SWSS_LOG_ENTER(); SWSS_LOG_INFO("create default vlan"); - { - status = vs_generic_create_vlan(DEFAULT_VLAN_NUMBER); + return vs_generic_create_vlan(DEFAULT_VLAN_NUMBER); +} - CHECK_STATUS(status); - } +sai_status_t create_cpu_port() +{ + SWSS_LOG_ENTER(); SWSS_LOG_INFO("create cpu port"); - { - sai_object_id_t cpu_port_id; - - sai_attribute_t attr; - - // currently we don't have attributes on cpu port - status = vs_generic_create(SAI_OBJECT_TYPE_PORT, &cpu_port_id, 0, &attr); - - CHECK_STATUS(status); - + sai_object_id_t cpu_port_id; - // populate cpu port object on switch + sai_attribute_t attr; - attr.id = SAI_SWITCH_ATTR_CPU_PORT; - attr.value.oid = cpu_port_id; + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_PORT, &cpu_port_id, 0, &attr)); - status = vs_generic_set_switch(&attr); + // populate cpu port object on switch + attr.id = SAI_SWITCH_ATTR_CPU_PORT; + attr.value.oid = cpu_port_id; - CHECK_STATUS(status); + CHECK_STATUS(vs_generic_set_switch(&attr)); - //attr.id = SAI_PORT_ATTR_TYPE; - //attr.value.s32 = SAI_PORT_TYPE_CPU; + // set type on cpu + attr.id = SAI_PORT_ATTR_TYPE; + attr.value.s32 = SAI_PORT_TYPE_CPU; - //status = vs_generic_set(SAI_OBJECT_TYPE_PORT, cpu_port_id, &attr); - - //CHECK_STATUS(status); - } + return vs_generic_set(SAI_OBJECT_TYPE_PORT, cpu_port_id, &attr); +} +sai_status_t create_ports(std::vector& port_list) +{ + SWSS_LOG_ENTER(); // TODO currently port information is hardcoded // but later on we can read this from config file const uint32_t port_count = 32; - std::vector port_list; - SWSS_LOG_INFO("create ports"); sai_uint32_t lanes[] = { @@ -130,135 +127,349 @@ sai_status_t initialize_default_objects() 101,102,103,104 }; - // create ports - { - for (uint32_t i = 0; i < port_count; i++) - { - SWSS_LOG_INFO("create port index %u", i); + port_list.clear(); - sai_object_id_t port_id; + for (uint32_t i = 0; i < port_count; i++) + { + SWSS_LOG_DEBUG("create port index %u", i); - sai_attribute_t attr; + sai_object_id_t port_id; - status = vs_generic_create(SAI_OBJECT_TYPE_PORT, &port_id, 0, &attr); + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_PORT, &port_id, 0, NULL)); - CHECK_STATUS(status); + port_list.push_back(port_id); - port_list.push_back(port_id); + sai_attribute_t attr; - // populate port object on switch + attr.id = SAI_PORT_ATTR_SPEED; + attr.value.u32 = 10 * 1000; - attr.id = SAI_PORT_ATTR_SPEED; - attr.value.u32 = 10 * 1000; + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); - status = vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr); + attr.id = SAI_PORT_ATTR_HW_LANE_LIST; + attr.value.u32list.count = 4; + attr.value.u32list.list = &lanes[4 * i]; - CHECK_STATUS(status); + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); - // populate lanes for each port + attr.id = SAI_PORT_ATTR_TYPE; + attr.value.s32 = SAI_PORT_TYPE_LOGICAL; - attr.id = SAI_PORT_ATTR_HW_LANE_LIST; - attr.value.u32list.count = 4; - attr.value.u32list.list = &lanes[4 * i]; + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); - status = vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr); + // TODO populate other port attributes + } - CHECK_STATUS(status); + return SAI_STATUS_SUCCESS; +} - // TODO populate ports attributes - // TODO populate vlan members - } - } +sai_status_t create_port_list(std::vector& port_list) +{ + SWSS_LOG_ENTER(); SWSS_LOG_INFO("create port list"); - { - sai_attribute_t attr; + // TODO this is static, when we start to "create/remove" ports + // we need to update this list since it's dynamic - attr.id = SAI_SWITCH_ATTR_PORT_LIST; - attr.value.objlist.count = port_count; - attr.value.objlist.list = port_list.data(); + sai_attribute_t attr; - status = vs_generic_set_switch(&attr); + uint32_t port_count = (uint32_t)port_list.size(); - CHECK_STATUS(status); + attr.id = SAI_SWITCH_ATTR_PORT_LIST; + attr.value.objlist.count = port_count; + attr.value.objlist.list = port_list.data(); - attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; - attr.value.u32 = port_count; + CHECK_STATUS(vs_generic_set_switch(&attr)); - status = vs_generic_set_switch(&attr); + attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + attr.value.u32 = port_count; - CHECK_STATUS(status); - } + return vs_generic_set_switch(&attr); +} + +sai_status_t create_default_virtual_router() +{ + SWSS_LOG_ENTER(); SWSS_LOG_INFO("create default virtual router"); + sai_object_id_t virtual_router_id; + + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &virtual_router_id, 0, NULL)); + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + attr.value.oid = virtual_router_id; + + return vs_generic_set_switch(&attr); +} + +sai_status_t create_vlan_members_for_default_vlan( + std::vector& port_list, + std::vector& vlan_member_list) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_INFO("create vlan members for all ports"); + + vlan_member_list.clear(); + + vlan_members_map[DEFAULT_VLAN_NUMBER] = {}; + + for (auto &port_id : port_list) { - sai_object_id_t virtual_router_id; + sai_object_id_t vlan_member_id; - sai_attribute_t attr; + std::vector attrs; + + sai_attribute_t attr_vlan_id; - status = vs_generic_create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &virtual_router_id, 0, &attr); + attr_vlan_id.id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; + attr_vlan_id.value.u16 = DEFAULT_VLAN_NUMBER; - CHECK_STATUS(status); + attrs.push_back(attr_vlan_id); - attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; - attr.value.oid = virtual_router_id; + sai_attribute_t attr_port_id; - status = vs_generic_set_switch(&attr); + attr_port_id.id = SAI_VLAN_MEMBER_ATTR_PORT_ID; + attr_port_id.value.oid = port_id; - CHECK_STATUS(status); + attrs.push_back(attr_port_id); + + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_VLAN_MEMBER, &vlan_member_id, (uint32_t)attrs.size(), attrs.data())); + + vlan_member_list.push_back(vlan_member_id); + + vlan_members_map[DEFAULT_VLAN_NUMBER].insert(vlan_member_id); } - SWSS_LOG_INFO("create vlan members for all ports"); + update_vlan_member_list_on_vlan(DEFAULT_VLAN_NUMBER); - std::vector vlan_member_list; + return SAI_STATUS_SUCCESS; +} + +/* +sai_status_t create_vlan_members_list_for_default_vlan(std::vector& vlan_member_list) +{ + SWSS_LOG_ENTER(); + SWSS_LOG_INFO("create vlan members list for default vlan"); + + // TODO this list must be modified when we add/remove vlan member + + sai_attribute_t attr; + + uint32_t members_count = (uint32_t)vlan_member_list.size(); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + attr.value.objlist.count = members_count; + attr.value.objlist.list = vlan_member_list.data(); + + return vs_generic_set_vlan(DEFAULT_VLAN_NUMBER, &attr); +} +*/ +/* +sai_status_t creae_vlan_member_list(std::vector& vlan_member_list) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_INFO("create vlan member list"); + + // TODO this list must be updated every time vlan member is created/removed + + sai_attribute_t attr; + + uint32_t vlan_member_list_count = (uint32_t)vlan_member_list.size(); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + attr.value.objlist.count = vlan_member_list_count; + attr.value.objlist.list = vlan_member_list.data(); + + return vs_generic_set_vlan(DEFAULT_VLAN_NUMBER, &attr); +} +*/ + +sai_status_t create_default_trap_group() +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_INFO("create default trap group"); + + sai_object_id_t trap_group_id; + + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_TRAP_GROUP, &trap_group_id, 0, NULL)); + + sai_attribute_t attr; + + // populate trap group on switch + attr.id = SAI_SWITCH_ATTR_DEFAULT_TRAP_GROUP; + attr.value.oid = trap_group_id; + + return vs_generic_set_switch(&attr); +} + +sai_status_t create_qos_queues(std::vector& port_list) +{ + SWSS_LOG_ENTER(); + + // TODO queues size may change when we will modify queue or ports + + SWSS_LOG_INFO("create qos queues"); + + // 10 in and 10 out queues per port + const uint32_t port_qos_queues_count = 20; + + for (auto &port_id : port_list) { - for (auto &portId : port_list) + std::vector queues; + + for (uint32_t i = 0; i < port_qos_queues_count; ++i) { - std::vector attrs; + sai_object_id_t queue_id; - sai_attribute_t attr_vlan_id; + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_QUEUE, &queue_id, 0, NULL)); - attr_vlan_id.id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; - attr_vlan_id.value.u16 = DEFAULT_VLAN_NUMBER; - attrs.push_back(attr_vlan_id); + queues.push_back(queue_id); + } - sai_attribute_t attr_port_id; + sai_attribute_t attr; - attr_port_id.id = SAI_VLAN_MEMBER_ATTR_PORT_ID; - attr_port_id.value.oid = portId; - attrs.push_back(attr_port_id); + attr.id = SAI_PORT_ATTR_QOS_NUMBER_OF_QUEUES; + attr.value.u32 = port_qos_queues_count; - sai_object_id_t vlan_member_id; - status = vs_generic_create(SAI_OBJECT_TYPE_VLAN_MEMBER, &vlan_member_id, (uint32_t)attrs.size() , attrs.data()); + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); - CHECK_STATUS(status); + attr.id = SAI_PORT_ATTR_QOS_QUEUE_LIST; + attr.value.objlist.count = port_qos_queues_count; + attr.value.objlist.list = queues.data(); - vlan_member_list.push_back(vlan_member_id); - } + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); } - SWSS_LOG_INFO("create vlan member list"); + return SAI_STATUS_SUCCESS; +} +sai_status_t create_priority_groups(std::vector& port_list) +{ + SWSS_LOG_ENTER(); + + // TODO prioirity groups size may change when we will modify pg or ports + + SWSS_LOG_INFO("create priority groups"); + + // + const uint32_t port_pgs_count = 8; + + for (auto &port_id : port_list) { - // TODO this list should be updated each time we modify any VLAN member - // and it probably should be handled inside create/remove vlan member api - // and not here + std::vector pgs; + + for (uint32_t i = 0; i < port_pgs_count; ++i) + { + sai_object_id_t pg_id; + + CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_PRIORITY_GROUP, &pg_id, 0, NULL)); + + pgs.push_back(pg_id); + } sai_attribute_t attr; - attr.id = SAI_VLAN_ATTR_MEMBER_LIST; - attr.value.objlist.count = (uint32_t)vlan_member_list.size(); - attr.value.objlist.list = vlan_member_list.data(); + attr.id = SAI_PORT_ATTR_NUMBER_OF_PRIORITY_GROUPS; + attr.value.u32 = port_pgs_count; + + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); - status = vs_generic_set_vlan(DEFAULT_VLAN_NUMBER, &attr); + attr.id = SAI_PORT_ATTR_PRIORITY_GROUP_LIST; + attr.value.objlist.count = port_pgs_count; + attr.value.objlist.list = pgs.data(); - CHECK_STATUS(status); + CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); } - return status; + return SAI_STATUS_SUCCESS; +} + +sai_status_t create_hostif_traps() +{ + SWSS_LOG_ENTER(); + + std::vector traps = { + 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_SWITCH_CUSTOM_RANGE_BASE, + 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_ROUTER_CUSTOM_RANGE_BASE, + SAI_HOSTIF_TRAP_ID_L3_MTU_ERROR, + SAI_HOSTIF_TRAP_ID_TTL_ERROR + }; + + for (auto trap: traps) + { + CHECK_STATUS(vs_generic_create_trap(trap, 0, NULL)); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t initialize_default_objects() +{ + SWSS_LOG_ENTER(); + + CHECK_STATUS(create_default_switch()); + CHECK_STATUS(set_switch_mac_address()); + CHECK_STATUS(create_default_vlan()); + CHECK_STATUS(create_cpu_port()); + + std::vector port_list; + + CHECK_STATUS(create_ports(port_list)); + CHECK_STATUS(create_port_list(port_list)); + + CHECK_STATUS(create_default_virtual_router()); + + std::vector vlan_member_list; + + CHECK_STATUS(create_vlan_members_for_default_vlan(port_list, vlan_member_list)); + // CHECK_STATUS(create_vlan_members_list_for_default_vlan(vlan_member_list)); + + CHECK_STATUS(create_default_trap_group()); + + CHECK_STATUS(create_qos_queues(port_list)); + CHECK_STATUS(create_priority_groups(port_list)); + + CHECK_STATUS(create_hostif_traps()); + + return SAI_STATUS_SUCCESS; } sai_status_t init_switch() diff --git a/vslib/src/sai_vs_vlan.cpp b/vslib/src/sai_vs_vlan.cpp index 1d21bc1f33e8..a5356881c3dc 100644 --- a/vslib/src/sai_vs_vlan.cpp +++ b/vslib/src/sai_vs_vlan.cpp @@ -1,5 +1,7 @@ #include "sai_vs.h" +std::map> vlan_members_map; + sai_status_t vs_create_vlan( _In_ sai_vlan_id_t vlan_id) { @@ -7,9 +9,16 @@ sai_status_t vs_create_vlan( SWSS_LOG_ENTER(); - return meta_sai_create_vlan( + sai_status_t status = meta_sai_create_vlan( vlan_id, &vs_generic_create_vlan); + + if (status == SAI_STATUS_SUCCESS) + { + vlan_members_map[vlan_id] = {}; + } + + return status; } sai_status_t vs_remove_vlan( @@ -19,9 +28,25 @@ sai_status_t vs_remove_vlan( SWSS_LOG_ENTER(); - return meta_sai_remove_vlan( + sai_status_t status = meta_sai_remove_vlan( vlan_id, &vs_generic_remove_vlan); + + if (status == SAI_STATUS_SUCCESS) + { + auto it = vlan_members_map.find(vlan_id); + + if (it == vlan_members_map.end()) + { + SWSS_LOG_ERROR("failed to find vlan %u in vlan members map", vlan_id); + + return SAI_STATUS_FAILURE; + } + + vlan_members_map.erase(it); + } + + return status; } sai_status_t vs_set_vlan_attribute( @@ -54,6 +79,60 @@ sai_status_t vs_get_vlan_attribute( &vs_generic_get_vlan); } +void update_vlan_member_list_on_vlan( + _In_ sai_vlan_id_t vlan_id) +{ + SWSS_LOG_ENTER(); + + std::vector vlan_member_list; + + sai_attribute_t attr; + + std::copy(vlan_members_map[vlan_id].begin(), vlan_members_map[vlan_id].end(), std::back_inserter(vlan_member_list)); + + uint32_t members_count = (uint32_t)vlan_member_list.size(); + + attr.id = SAI_VLAN_ATTR_MEMBER_LIST; + attr.value.objlist.count = members_count; + attr.value.objlist.list = vlan_member_list.data(); + + sai_status_t status = vs_generic_set_vlan(vlan_id, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("failed to update vlan %d members list: %d", vlan_id, status); + + throw std::runtime_error("failed to update vlan members list"); + } + + SWSS_LOG_INFO("updated vlan %d member list to %zu", vlan_id, vlan_member_list.size()); +} + +sai_vlan_id_t get_vlan_id_from_member( + _In_ sai_object_id_t vlan_member_id) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + + attr.id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; + + sai_status_t status = vs_generic_get( + SAI_OBJECT_TYPE_VLAN_MEMBER, + vlan_member_id, + 1, + &attr); + + if (status == SAI_STATUS_SUCCESS) + { + return (sai_vlan_id_t)attr.value.u16; + } + + SWSS_LOG_ERROR("failed to get vlan id from vlan member 0x%llx, status: %d", vlan_member_id, status); + + throw std::runtime_error("failed to get vlan id from vlan member"); +} + sai_status_t vs_create_vlan_member( _Out_ sai_object_id_t* vlan_member_id, _In_ uint32_t attr_count, @@ -63,12 +142,23 @@ sai_status_t vs_create_vlan_member( SWSS_LOG_ENTER(); - return meta_sai_create_oid( + sai_status_t status = meta_sai_create_oid( SAI_OBJECT_TYPE_VLAN_MEMBER, vlan_member_id, attr_count, attr_list, &vs_generic_create); + + if (status == SAI_STATUS_SUCCESS) + { + sai_vlan_id_t vlan_id = get_vlan_id_from_member(*vlan_member_id); + + vlan_members_map[vlan_id].insert(*vlan_member_id); + + update_vlan_member_list_on_vlan(vlan_id); + } + + return status; } sai_status_t vs_remove_vlan_member( @@ -78,10 +168,30 @@ sai_status_t vs_remove_vlan_member( SWSS_LOG_ENTER(); - return meta_sai_remove_oid( + sai_vlan_id_t vlan_id = get_vlan_id_from_member(vlan_member_id); + + sai_status_t status = meta_sai_remove_oid( SAI_OBJECT_TYPE_VLAN_MEMBER, vlan_member_id, &vs_generic_remove); + + if (status == SAI_STATUS_SUCCESS) + { + auto it = vlan_members_map[vlan_id].find(vlan_member_id); + + if (it == vlan_members_map[vlan_id].end()) + { + SWSS_LOG_ERROR("failed to find vlan member 0x%llx in vlan members map", vlan_member_id); + + return SAI_STATUS_FAILURE; + } + + vlan_members_map[vlan_id].erase(it); + + update_vlan_member_list_on_vlan(vlan_id); + } + + return status; } sai_status_t vs_set_vlan_member_attribute(