diff --git a/lib/inc/Recorder.h b/lib/inc/Recorder.h index 927bdc1f4..b747589ce 100644 --- a/lib/inc/Recorder.h +++ b/lib/inc/Recorder.h @@ -290,6 +290,18 @@ namespace sairedis _In_ sai_status_t status, _In_ const uint64_t *count); + void recordQueryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability); + + void recordQueryAttributeCapabilityResponse( + _In_ sai_status_t status, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _In_ const sai_attr_capability_t* capability); + void recordQueryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, @@ -303,6 +315,14 @@ namespace sairedis _In_ const sai_s32_list_t* enumValuesCapability); // TODO move to private + void recordQueryAttributeCapability( + _In_ const std::string& key, + _In_ const std::vector& arguments); + + void recordQueryAttributeCapabilityResponse( + _In_ sai_status_t status, + _In_ const std::vector& arguments); + void recordQueryAttributeEnumValuesCapability( _In_ const std::string& key, _In_ const std::vector& arguments); diff --git a/lib/inc/RedisRemoteSaiInterface.h b/lib/inc/RedisRemoteSaiInterface.h index 8ed001b75..12d624ae2 100644 --- a/lib/inc/RedisRemoteSaiInterface.h +++ b/lib/inc/RedisRemoteSaiInterface.h @@ -240,6 +240,12 @@ namespace sairedis _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, @@ -386,6 +392,9 @@ namespace sairedis private: // SAI API response + sai_status_t waitForQueryAttributeCapabilityResponse( + _Out_ sai_attr_capability_t* capability); + sai_status_t waitForQueryAattributeEnumValuesCapabilityResponse( _Inout_ sai_s32_list_t* enumValuesCapability); diff --git a/lib/inc/Sai.h b/lib/inc/Sai.h index 3cb1e9d9b..1ea13bac0 100644 --- a/lib/inc/Sai.h +++ b/lib/inc/Sai.h @@ -231,6 +231,12 @@ namespace sairedis _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/lib/inc/SaiInterface.h b/lib/inc/SaiInterface.h index 48c26996a..5ce7f727f 100644 --- a/lib/inc/SaiInterface.h +++ b/lib/inc/SaiInterface.h @@ -242,6 +242,12 @@ namespace sairedis _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) = 0; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) = 0; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/lib/inc/sairediscommon.h b/lib/inc/sairediscommon.h index 4a4ffff74..d0de3dd26 100644 --- a/lib/inc/sairediscommon.h +++ b/lib/inc/sairediscommon.h @@ -37,6 +37,9 @@ #define REDIS_ASIC_STATE_COMMAND_FLUSH "flush" #define REDIS_ASIC_STATE_COMMAND_FLUSHRESPONSE "flushresponse" +#define REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_QUERY "attribute_capability_query" +#define REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_RESPONSE "attribute_capability_response" + #define REDIS_ASIC_STATE_COMMAND_ATTR_ENUM_VALUES_CAPABILITY_QUERY "attr_enum_values_capability_query" #define REDIS_ASIC_STATE_COMMAND_ATTR_ENUM_VALUES_CAPABILITY_RESPONSE "attr_enum_values_capability_response" diff --git a/lib/src/Recorder.cpp b/lib/src/Recorder.cpp index becc9ef4c..448bd108f 100644 --- a/lib/src/Recorder.cpp +++ b/lib/src/Recorder.cpp @@ -265,6 +265,25 @@ void Recorder::recordFlushFdbEntriesResponse( recordLine("F|" + sai_serialize_status(status)); } +void Recorder::recordQueryAttributeCapability( + _In_ const std::string& key, + _In_ const std::vector& arguments) +{ + SWSS_LOG_ENTER(); + + recordLine("q|attribute_capability|" + key + "|" + joinFieldValues(arguments)); +} + +void Recorder::recordQueryAttributeCapabilityResponse( + _In_ sai_status_t status, + _In_ const std::vector& arguments) +{ + SWSS_LOG_ENTER(); + + recordLine("Q|attribute_capability|" + sai_serialize_status(status) + "|" + joinFieldValues(arguments)); +} + + void Recorder::recordQueryAttributeEnumValuesCapability( _In_ const std::string& key, _In_ const std::vector& arguments) @@ -886,6 +905,76 @@ void Recorder::recordObjectTypeGetAvailabilityResponse( recordObjectTypeGetAvailabilityResponse(status, values); } +void Recorder::recordQueryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *Capability) +{ + SWSS_LOG_ENTER(); + + auto meta = sai_metadata_get_attr_metadata(objectType, attrId); + + if (meta == NULL) + { + SWSS_LOG_ERROR("Failed to find attribute metadata: object type %s, attr id %d", + sai_serialize_object_type(objectType).c_str(), attrId); + return; + } + + auto key = sai_serialize_object_type(SAI_OBJECT_TYPE_SWITCH) + ":" + sai_serialize_object_id(switchId); + + auto object_type_str = sai_serialize_object_type(objectType); + const std::string attr_id_str = meta->attridname; + const std::vector values = + { + swss::FieldValueTuple("OBJECT_TYPE", object_type_str), + swss::FieldValueTuple("ATTR_ID", attr_id_str) + }; + + SWSS_LOG_DEBUG("Query arguments: switch %s, object_type: %s, attribute: %s", + key.c_str(), + object_type_str.c_str(), + meta->attridname); + + recordQueryAttributeCapability(key, values); +} + + +void Recorder::recordQueryAttributeCapabilityResponse( + _In_ sai_status_t status, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _In_ const sai_attr_capability_t* capability) +{ + SWSS_LOG_ENTER(); + + auto meta = sai_metadata_get_attr_metadata(objectType, attrId); + + if (meta == NULL) + { + SWSS_LOG_ERROR("Failed to find attribute metadata: object type %s, attr id %d", + sai_serialize_object_type(objectType).c_str(), attrId); + return; + } + + auto object_type_str = sai_serialize_object_type(objectType); + const std::string attr_id_str = meta->attridname; + const std::string create_str = (status == SAI_STATUS_SUCCESS ? (capability->create_implemented? "true":"false"): "false"); + const std::string set_str = (status == SAI_STATUS_SUCCESS ? (capability->set_implemented? "true":"false"): "false"); + const std::string get_str = (status == SAI_STATUS_SUCCESS ? (capability->get_implemented? "true":"false"): "false"); + const std::vector values = + { + swss::FieldValueTuple("OBJECT_TYPE", object_type_str), + swss::FieldValueTuple("ATTR_ID", attr_id_str), + swss::FieldValueTuple("CREATE_IMP", create_str), + swss::FieldValueTuple("SET_IMP", set_str), + swss::FieldValueTuple("GET_IMP", get_str) + }; + + recordQueryAttributeCapabilityResponse(status, values); +} + void Recorder::recordQueryAattributeEnumValuesCapability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/lib/src/RedisRemoteSaiInterface.cpp b/lib/src/RedisRemoteSaiInterface.cpp index 86de5e3a5..ec045b54f 100644 --- a/lib/src/RedisRemoteSaiInterface.cpp +++ b/lib/src/RedisRemoteSaiInterface.cpp @@ -827,6 +827,85 @@ sai_status_t RedisRemoteSaiInterface::waitForObjectTypeGetAvailabilityResponse( return status; } +sai_status_t RedisRemoteSaiInterface::queryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *capability) +{ + SWSS_LOG_ENTER(); + + auto switchIdStr = sai_serialize_object_id(switchId); + auto objectTypeStr = sai_serialize_object_type(objectType); + + auto meta = sai_metadata_get_attr_metadata(objectType, attrId); + + if (meta == NULL) + { + SWSS_LOG_ERROR("Failed to find attribute metadata: object type %s, attr id %d", objectTypeStr.c_str(), attrId); + return SAI_STATUS_INVALID_PARAMETER; + } + + const std::string attrIdStr = meta->attridname; + + const std::vector entry = + { + swss::FieldValueTuple("OBJECT_TYPE", objectTypeStr), + swss::FieldValueTuple("ATTR_ID", attrIdStr) + }; + + SWSS_LOG_DEBUG( + "Query arguments: switch %s, object type: %s, attribute: %s", + switchIdStr.c_str(), + objectTypeStr.c_str(), + attrIdStr.c_str() + ); + + // This query will not put any data into the ASIC view, just into the + // message queue + + m_recorder->recordQueryAttributeCapability(switchId, objectType, attrId, capability); + + m_redisChannel->set(switchIdStr, entry, REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_QUERY); + + auto status = waitForQueryAttributeCapabilityResponse(capability); + + m_recorder->recordQueryAttributeCapabilityResponse(status, objectType, attrId, capability); + + return status; +} + +sai_status_t RedisRemoteSaiInterface::waitForQueryAttributeCapabilityResponse( + _Out_ sai_attr_capability_t* capability) +{ + SWSS_LOG_ENTER(); + + swss::KeyOpFieldsValuesTuple kco; + + auto status = m_redisChannel->wait(REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_RESPONSE, kco); + + if (status == SAI_STATUS_SUCCESS) + { + const std::vector &values = kfvFieldsValues(kco); + + if (values.size() != 3) + { + SWSS_LOG_ERROR("Invalid response from syncd: expected 3 values, received %zu", values.size()); + + return SAI_STATUS_FAILURE; + } + + capability->create_implemented = (fvValue(values[0]) == "true" ? true : false); + capability->set_implemented = (fvValue(values[1]) == "true" ? true : false); + capability->get_implemented = (fvValue(values[2]) == "true" ? true : false); + + SWSS_LOG_DEBUG("Received payload: create_implemented:%s, set_implemented:%s, get_implemented:%s", + (capability->create_implemented? "true":"false"), (capability->set_implemented? "true":"false"), (capability->get_implemented? "true":"false")); + } + + return status; +} + sai_status_t RedisRemoteSaiInterface::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/lib/src/Sai.cpp b/lib/src/Sai.cpp index 483eccd41..83f46f101 100644 --- a/lib/src/Sai.cpp +++ b/lib/src/Sai.cpp @@ -576,6 +576,24 @@ sai_status_t Sai::objectTypeGetAvailability( count); } +sai_status_t Sai::queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) +{ + MUTEX(); + SWSS_LOG_ENTER(); + REDIS_CHECK_API_INITIALIZED(); + REDIS_CHECK_CONTEXT(switch_id); + + return context->m_meta->queryAttributeCapability( + switch_id, + object_type, + attr_id, + capability); +} + sai_status_t Sai::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/lib/src/sai_redis_interfacequery.cpp b/lib/src/sai_redis_interfacequery.cpp index 1d8d9f4c2..b90161cee 100644 --- a/lib/src/sai_redis_interfacequery.cpp +++ b/lib/src/sai_redis_interfacequery.cpp @@ -105,6 +105,21 @@ sai_status_t sai_api_query( return SAI_STATUS_INVALID_PARAMETER; } +sai_status_t sai_query_attribute_capability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) +{ + SWSS_LOG_ENTER(); + + return redis_sai->queryAttributeCapability( + switch_id, + object_type, + attr_id, + capability); +} + sai_status_t sai_query_attribute_enum_values_capability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/meta/DummySaiInterface.cpp b/meta/DummySaiInterface.cpp index da34ebe9a..3f32f9229 100644 --- a/meta/DummySaiInterface.cpp +++ b/meta/DummySaiInterface.cpp @@ -153,6 +153,17 @@ sai_status_t DummySaiInterface::objectTypeGetAvailability( return m_status; } +sai_status_t DummySaiInterface::queryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *capability) +{ + SWSS_LOG_ENTER(); + + return m_status; +} + sai_status_t DummySaiInterface::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/meta/DummySaiInterface.h b/meta/DummySaiInterface.h index 76007c8e1..b0d801233 100644 --- a/meta/DummySaiInterface.h +++ b/meta/DummySaiInterface.h @@ -230,6 +230,12 @@ namespace saimeta _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/meta/Meta.cpp b/meta/Meta.cpp index 9a6c3dc64..cecec4e86 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -1856,6 +1856,37 @@ sai_status_t Meta::objectTypeGetAvailability( return status; } +sai_status_t Meta::queryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *capability) +{ + SWSS_LOG_ENTER(); + + PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); + + auto mdp = sai_metadata_get_attr_metadata(objectType, attrId); + + if (!mdp) + { + SWSS_LOG_ERROR("unable to find attribute: %s:%d", + sai_serialize_object_type(objectType).c_str(), + attrId); + + return SAI_STATUS_INVALID_PARAMETER; + } + + PARAMETER_CHECK_IF_NOT_NULL(capability); + + auto status = m_implementation->queryAttributeCapability(switchId, objectType, attrId, capability); + + return status; +} + + sai_status_t Meta::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/meta/Meta.h b/meta/Meta.h index 7860fcc8b..498ce11ea 100644 --- a/meta/Meta.h +++ b/meta/Meta.h @@ -235,6 +235,12 @@ namespace saimeta _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 598aec166..b33a9af29 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -301,6 +301,9 @@ sai_status_t Syncd::processSingleEvent( if (op == REDIS_ASIC_STATE_COMMAND_FLUSH) return processFdbFlush(kco); + if (op == REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_QUERY) + return processAttrCapabilityQuery(kco); + if (op == REDIS_ASIC_STATE_COMMAND_ATTR_ENUM_VALUES_CAPABILITY_QUERY) return processAttrEnumValuesCapabilityQuery(kco); @@ -310,6 +313,59 @@ sai_status_t Syncd::processSingleEvent( SWSS_LOG_THROW("event op '%s' is not implemented, FIXME", op.c_str()); } +sai_status_t Syncd::processAttrCapabilityQuery( + _In_ const swss::KeyOpFieldsValuesTuple &kco) +{ + SWSS_LOG_ENTER(); + + auto& strSwitchVid = kfvKey(kco); + + sai_object_id_t switchVid; + sai_deserialize_object_id(strSwitchVid, switchVid); + + sai_object_id_t switchRid = m_translator->translateVidToRid(switchVid); + + auto& values = kfvFieldsValues(kco); + + if (values.size() != 2) + { + SWSS_LOG_ERROR("Invalid input: expected 2 arguments, received %zu", values.size()); + + m_getResponse->set(sai_serialize_status(SAI_STATUS_INVALID_PARAMETER), {}, REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_RESPONSE); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_type_t objectType; + sai_deserialize_object_type(fvValue(values[0]), objectType); + + sai_attr_id_t attrId; + sai_deserialize_attr_id(fvValue(values[1]), attrId); + + sai_attr_capability_t capability; + + sai_status_t status = m_vendorSai->queryAttributeCapability(switchRid, objectType, attrId, &capability); + + std::vector entry; + + if (status == SAI_STATUS_SUCCESS) + { + entry = + { + swss::FieldValueTuple("CREATE_IMPLEMENTED", (capability.create_implemented ? "true" : "false")), + swss::FieldValueTuple("SET_IMPLEMENTED", (capability.set_implemented ? "true" : "false")), + swss::FieldValueTuple("GET_IMPLEMENTED", (capability.get_implemented ? "true" : "false")) + }; + + SWSS_LOG_INFO("Sending response: create_implemented:%d, set_implemented:%d, get_implemented:%d", + capability.create_implemented, capability.set_implemented, capability.get_implemented); + } + + m_getResponse->set(sai_serialize_status(status), entry, REDIS_ASIC_STATE_COMMAND_ATTR_CAPABILITY_RESPONSE); + + return status; +} + sai_status_t Syncd::processAttrEnumValuesCapabilityQuery( _In_ const swss::KeyOpFieldsValuesTuple &kco) { diff --git a/syncd/Syncd.h b/syncd/Syncd.h index 92a31aee7..561f95797 100644 --- a/syncd/Syncd.h +++ b/syncd/Syncd.h @@ -120,6 +120,9 @@ namespace syncd sai_status_t processSingleEvent( _In_ const swss::KeyOpFieldsValuesTuple &kco); + sai_status_t processAttrCapabilityQuery( + _In_ const swss::KeyOpFieldsValuesTuple &kco); + sai_status_t processAttrEnumValuesCapabilityQuery( _In_ const swss::KeyOpFieldsValuesTuple &kco); diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index 0539ac4ca..aec6765d6 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -941,6 +941,27 @@ sai_status_t VendorSai::objectTypeGetAvailability( count); } +sai_status_t VendorSai::queryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *capability) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + +#if 0 // Wait until BRCM fix their SAI issue then enable this + return sai_query_attribute_capability( + switchId, + objectType, + attrId, + capability); +#else + return SAI_STATUS_NOT_IMPLEMENTED; +#endif +} + sai_status_t VendorSai::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/syncd/VendorSai.h b/syncd/VendorSai.h index 2f79aaf5d..0c91eaf83 100644 --- a/syncd/VendorSai.h +++ b/syncd/VendorSai.h @@ -227,6 +227,12 @@ namespace syncd _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/vslib/inc/Sai.h b/vslib/inc/Sai.h index 7412bd928..7a6ec637b 100644 --- a/vslib/inc/Sai.h +++ b/vslib/inc/Sai.h @@ -232,6 +232,12 @@ namespace saivs _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/vslib/inc/VirtualSwitchSaiInterface.h b/vslib/inc/VirtualSwitchSaiInterface.h index 0891585bd..0e41302a6 100644 --- a/vslib/inc/VirtualSwitchSaiInterface.h +++ b/vslib/inc/VirtualSwitchSaiInterface.h @@ -234,6 +234,12 @@ namespace saivs _In_ const sai_attribute_t *attrList, _Out_ uint64_t *count) override; + virtual sai_status_t queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) override; + virtual sai_status_t queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/vslib/src/Sai.cpp b/vslib/src/Sai.cpp index d2a0b1287..1699fd1c8 100644 --- a/vslib/src/Sai.cpp +++ b/vslib/src/Sai.cpp @@ -706,6 +706,23 @@ sai_status_t Sai::objectTypeGetAvailability( count); } +sai_status_t Sai::queryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *capability) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VS_CHECK_API_INITIALIZED(); + + return m_meta->queryAttributeCapability( + switchId, + objectType, + attrId, + capability); +} + sai_status_t Sai::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/vslib/src/VirtualSwitchSaiInterface.cpp b/vslib/src/VirtualSwitchSaiInterface.cpp index e35a90547..225c0e207 100644 --- a/vslib/src/VirtualSwitchSaiInterface.cpp +++ b/vslib/src/VirtualSwitchSaiInterface.cpp @@ -789,6 +789,26 @@ sai_status_t VirtualSwitchSaiInterface::objectTypeGetAvailability( return SAI_STATUS_NOT_SUPPORTED; } +sai_status_t VirtualSwitchSaiInterface::queryAttributeCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) +{ + SWSS_LOG_ENTER(); + + // TODO: We should generate this metadata for the virtual switch rather + // than hard-coding it here. + + // in virtual switch by default all apis are implemented for all objects. SUCCESS for all attributes + + capability->create_implemented = true; + capability->set_implemented = true; + capability->get_implemented = true; + + return SAI_STATUS_SUCCESS; +} + sai_status_t VirtualSwitchSaiInterface::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type, diff --git a/vslib/src/sai_vs_interfacequery.cpp b/vslib/src/sai_vs_interfacequery.cpp index dddddcd8a..0ea644e3f 100644 --- a/vslib/src/sai_vs_interfacequery.cpp +++ b/vslib/src/sai_vs_interfacequery.cpp @@ -104,6 +104,21 @@ sai_status_t sai_api_query( return SAI_STATUS_INVALID_PARAMETER; } +sai_status_t sai_query_attribute_capability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Out_ sai_attr_capability_t *capability) +{ + SWSS_LOG_ENTER(); + + return vs_sai->queryAttributeCapability( + switch_id, + object_type, + attr_id, + capability); +} + sai_status_t sai_query_attribute_enum_values_capability( _In_ sai_object_id_t switch_id, _In_ sai_object_type_t object_type,