From 58f8df3ee837d52fe3a356ad6094a737712c81e5 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 4 Jan 2023 14:37:53 +0200 Subject: [PATCH 1/2] [hash]: Implement GH backend. Signed-off-by: Nazarii Hnydyn --- orchagent/Makefile.am | 3 + orchagent/orchdaemon.cpp | 4 +- orchagent/p4orch/tests/Makefile.am | 2 + orchagent/p4orch/tests/test_main.cpp | 3 + orchagent/switch/swcap.cpp | 354 +++++++++++++++++++++++++ orchagent/switch/swcap.h | 68 +++++ orchagent/switch/swcnt.h | 28 ++ orchagent/switch/swhlpr.cpp | 142 ++++++++++ orchagent/switch/swhlpr.h | 27 ++ orchagent/switch/swschema.h | 25 ++ orchagent/switchorch.cpp | 272 ++++++++++++++++++- orchagent/switchorch.h | 31 +++ tests/mock_tests/Makefile.am | 2 + tests/mock_tests/aclorch_ut.cpp | 2 + tests/mock_tests/mock_orchagent_main.h | 1 + tests/mock_tests/ut_saihelper.cpp | 1 + tests/test_hash.py | 174 ++++++++++++ 17 files changed, 1131 insertions(+), 8 deletions(-) create mode 100644 orchagent/switch/swcap.cpp create mode 100644 orchagent/switch/swcap.h create mode 100644 orchagent/switch/swcnt.h create mode 100644 orchagent/switch/swhlpr.cpp create mode 100644 orchagent/switch/swhlpr.h create mode 100644 orchagent/switch/swschema.h create mode 100644 tests/test_hash.py diff --git a/orchagent/Makefile.am b/orchagent/Makefile.am index 5e3cd741cc..17827e7b1f 100644 --- a/orchagent/Makefile.am +++ b/orchagent/Makefile.am @@ -1,6 +1,7 @@ INCLUDES = -I $(top_srcdir)/lib \ -I $(top_srcdir) \ -I $(top_srcdir)/warmrestart \ + -I switch \ -I flex_counter \ -I debug_counter \ -I pbh \ @@ -73,6 +74,8 @@ orchagent_SOURCES = \ pbhorch.cpp \ saihelper.cpp \ saiattr.cpp \ + switch/swcap.cpp \ + switch/swhlpr.cpp \ switchorch.cpp \ pfcwdorch.cpp \ pfcactionhandler.cpp \ diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index a652b9b657..6254684cea 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -106,11 +106,13 @@ bool OrchDaemon::init() gCrmOrch = new CrmOrch(m_configDb, CFG_CRM_TABLE_NAME); - TableConnector stateDbSwitchTable(m_stateDb, "SWITCH_CAPABILITY"); + TableConnector stateDbSwitchTable(m_stateDb, STATE_SWITCH_CAPABILITY_TABLE_NAME); TableConnector app_switch_table(m_applDb, APP_SWITCH_TABLE_NAME); TableConnector conf_asic_sensors(m_configDb, CFG_ASIC_SENSORS_TABLE_NAME); + TableConnector conf_switch_hash(m_configDb, CFG_SWITCH_HASH_TABLE_NAME); vector switch_tables = { + conf_switch_hash, conf_asic_sensors, app_switch_table }; diff --git a/orchagent/p4orch/tests/Makefile.am b/orchagent/p4orch/tests/Makefile.am index d759033c68..1e55fa873a 100644 --- a/orchagent/p4orch/tests/Makefile.am +++ b/orchagent/p4orch/tests/Makefile.am @@ -26,6 +26,8 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \ $(ORCHAGENT_DIR)/vrforch.cpp \ $(ORCHAGENT_DIR)/vxlanorch.cpp \ $(ORCHAGENT_DIR)/copporch.cpp \ + $(ORCHAGENT_DIR)/switch/swcap.cpp \ + $(ORCHAGENT_DIR)/switch/swhlpr.cpp \ $(ORCHAGENT_DIR)/switchorch.cpp \ $(ORCHAGENT_DIR)/request_parser.cpp \ $(ORCHAGENT_DIR)/flex_counter/flex_counter_manager.cpp \ diff --git a/orchagent/p4orch/tests/test_main.cpp b/orchagent/p4orch/tests/test_main.cpp index 08b72a9377..e76104ce45 100644 --- a/orchagent/p4orch/tests/test_main.cpp +++ b/orchagent/p4orch/tests/test_main.cpp @@ -72,6 +72,7 @@ sai_acl_api_t *sai_acl_api; sai_policer_api_t *sai_policer_api; sai_virtual_router_api_t *sai_virtual_router_api; sai_hostif_api_t *sai_hostif_api; +sai_hash_api_t *sai_hash_api; sai_switch_api_t *sai_switch_api; sai_mirror_api_t *sai_mirror_api; sai_udf_api_t *sai_udf_api; @@ -191,6 +192,7 @@ int main(int argc, char *argv[]) sai_policer_api_t policer_api; sai_virtual_router_api_t virtual_router_api; sai_hostif_api_t hostif_api; + sai_hash_api_t hash_api; sai_switch_api_t switch_api; sai_mirror_api_t mirror_api; sai_udf_api_t udf_api; @@ -207,6 +209,7 @@ int main(int argc, char *argv[]) sai_policer_api = &policer_api; sai_virtual_router_api = &virtual_router_api; sai_hostif_api = &hostif_api; + sai_hash_api = &hash_api; sai_switch_api = &switch_api; sai_mirror_api = &mirror_api; sai_udf_api = &udf_api; diff --git a/orchagent/switch/swcap.cpp b/orchagent/switch/swcap.cpp new file mode 100644 index 0000000000..da6af31f50 --- /dev/null +++ b/orchagent/switch/swcap.cpp @@ -0,0 +1,354 @@ +// includes ----------------------------------------------------------------------------------------------------------- + +extern "C" { +#include +#include +#include +#include +} + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "swschema.h" +#include "swcap.h" + +using namespace swss; + +// defines ------------------------------------------------------------------------------------------------------------ + +#define SWITCH_CAPABILITY_HASH_NATIVE_HASH_FIELD_LIST_FIELD "HASH|NATIVE_HASH_FIELD_LIST" +#define SWITCH_CAPABILITY_ECMP_HASH_CAPABLE_FIELD "ECMP_HASH_CAPABLE" +#define SWITCH_CAPABILITY_LAG_HASH_CAPABLE_FIELD "LAG_HASH_CAPABLE" + +#define SWITCH_CAPABILITY_KEY "switch" + +#define SWITCH_STATE_DB_NAME "STATE_DB" +#define SWITCH_STATE_DB_TIMEOUT 0 + +// constants ---------------------------------------------------------------------------------------------------------- + +static const std::unordered_map swHashHashFieldMap = +{ + { SAI_NATIVE_HASH_FIELD_IN_PORT, SWITCH_HASH_FIELD_IN_PORT }, + { SAI_NATIVE_HASH_FIELD_DST_MAC, SWITCH_HASH_FIELD_DST_MAC }, + { SAI_NATIVE_HASH_FIELD_SRC_MAC, SWITCH_HASH_FIELD_SRC_MAC }, + { SAI_NATIVE_HASH_FIELD_ETHERTYPE, SWITCH_HASH_FIELD_ETHERTYPE }, + { SAI_NATIVE_HASH_FIELD_VLAN_ID, SWITCH_HASH_FIELD_VLAN_ID }, + { SAI_NATIVE_HASH_FIELD_IP_PROTOCOL, SWITCH_HASH_FIELD_IP_PROTOCOL }, + { SAI_NATIVE_HASH_FIELD_DST_IP, SWITCH_HASH_FIELD_DST_IP }, + { SAI_NATIVE_HASH_FIELD_SRC_IP, SWITCH_HASH_FIELD_SRC_IP }, + { SAI_NATIVE_HASH_FIELD_L4_DST_PORT, SWITCH_HASH_FIELD_L4_DST_PORT }, + { SAI_NATIVE_HASH_FIELD_L4_SRC_PORT, SWITCH_HASH_FIELD_L4_SRC_PORT }, + { SAI_NATIVE_HASH_FIELD_INNER_DST_MAC, SWITCH_HASH_FIELD_INNER_DST_MAC }, + { SAI_NATIVE_HASH_FIELD_INNER_SRC_MAC, SWITCH_HASH_FIELD_INNER_SRC_MAC }, + { SAI_NATIVE_HASH_FIELD_INNER_ETHERTYPE, SWITCH_HASH_FIELD_INNER_ETHERTYPE }, + { SAI_NATIVE_HASH_FIELD_INNER_IP_PROTOCOL, SWITCH_HASH_FIELD_INNER_IP_PROTOCOL }, + { SAI_NATIVE_HASH_FIELD_INNER_DST_IP, SWITCH_HASH_FIELD_INNER_DST_IP }, + { SAI_NATIVE_HASH_FIELD_INNER_SRC_IP, SWITCH_HASH_FIELD_INNER_SRC_IP }, + { SAI_NATIVE_HASH_FIELD_INNER_L4_DST_PORT, SWITCH_HASH_FIELD_INNER_L4_DST_PORT }, + { SAI_NATIVE_HASH_FIELD_INNER_L4_SRC_PORT, SWITCH_HASH_FIELD_INNER_L4_SRC_PORT } +}; + +// variables ---------------------------------------------------------------------------------------------------------- + +extern sai_object_id_t gSwitchId; + +// functions ---------------------------------------------------------------------------------------------------------- + +static std::string toStr(sai_object_type_t objType, sai_attr_id_t attrId) noexcept +{ + const auto *meta = sai_metadata_get_attr_metadata(objType, attrId); + + return meta != nullptr ? meta->attridname : "UNKNOWN"; +} + +static std::string toStr(const std::set &value) noexcept +{ + std::vector strList; + + for (const auto &cit1 : value) + { + const auto &cit2 = swHashHashFieldMap.find(cit1); + if (cit2 != swHashHashFieldMap.cend()) + { + strList.push_back(cit2->second); + } + } + + return join(",", strList.cbegin(), strList.cend()); +} + +static std::string toStr(bool value) noexcept +{ + return value ? "true" : "false"; +} + +// Switch capabilities ------------------------------------------------------------------------------------------------ + +DBConnector SwitchCapabilities::stateDb(SWITCH_STATE_DB_NAME, SWITCH_STATE_DB_TIMEOUT); +Table SwitchCapabilities::capTable(&stateDb, STATE_SWITCH_CAPABILITY_TABLE_NAME); + +SwitchCapabilities::SwitchCapabilities() +{ + this->queryHashCapabilities(); + this->querySwitchCapabilities(); + + this->writeHashCapabilitiesToDb(); + this->writeSwitchCapabilitiesToDb(); +} + +bool SwitchCapabilities::isSwitchEcmpHashSupported() const +{ + const auto &nativeHashFieldList = this->hashCapabilities.nativeHashFieldList; + const auto &ecmpHash = this->switchCapabilities.ecmpHash; + + return nativeHashFieldList.isAttrSupported && ecmpHash.isAttrSupported; +} + +bool SwitchCapabilities::isSwitchLagHashSupported() const +{ + const auto &nativeHashFieldList = this->hashCapabilities.nativeHashFieldList; + const auto &lagHash = this->switchCapabilities.lagHash; + + return nativeHashFieldList.isAttrSupported && lagHash.isAttrSupported; +} + +bool SwitchCapabilities::validateSwitchHashFieldCap(const std::set &hfSet) const +{ + if (!this->hashCapabilities.nativeHashFieldList.isEnumSupported) + { + return true; + } + + if (this->hashCapabilities.nativeHashFieldList.hfSet.empty()) + { + SWSS_LOG_ERROR("Failed to validate hash field: no hash field capabilities"); + return false; + } + + for (const auto &cit : hfSet) + { + if (this->hashCapabilities.nativeHashFieldList.hfSet.count(cit) == 0) + { + SWSS_LOG_ERROR("Failed to validate hash field: value(%s) is not supported"); + return false; + } + } + + return true; +} + +FieldValueTuple SwitchCapabilities::makeHashFieldCapDbEntry() const +{ + const auto &nativeHashFieldList = this->hashCapabilities.nativeHashFieldList; + + auto field = SWITCH_CAPABILITY_HASH_NATIVE_HASH_FIELD_LIST_FIELD; + auto value = nativeHashFieldList.isEnumSupported ? toStr(nativeHashFieldList.hfSet) : "N/A"; + + return FieldValueTuple(field, value); +} + +FieldValueTuple SwitchCapabilities::makeEcmpHashCapDbEntry() const +{ + auto field = SWITCH_CAPABILITY_ECMP_HASH_CAPABLE_FIELD; + auto value = toStr(this->isSwitchEcmpHashSupported()); + + return FieldValueTuple(field, value); +} + +FieldValueTuple SwitchCapabilities::makeLagHashCapDbEntry() const +{ + auto field = SWITCH_CAPABILITY_LAG_HASH_CAPABLE_FIELD; + auto value = toStr(this->isSwitchLagHashSupported()); + + return FieldValueTuple(field, value); +} + +sai_status_t SwitchCapabilities::queryEnumCapabilitiesSai(std::vector &capList, sai_object_type_t objType, sai_attr_id_t attrId) const +{ + sai_s32_list_t enumList = { .count = 0, .list = nullptr }; + + auto status = sai_query_attribute_enum_values_capability(gSwitchId, objType, attrId, &enumList); + if ((status != SAI_STATUS_SUCCESS) && (status != SAI_STATUS_BUFFER_OVERFLOW)) + { + return status; + } + + capList.resize(enumList.count); + enumList.list = capList.data(); + + return sai_query_attribute_enum_values_capability(gSwitchId, objType, attrId, &enumList); +} + +sai_status_t SwitchCapabilities::queryAttrCapabilitiesSai(sai_attr_capability_t &attrCap, sai_object_type_t objType, sai_attr_id_t attrId) const +{ + return sai_query_attribute_capability(gSwitchId, objType, attrId, &attrCap); +} + +void SwitchCapabilities::queryHashNativeHashFieldListEnumCapabilities() +{ + SWSS_LOG_ENTER(); + + std::vector hfList; + auto status = this->queryEnumCapabilitiesSai( + hfList, SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST + ); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR( + "Failed to get attribute(%s) enum value capabilities", + toStr(SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST).c_str() + ); + return; + } + + auto &hfSet = this->hashCapabilities.nativeHashFieldList.hfSet; + std::transform( + hfList.cbegin(), hfList.cend(), std::inserter(hfSet, hfSet.begin()), + [](sai_int32_t value) { return static_cast(value); } + ); + + this->hashCapabilities.nativeHashFieldList.isEnumSupported = true; +} + +void SwitchCapabilities::queryHashNativeHashFieldListAttrCapabilities() +{ + SWSS_LOG_ENTER(); + + sai_attr_capability_t attrCap; + + auto status = this->queryAttrCapabilitiesSai( + attrCap, SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST + ); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR( + "Failed to get attribute(%s) capabilities", + toStr(SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST).c_str() + ); + return; + } + + if (!attrCap.set_implemented) + { + SWSS_LOG_WARN( + "Attribute(%s) SET is not implemented in SAI", + toStr(SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST).c_str() + ); + return; + } + + this->hashCapabilities.nativeHashFieldList.isAttrSupported = true; +} + +void SwitchCapabilities::queryHashCapabilities() +{ + this->queryHashNativeHashFieldListEnumCapabilities(); + this->queryHashNativeHashFieldListAttrCapabilities(); +} + +void SwitchCapabilities::querySwitchEcmpHashCapabilities() +{ + SWSS_LOG_ENTER(); + + sai_attr_capability_t attrCap; + + auto status = this->queryAttrCapabilitiesSai( + attrCap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH + ); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR( + "Failed to get attribute(%s) capabilities", + toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH).c_str() + ); + return; + } + + if (!attrCap.get_implemented) + { + SWSS_LOG_WARN( + "Attribute(%s) GET is not implemented in SAI", + toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH).c_str() + ); + return; + } + + this->switchCapabilities.ecmpHash.isAttrSupported = true; +} + +void SwitchCapabilities::querySwitchLagHashCapabilities() +{ + SWSS_LOG_ENTER(); + + sai_attr_capability_t attrCap; + + auto status = this->queryAttrCapabilitiesSai( + attrCap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH + ); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR( + "Failed to get attribute(%s) capabilities", + toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH).c_str() + ); + return; + } + + if (!attrCap.get_implemented) + { + SWSS_LOG_WARN( + "Attribute(%s) GET is not implemented in SAI", + toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH).c_str() + ); + return; + } + + this->switchCapabilities.lagHash.isAttrSupported = true; +} + +void SwitchCapabilities::querySwitchCapabilities() +{ + this->querySwitchEcmpHashCapabilities(); + this->querySwitchLagHashCapabilities(); +} + +void SwitchCapabilities::writeHashCapabilitiesToDb() +{ + SWSS_LOG_ENTER(); + + auto key = SwitchCapabilities::capTable.getKeyName(SWITCH_CAPABILITY_KEY); + + std::vector fvList = { + this->makeHashFieldCapDbEntry() + }; + + SwitchCapabilities::capTable.set(SWITCH_CAPABILITY_KEY, fvList); + + SWSS_LOG_NOTICE("Wrote hash enum capabilities to State DB: %s key", key.c_str()); +} + +void SwitchCapabilities::writeSwitchCapabilitiesToDb() +{ + SWSS_LOG_ENTER(); + + auto key = SwitchCapabilities::capTable.getKeyName(SWITCH_CAPABILITY_KEY); + + std::vector fvList = { + this->makeEcmpHashCapDbEntry(), + this->makeLagHashCapDbEntry() + }; + + SwitchCapabilities::capTable.set(SWITCH_CAPABILITY_KEY, fvList); + + SWSS_LOG_NOTICE("Wrote switch hash capabilities to State DB: %s key", key.c_str()); +} diff --git a/orchagent/switch/swcap.h b/orchagent/switch/swcap.h new file mode 100644 index 0000000000..47dcb0c7ec --- /dev/null +++ b/orchagent/switch/swcap.h @@ -0,0 +1,68 @@ +#pragma once + +extern "C" { +#include +#include +#include +} + +#include +#include + +#include +#include + +class SwitchCapabilities final +{ +public: + SwitchCapabilities(); + ~SwitchCapabilities() = default; + + bool isSwitchEcmpHashSupported() const; + bool isSwitchLagHashSupported() const; + + bool validateSwitchHashFieldCap(const std::set &hfSet) const; + +private: + swss::FieldValueTuple makeHashFieldCapDbEntry() const; + swss::FieldValueTuple makeEcmpHashCapDbEntry() const; + swss::FieldValueTuple makeLagHashCapDbEntry() const; + + sai_status_t queryEnumCapabilitiesSai(std::vector &capList, sai_object_type_t objType, sai_attr_id_t attrId) const; + sai_status_t queryAttrCapabilitiesSai(sai_attr_capability_t &attrCap, sai_object_type_t objType, sai_attr_id_t attrId) const; + + void queryHashNativeHashFieldListEnumCapabilities(); + void queryHashNativeHashFieldListAttrCapabilities(); + + void querySwitchEcmpHashCapabilities(); + void querySwitchLagHashCapabilities(); + + void queryHashCapabilities(); + void querySwitchCapabilities(); + + void writeHashCapabilitiesToDb(); + void writeSwitchCapabilitiesToDb(); + + // Hash SAI capabilities + struct { + struct { + std::set hfSet; + bool isEnumSupported = false; + bool isAttrSupported = false; + } nativeHashFieldList; + } hashCapabilities; + + // Switch SAI capabilities + struct { + struct { + bool isAttrSupported = false; + } ecmpHash; + + struct { + bool isAttrSupported = false; + } lagHash; + } switchCapabilities; + + static swss::DBConnector stateDb; + static swss::Table capTable; +}; diff --git a/orchagent/switch/swcnt.h b/orchagent/switch/swcnt.h new file mode 100644 index 0000000000..c56ae166f0 --- /dev/null +++ b/orchagent/switch/swcnt.h @@ -0,0 +1,28 @@ +#pragma once + +extern "C" { +#include +} + +#include +#include +#include + +class SwitchHash final +{ +public: + SwitchHash() = default; + ~SwitchHash() = default; + + struct { + std::set value; + bool is_set = false; + } ecmp_hash; + + struct { + std::set value; + bool is_set = false; + } lag_hash; + + std::unordered_map fieldValueMap; +}; diff --git a/orchagent/switch/swhlpr.cpp b/orchagent/switch/swhlpr.cpp new file mode 100644 index 0000000000..071f3b98b9 --- /dev/null +++ b/orchagent/switch/swhlpr.cpp @@ -0,0 +1,142 @@ +// includes ----------------------------------------------------------------------------------------------------------- + +#include +#include +#include + +#include +#include + +#include "swschema.h" +#include "swhlpr.h" + +using namespace swss; + +// constants ---------------------------------------------------------------------------------------------------------- + +static const std::unordered_map swHashHashFieldMap = +{ + { SWITCH_HASH_FIELD_IN_PORT, SAI_NATIVE_HASH_FIELD_IN_PORT }, + { SWITCH_HASH_FIELD_DST_MAC, SAI_NATIVE_HASH_FIELD_DST_MAC }, + { SWITCH_HASH_FIELD_SRC_MAC, SAI_NATIVE_HASH_FIELD_SRC_MAC }, + { SWITCH_HASH_FIELD_ETHERTYPE, SAI_NATIVE_HASH_FIELD_ETHERTYPE }, + { SWITCH_HASH_FIELD_VLAN_ID, SAI_NATIVE_HASH_FIELD_VLAN_ID }, + { SWITCH_HASH_FIELD_IP_PROTOCOL, SAI_NATIVE_HASH_FIELD_IP_PROTOCOL }, + { SWITCH_HASH_FIELD_DST_IP, SAI_NATIVE_HASH_FIELD_DST_IP }, + { SWITCH_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_SRC_IP }, + { SWITCH_HASH_FIELD_L4_DST_PORT, SAI_NATIVE_HASH_FIELD_L4_DST_PORT }, + { SWITCH_HASH_FIELD_L4_SRC_PORT, SAI_NATIVE_HASH_FIELD_L4_SRC_PORT }, + { SWITCH_HASH_FIELD_INNER_DST_MAC, SAI_NATIVE_HASH_FIELD_INNER_DST_MAC }, + { SWITCH_HASH_FIELD_INNER_SRC_MAC, SAI_NATIVE_HASH_FIELD_INNER_SRC_MAC }, + { SWITCH_HASH_FIELD_INNER_ETHERTYPE, SAI_NATIVE_HASH_FIELD_INNER_ETHERTYPE }, + { SWITCH_HASH_FIELD_INNER_IP_PROTOCOL, SAI_NATIVE_HASH_FIELD_INNER_IP_PROTOCOL }, + { SWITCH_HASH_FIELD_INNER_DST_IP, SAI_NATIVE_HASH_FIELD_INNER_DST_IP }, + { SWITCH_HASH_FIELD_INNER_SRC_IP, SAI_NATIVE_HASH_FIELD_INNER_SRC_IP }, + { SWITCH_HASH_FIELD_INNER_L4_DST_PORT, SAI_NATIVE_HASH_FIELD_INNER_L4_DST_PORT }, + { SWITCH_HASH_FIELD_INNER_L4_SRC_PORT, SAI_NATIVE_HASH_FIELD_INNER_L4_SRC_PORT } +}; + +// switch helper ------------------------------------------------------------------------------------------------------ + +const SwitchHash& SwitchHelper::getSwHash() const +{ + return this->swHash; +} + +void SwitchHelper::setSwHash(const SwitchHash &hash) +{ + this->swHash = hash; +} + +template +bool SwitchHelper::parseSwHashFieldList(T &obj, const std::string &field, const std::string &value) const +{ + SWSS_LOG_ENTER(); + + const auto &hfList = tokenize(value, ','); + + if (hfList.empty()) + { + SWSS_LOG_ERROR("Failed to parse field(%s): empty list is prohibited", field.c_str()); + return false; + } + + const auto &hfSet = std::unordered_set(hfList.cbegin(), hfList.cend()); + + if (hfSet.size() != hfList.size()) + { + SWSS_LOG_ERROR("Duplicate hash fields in field(%s): unexpected value(%s)", field.c_str(), value.c_str()); + return false; + } + + for (const auto &cit1 : hfSet) + { + const auto &cit2 = swHashHashFieldMap.find(cit1); + if (cit2 == swHashHashFieldMap.cend()) + { + SWSS_LOG_ERROR("Failed to parse field(%s): invalid value(%s)", field.c_str(), value.c_str()); + return false; + } + + obj.value.insert(cit2->second); + } + + obj.is_set = true; + + return true; +} + +bool SwitchHelper::parseSwHashEcmpHash(SwitchHash &hash, const std::string &field, const std::string &value) const +{ + return this->parseSwHashFieldList(hash.ecmp_hash, field, value); +} + +bool SwitchHelper::parseSwHashLagHash(SwitchHash &hash, const std::string &field, const std::string &value) const +{ + return this->parseSwHashFieldList(hash.lag_hash, field, value); +} + +bool SwitchHelper::parseSwHash(SwitchHash &hash) const +{ + SWSS_LOG_ENTER(); + + for (const auto &cit : hash.fieldValueMap) + { + const auto &field = cit.first; + const auto &value = cit.second; + + if (field == SWITCH_HASH_ECMP_HASH) + { + if (!this->parseSwHashEcmpHash(hash, field, value)) + { + return false; + } + } + else if (field == SWITCH_HASH_LAG_HASH) + { + if (!this->parseSwHashLagHash(hash, field, value)) + { + return false; + } + } + else + { + SWSS_LOG_WARN("Unknown field(%s): skipping ...", field.c_str()); + } + } + + return this->validateSwHash(hash); +} + +bool SwitchHelper::validateSwHash(SwitchHash &hash) const +{ + SWSS_LOG_ENTER(); + + if (!hash.ecmp_hash.is_set && !hash.lag_hash.is_set) + { + SWSS_LOG_ERROR("Validation error: missing valid fields"); + return false; + } + + return true; +} diff --git a/orchagent/switch/swhlpr.h b/orchagent/switch/swhlpr.h new file mode 100644 index 0000000000..e9fd80756e --- /dev/null +++ b/orchagent/switch/swhlpr.h @@ -0,0 +1,27 @@ +#pragma once + +#include "swcnt.h" + +class SwitchHelper final +{ +public: + SwitchHelper() = default; + ~SwitchHelper() = default; + + const SwitchHash& getSwHash() const; + void setSwHash(const SwitchHash &hash); + + bool parseSwHash(SwitchHash &hash) const; + +private: + template + bool parseSwHashFieldList(T &obj, const std::string &field, const std::string &value) const; + + bool parseSwHashEcmpHash(SwitchHash &hash, const std::string &field, const std::string &value) const; + bool parseSwHashLagHash(SwitchHash &hash, const std::string &field, const std::string &value) const; + + bool validateSwHash(SwitchHash &hash) const; + +private: + SwitchHash swHash; +}; diff --git a/orchagent/switch/swschema.h b/orchagent/switch/swschema.h new file mode 100644 index 0000000000..c836eff120 --- /dev/null +++ b/orchagent/switch/swschema.h @@ -0,0 +1,25 @@ +#pragma once + +// defines ------------------------------------------------------------------------------------------------------------ + +#define SWITCH_HASH_FIELD_IN_PORT "IN_PORT" +#define SWITCH_HASH_FIELD_DST_MAC "DST_MAC" +#define SWITCH_HASH_FIELD_SRC_MAC "SRC_MAC" +#define SWITCH_HASH_FIELD_ETHERTYPE "ETHERTYPE" +#define SWITCH_HASH_FIELD_VLAN_ID "VLAN_ID" +#define SWITCH_HASH_FIELD_IP_PROTOCOL "IP_PROTOCOL" +#define SWITCH_HASH_FIELD_DST_IP "DST_IP" +#define SWITCH_HASH_FIELD_SRC_IP "SRC_IP" +#define SWITCH_HASH_FIELD_L4_DST_PORT "L4_DST_PORT" +#define SWITCH_HASH_FIELD_L4_SRC_PORT "L4_SRC_PORT" +#define SWITCH_HASH_FIELD_INNER_DST_MAC "INNER_DST_MAC" +#define SWITCH_HASH_FIELD_INNER_SRC_MAC "INNER_SRC_MAC" +#define SWITCH_HASH_FIELD_INNER_ETHERTYPE "INNER_ETHERTYPE" +#define SWITCH_HASH_FIELD_INNER_IP_PROTOCOL "INNER_IP_PROTOCOL" +#define SWITCH_HASH_FIELD_INNER_DST_IP "INNER_DST_IP" +#define SWITCH_HASH_FIELD_INNER_SRC_IP "INNER_SRC_IP" +#define SWITCH_HASH_FIELD_INNER_L4_DST_PORT "INNER_L4_DST_PORT" +#define SWITCH_HASH_FIELD_INNER_L4_SRC_PORT "INNER_L4_SRC_PORT" + +#define SWITCH_HASH_ECMP_HASH "ecmp_hash" +#define SWITCH_HASH_LAG_HASH "lag_hash" diff --git a/orchagent/switchorch.cpp b/orchagent/switchorch.cpp index 52ef7a24b3..6a57aa6525 100644 --- a/orchagent/switchorch.cpp +++ b/orchagent/switchorch.cpp @@ -14,9 +14,13 @@ using namespace std; using namespace swss; +#define CONFIG_DB_NAME "CONFIG_DB" +#define APPL_DB_NAME "APPL_DB" + extern sai_object_id_t gSwitchId; extern sai_switch_api_t *sai_switch_api; extern sai_acl_api_t *sai_acl_api; +extern sai_hash_api_t *sai_hash_api; extern MacAddress gVxlanMacAddress; extern CrmOrch *gCrmOrch; @@ -86,6 +90,8 @@ SwitchOrch::SwitchOrch(DBConnector *db, vector& connectors, Tabl initSensorsTable(); querySwitchTpidCapability(); querySwitchPortEgressSampleCapability(); + querySwitchHashDefaults(); + auto executorT = new ExecutableTimer(m_sensorsPollerTimer, this, "ASIC_SENSORS_POLL_TIMER"); Orch::addExecutor(executorT); } @@ -473,24 +479,230 @@ void SwitchOrch::doAppSwitchTableTask(Consumer &consumer) } } -void SwitchOrch::doTask(Consumer &consumer) +bool SwitchOrch::setSwitchHashFieldListSai(sai_object_id_t oid, std::vector &hfList) const +{ + sai_attribute_t attr; + + attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; + attr.value.s32list.list = hfList.data(); + attr.value.s32list.count = static_cast(hfList.size()); + + auto status = sai_hash_api->set_hash_attribute(oid, &attr); + return status == SAI_STATUS_SUCCESS; +} + +bool SwitchOrch::setSwitchHashEcmpHash(const SwitchHash &hash) const +{ + const auto &oid = this->m_switchHashDefaults.ecmpHash.oid; + const auto &hfSet = hash.ecmp_hash.value; + + std::vector hfList; + std::transform( + hfSet.cbegin(), hfSet.cend(), std::back_inserter(hfList), + [](sai_native_hash_field_t value) { return static_cast(value); } + ); + + return this->setSwitchHashFieldListSai(oid, hfList); +} + +bool SwitchOrch::setSwitchHashLagHash(const SwitchHash &hash) const +{ + const auto &oid = this->m_switchHashDefaults.lagHash.oid; + const auto &hfSet = hash.lag_hash.value; + + std::vector hfList; + std::transform( + hfSet.cbegin(), hfSet.cend(), std::back_inserter(hfList), + [](sai_native_hash_field_t value) { return static_cast(value); } + ); + + return this->setSwitchHashFieldListSai(oid, hfList); +} + +bool SwitchOrch::setSwitchHash(const SwitchHash &hash) { SWSS_LOG_ENTER(); - const string & table_name = consumer.getTableName(); - if (table_name == APP_SWITCH_TABLE_NAME) + auto hObj = this->swHlpr.getSwHash(); + auto cfgUpd = false; + + if (hash.ecmp_hash.is_set) + { + if (hObj.ecmp_hash.value != hash.ecmp_hash.value) + { + if (this->swCap.isSwitchEcmpHashSupported()) + { + if (!this->swCap.validateSwitchHashFieldCap(hash.ecmp_hash.value)) + { + SWSS_LOG_ERROR("Failed to validate switch ECMP hash: capability is not supported"); + return false; + } + + if (!this->setSwitchHashEcmpHash(hash)) + { + SWSS_LOG_ERROR("Failed to set switch ECMP hash in SAI"); + return false; + } + + cfgUpd = true; + } + else + { + SWSS_LOG_WARN("Switch ECMP hash configuration is not supported: skipping ..."); + } + } + } + else { - doAppSwitchTableTask(consumer); + if (hObj.ecmp_hash.is_set) + { + SWSS_LOG_ERROR("Failed to remove switch ECMP hash configuration: operation is not supported"); + return false; + } } - else if (table_name == CFG_ASIC_SENSORS_TABLE_NAME) + + if (hash.lag_hash.is_set) { - doCfgSensorsTableTask(consumer); + if (hObj.lag_hash.value != hash.lag_hash.value) + { + if (this->swCap.isSwitchLagHashSupported()) + { + if (!this->swCap.validateSwitchHashFieldCap(hash.lag_hash.value)) + { + SWSS_LOG_ERROR("Failed to validate switch LAG hash: capability is not supported"); + return false; + } + + if (!this->setSwitchHashLagHash(hash)) + { + SWSS_LOG_ERROR("Failed to set switch LAG hash in SAI"); + return false; + } + + cfgUpd = true; + } + else + { + SWSS_LOG_WARN("Switch LAG hash configuration is not supported: skipping ..."); + } + } } else { - SWSS_LOG_ERROR("Unknown table : %s", table_name.c_str()); + if (hObj.lag_hash.is_set) + { + SWSS_LOG_ERROR("Failed to remove switch LAG hash configuration: operation is not supported"); + return false; + } } + if (!cfgUpd) + { + SWSS_LOG_NOTICE("Switch hash in SAI is up-to-date"); + return true; + } + + this->swHlpr.setSwHash(hash); + + SWSS_LOG_NOTICE("Set switch hash in SAI"); + + return true; +} + +void SwitchOrch::doCfgSwitchHashTableTask(Consumer &consumer) +{ + SWSS_LOG_ENTER(); + + auto &map = consumer.m_toSync; + auto it = map.begin(); + + while (it != map.end()) + { + auto keyOpFieldsValues = it->second; + auto key = kfvKey(keyOpFieldsValues); + auto op = kfvOp(keyOpFieldsValues); + + SWSS_LOG_INFO("KEY: %s, OP: %s", key.c_str(), op.c_str()); + + if (key.empty()) + { + SWSS_LOG_ERROR("Failed to parse switch hash key: empty string"); + it = map.erase(it); + continue; + } + + SwitchHash hash; + + if (op == SET_COMMAND) + { + for (const auto &cit : kfvFieldsValues(keyOpFieldsValues)) + { + auto fieldName = fvField(cit); + auto fieldValue = fvValue(cit); + + SWSS_LOG_INFO("FIELD: %s, VALUE: %s", fieldName.c_str(), fieldValue.c_str()); + + hash.fieldValueMap[fieldName] = fieldValue; + } + + if (this->swHlpr.parseSwHash(hash)) + { + if (!this->setSwitchHash(hash)) + { + SWSS_LOG_ERROR("Failed to set switch hash: ASIC and CONFIG DB are diverged"); + } + } + } + else if (op == DEL_COMMAND) + { + SWSS_LOG_ERROR("Failed to remove switch hash: operation is not supported: ASIC and CONFIG DB are diverged"); + } + else + { + SWSS_LOG_ERROR("Unknown operation(%s)", op.c_str()); + } + + it = map.erase(it); + } +} + +void SwitchOrch::doTask(Consumer &consumer) +{ + SWSS_LOG_ENTER(); + + const std::string &dbName = consumer.getDbName(); + const std::string &tableName = consumer.getTableName(); + + if (dbName == CONFIG_DB_NAME) + { + if (tableName == CFG_SWITCH_HASH_TABLE_NAME) + { + doCfgSwitchHashTableTask(consumer); + } + else if (tableName == CFG_ASIC_SENSORS_TABLE_NAME) + { + doCfgSensorsTableTask(consumer); + } + else + { + SWSS_LOG_ERROR("Unknown table : %s", tableName.c_str()); + } + } + else if (dbName == APPL_DB_NAME) + { + if (tableName == APP_SWITCH_TABLE_NAME) + { + doAppSwitchTableTask(consumer); + } + else + { + SWSS_LOG_ERROR("Unknown table : %s", tableName.c_str()); + } + } + else + { + SWSS_LOG_ERROR("Unknown DB : %s", dbName.c_str()); + } } void SwitchOrch::doTask(NotificationConsumer& consumer) @@ -814,6 +1026,52 @@ void SwitchOrch::querySwitchTpidCapability() } } +bool SwitchOrch::getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHashOid) const +{ + sai_attribute_t attr; + attr.id = isEcmpHashOid ? SAI_SWITCH_ATTR_ECMP_HASH : SAI_SWITCH_ATTR_LAG_HASH; + attr.value.oid = SAI_NULL_OBJECT_ID; + + auto status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr); + oid = attr.value.oid; + + return status == SAI_STATUS_SUCCESS; +} + +void SwitchOrch::getSwitchHashEcmpOid() +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid = SAI_NULL_OBJECT_ID; + + if (!this->getSwitchHashOidSai(oid, true)) + { + SWSS_LOG_THROW("Failed to get switch ECMP hash OID"); + } + + this->m_switchHashDefaults.ecmpHash.oid = oid; +} + +void SwitchOrch::getSwitchHashLagOid() +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid = SAI_NULL_OBJECT_ID; + + if (!this->getSwitchHashOidSai(oid, false)) + { + SWSS_LOG_THROW("Failed to get switch LAG hash OID"); + } + + this->m_switchHashDefaults.lagHash.oid = oid; +} + +void SwitchOrch::querySwitchHashDefaults() +{ + this->getSwitchHashEcmpOid(); + this->getSwitchHashLagOid(); +} + bool SwitchOrch::querySwitchCapability(sai_object_type_t sai_object, sai_attr_id_t attr_id) { SWSS_LOG_ENTER(); diff --git a/orchagent/switchorch.h b/orchagent/switchorch.h index cabdb9359d..2063371c9f 100644 --- a/orchagent/switchorch.h +++ b/orchagent/switchorch.h @@ -3,6 +3,8 @@ #include "acltable.h" #include "orch.h" #include "timer.h" +#include "switch/swcap.h" +#include "switch/swhlpr.h" #define DEFAULT_ASIC_SENSORS_POLLER_INTERVAL 60 #define ASIC_SENSORS_POLLER_STATUS "ASIC_SENSORS_POLLER_STATUS" @@ -47,11 +49,24 @@ class SwitchOrch : public Orch private: void doTask(Consumer &consumer); void doTask(swss::SelectableTimer &timer); + void doCfgSwitchHashTableTask(Consumer &consumer); void doCfgSensorsTableTask(Consumer &consumer); void doAppSwitchTableTask(Consumer &consumer); void initSensorsTable(); void querySwitchTpidCapability(); void querySwitchPortEgressSampleCapability(); + + // Switch hash + bool setSwitchHashFieldListSai(sai_object_id_t oid, std::vector &hfList) const; + bool setSwitchHashEcmpHash(const SwitchHash &hash) const; + bool setSwitchHashLagHash(const SwitchHash &hash) const; + bool setSwitchHash(const SwitchHash &hash); + + bool getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHashOid) const; + void getSwitchHashEcmpOid(); + void getSwitchHashLagOid(); + void querySwitchHashDefaults(); + sai_status_t setSwitchTunnelVxlanParams(swss::FieldValueTuple &val); void setSwitchNonSaiAttributes(swss::FieldValueTuple &val); @@ -87,7 +102,23 @@ class SwitchOrch : public Orch bool m_orderedEcmpEnable = false; bool m_PfcDlrInitEnable = false; + // Switch hash SAI defaults + struct { + struct { + sai_object_id_t oid = SAI_NULL_OBJECT_ID; + } ecmpHash; + struct { + sai_object_id_t oid = SAI_NULL_OBJECT_ID; + } lagHash; + } m_switchHashDefaults; + // Information contained in the request from // external program for orchagent pre-shutdown state check WarmRestartCheck m_warmRestartCheck = {false, false, false}; + + // Switch OA capabilities + SwitchCapabilities swCap; + + // Switch OA helper + SwitchHelper swHlpr; }; diff --git a/tests/mock_tests/Makefile.am b/tests/mock_tests/Makefile.am index 3741e7da27..7c272c18d4 100644 --- a/tests/mock_tests/Makefile.am +++ b/tests/mock_tests/Makefile.am @@ -83,6 +83,8 @@ tests_SOURCES = aclorch_ut.cpp \ $(top_srcdir)/orchagent/pbhorch.cpp \ $(top_srcdir)/orchagent/saihelper.cpp \ $(top_srcdir)/orchagent/saiattr.cpp \ + $(top_srcdir)/orchagent/switch/swcap.cpp \ + $(top_srcdir)/orchagent/switch/swhlpr.cpp \ $(top_srcdir)/orchagent/switchorch.cpp \ $(top_srcdir)/orchagent/pfcwdorch.cpp \ $(top_srcdir)/orchagent/pfcactionhandler.cpp \ diff --git a/tests/mock_tests/aclorch_ut.cpp b/tests/mock_tests/aclorch_ut.cpp index 5c8866b240..b03d219138 100644 --- a/tests/mock_tests/aclorch_ut.cpp +++ b/tests/mock_tests/aclorch_ut.cpp @@ -19,6 +19,7 @@ extern VRFOrch *gVrfOrch; extern sai_acl_api_t *sai_acl_api; extern sai_switch_api_t *sai_switch_api; +extern sai_hash_api_t *sai_hash_api; extern sai_port_api_t *sai_port_api; extern sai_vlan_api_t *sai_vlan_api; extern sai_bridge_api_t *sai_bridge_api; @@ -312,6 +313,7 @@ namespace aclorch_test ASSERT_EQ(status, SAI_STATUS_SUCCESS); sai_api_query(SAI_API_SWITCH, (void **)&sai_switch_api); + sai_api_query(SAI_API_HASH, (void **)&sai_hash_api); sai_api_query(SAI_API_BRIDGE, (void **)&sai_bridge_api); sai_api_query(SAI_API_PORT, (void **)&sai_port_api); sai_api_query(SAI_API_VLAN, (void **)&sai_vlan_api); diff --git a/tests/mock_tests/mock_orchagent_main.h b/tests/mock_tests/mock_orchagent_main.h index bf8456829d..0a73734c20 100644 --- a/tests/mock_tests/mock_orchagent_main.h +++ b/tests/mock_tests/mock_orchagent_main.h @@ -62,6 +62,7 @@ extern Directory gDirectory; extern sai_acl_api_t *sai_acl_api; extern sai_switch_api_t *sai_switch_api; +extern sai_hash_api_t *sai_hash_api; extern sai_virtual_router_api_t *sai_virtual_router_api; extern sai_port_api_t *sai_port_api; extern sai_lag_api_t *sai_lag_api; diff --git a/tests/mock_tests/ut_saihelper.cpp b/tests/mock_tests/ut_saihelper.cpp index f7a1f2fb2d..8b6b35b6f7 100644 --- a/tests/mock_tests/ut_saihelper.cpp +++ b/tests/mock_tests/ut_saihelper.cpp @@ -64,6 +64,7 @@ namespace ut_helper } sai_api_query(SAI_API_SWITCH, (void **)&sai_switch_api); + sai_api_query(SAI_API_HASH, (void **)&sai_hash_api); sai_api_query(SAI_API_BRIDGE, (void **)&sai_bridge_api); sai_api_query(SAI_API_VIRTUAL_ROUTER, (void **)&sai_virtual_router_api); sai_api_query(SAI_API_SAMPLEPACKET, (void **)&sai_samplepacket_api); diff --git a/tests/test_hash.py b/tests/test_hash.py new file mode 100644 index 0000000000..9c08aabb65 --- /dev/null +++ b/tests/test_hash.py @@ -0,0 +1,174 @@ +import pytest +import logging + + +logging.basicConfig(level=logging.INFO) +hashlogger = logging.getLogger(__name__) + + +HASH_FIELD_LIST = [ + "DST_MAC", + "SRC_MAC", + "ETHERTYPE", + "IP_PROTOCOL", + "DST_IP", + "SRC_IP", + "L4_DST_PORT", + "L4_SRC_PORT" +] +INNER_HASH_FIELD_LIST = [ + "INNER_DST_MAC", + "INNER_SRC_MAC", + "INNER_ETHERTYPE", + "INNER_IP_PROTOCOL", + "INNER_DST_IP", + "INNER_SRC_IP", + "INNER_L4_DST_PORT", + "INNER_L4_SRC_PORT" +] +DEFAULT_HASH_FIELD_LIST = [ + "DST_MAC", + "SRC_MAC", + "ETHERTYPE", + "IN_PORT" +] + +SAI_HASH_FIELD_LIST = [ + "SAI_NATIVE_HASH_FIELD_DST_MAC", + "SAI_NATIVE_HASH_FIELD_SRC_MAC", + "SAI_NATIVE_HASH_FIELD_ETHERTYPE", + "SAI_NATIVE_HASH_FIELD_IP_PROTOCOL", + "SAI_NATIVE_HASH_FIELD_DST_IP", + "SAI_NATIVE_HASH_FIELD_SRC_IP", + "SAI_NATIVE_HASH_FIELD_L4_DST_PORT", + "SAI_NATIVE_HASH_FIELD_L4_SRC_PORT" +] +SAI_INNER_HASH_FIELD_LIST = [ + "SAI_NATIVE_HASH_FIELD_INNER_DST_MAC", + "SAI_NATIVE_HASH_FIELD_INNER_SRC_MAC", + "SAI_NATIVE_HASH_FIELD_INNER_ETHERTYPE", + "SAI_NATIVE_HASH_FIELD_INNER_IP_PROTOCOL", + "SAI_NATIVE_HASH_FIELD_INNER_DST_IP", + "SAI_NATIVE_HASH_FIELD_INNER_SRC_IP", + "SAI_NATIVE_HASH_FIELD_INNER_L4_DST_PORT", + "SAI_NATIVE_HASH_FIELD_INNER_L4_SRC_PORT" +] +SAI_DEFAULT_HASH_FIELD_LIST = [ + "SAI_NATIVE_HASH_FIELD_DST_MAC", + "SAI_NATIVE_HASH_FIELD_SRC_MAC", + "SAI_NATIVE_HASH_FIELD_ETHERTYPE", + "SAI_NATIVE_HASH_FIELD_IN_PORT" +] + + +@pytest.mark.usefixtures("dvs_hash_manager") +class TestHashBasicFlows: + @pytest.fixture(scope="class") + def hashData(self, dvs_hash_manager): + hashlogger.info("Initialize HASH data") + + hashlogger.info("Verify HASH count") + self.dvs_hash.verify_hash_count(0) + + hashlogger.info("Get ECMP/LAG HASH id") + hashIdList = sorted(self.dvs_hash.get_hash_ids()) + + # Assumption: VS has only two HASH objects: ECMP, LAG + meta_dict = { + "ecmp": hashIdList[0], + "lag": hashIdList[1] + } + + yield meta_dict + + hashlogger.info("Deinitialize HASH data") + + @pytest.mark.parametrize( + "hash,field", [ + pytest.param( + "ecmp", + "ecmp_hash", + id="ecmp-hash" + ), + pytest.param( + "lag", + "lag_hash", + id="lag-hash" + ) + ] + ) + @pytest.mark.parametrize( + "hfList,saiHfList", [ + pytest.param( + ",".join(HASH_FIELD_LIST), + SAI_HASH_FIELD_LIST, + id="outer-frame" + ), + pytest.param( + ",".join(INNER_HASH_FIELD_LIST), + SAI_INNER_HASH_FIELD_LIST, + id="inner-frame" + ) + ] + ) + def test_HashSwitchGlobalConfiguration(self, hash, field, hfList, saiHfList, testlog, hashData): + attr_dict = { + field: hfList + } + + hashlogger.info("Update {} hash".format(hash.upper())) + self.dvs_hash.update_switch_hash( + qualifiers=attr_dict + ) + + hashId = hashData[hash] + sai_attr_dict = { + "SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST": saiHfList + } + + hashlogger.info("Validate {} hash".format(hash.upper())) + self.dvs_hash.verify_hash_generic( + sai_hash_id=hashId, + sai_qualifiers=sai_attr_dict + ) + + @pytest.mark.parametrize( + "hash,field", [ + pytest.param( + "ecmp", + "ecmp_hash", + id="ecmp-hash" + ), + pytest.param( + "lag", + "lag_hash", + id="lag-hash" + ) + ] + ) + def test_HashDefaultSwitchGlobalConfiguration(self, hash, field, testlog, hashData): + attr_dict = { + field: ",".join(DEFAULT_HASH_FIELD_LIST) + } + + hashlogger.info("Update {} hash".format(hash.upper())) + self.dvs_hash.update_switch_hash( + qualifiers=attr_dict + ) + + hashId = hashData[hash] + sai_attr_dict = { + "SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST": SAI_DEFAULT_HASH_FIELD_LIST + } + + hashlogger.info("Validate {} hash".format(hash.upper())) + self.dvs_hash.verify_hash_generic( + sai_hash_id=hashId, + sai_qualifiers=sai_attr_dict + ) + + +# Add Dummy always-pass test at end as workaroud +# for issue when Flaky fail on final test it invokes module tear-down before retrying +def test_nonflaky_dummy(): + pass From 2cc8534dbd26bc6c27fe94e47152934353dd8201 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 1 Jun 2023 22:13:35 +0300 Subject: [PATCH 2/2] [hash]: Handle review comments. Signed-off-by: Nazarii Hnydyn --- orchagent/Makefile.am | 4 +- orchagent/p4orch/tests/Makefile.am | 4 +- .../{swcap.cpp => switch_capabilities.cpp} | 64 ++++----- .../switch/{swcap.h => switch_capabilities.h} | 0 .../switch/{swcnt.h => switch_container.h} | 0 .../switch/{swhlpr.cpp => switch_helper.cpp} | 18 +-- .../switch/{swhlpr.h => switch_helper.h} | 2 +- .../switch/{swschema.h => switch_schema.h} | 0 orchagent/switchorch.cpp | 136 ++++++------------ orchagent/switchorch.h | 12 +- tests/mock_tests/Makefile.am | 4 +- 11 files changed, 95 insertions(+), 149 deletions(-) rename orchagent/switch/{swcap.cpp => switch_capabilities.cpp} (84%) rename orchagent/switch/{swcap.h => switch_capabilities.h} (100%) rename orchagent/switch/{swcnt.h => switch_container.h} (100%) rename orchagent/switch/{swhlpr.cpp => switch_helper.cpp} (91%) rename orchagent/switch/{swhlpr.h => switch_helper.h} (95%) rename orchagent/switch/{swschema.h => switch_schema.h} (100%) diff --git a/orchagent/Makefile.am b/orchagent/Makefile.am index 17827e7b1f..03ec1e24ed 100644 --- a/orchagent/Makefile.am +++ b/orchagent/Makefile.am @@ -74,8 +74,8 @@ orchagent_SOURCES = \ pbhorch.cpp \ saihelper.cpp \ saiattr.cpp \ - switch/swcap.cpp \ - switch/swhlpr.cpp \ + switch/switch_capabilities.cpp \ + switch/switch_helper.cpp \ switchorch.cpp \ pfcwdorch.cpp \ pfcactionhandler.cpp \ diff --git a/orchagent/p4orch/tests/Makefile.am b/orchagent/p4orch/tests/Makefile.am index 1e55fa873a..34fd93f59b 100644 --- a/orchagent/p4orch/tests/Makefile.am +++ b/orchagent/p4orch/tests/Makefile.am @@ -26,8 +26,8 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \ $(ORCHAGENT_DIR)/vrforch.cpp \ $(ORCHAGENT_DIR)/vxlanorch.cpp \ $(ORCHAGENT_DIR)/copporch.cpp \ - $(ORCHAGENT_DIR)/switch/swcap.cpp \ - $(ORCHAGENT_DIR)/switch/swhlpr.cpp \ + $(ORCHAGENT_DIR)/switch/switch_capabilities.cpp \ + $(ORCHAGENT_DIR)/switch/switch_helper.cpp \ $(ORCHAGENT_DIR)/switchorch.cpp \ $(ORCHAGENT_DIR)/request_parser.cpp \ $(ORCHAGENT_DIR)/flex_counter/flex_counter_manager.cpp \ diff --git a/orchagent/switch/swcap.cpp b/orchagent/switch/switch_capabilities.cpp similarity index 84% rename from orchagent/switch/swcap.cpp rename to orchagent/switch/switch_capabilities.cpp index da6af31f50..d826a9e49f 100644 --- a/orchagent/switch/swcap.cpp +++ b/orchagent/switch/switch_capabilities.cpp @@ -18,8 +18,8 @@ extern "C" { #include #include -#include "swschema.h" -#include "swcap.h" +#include "switch_schema.h" +#include "switch_capabilities.h" using namespace swss; @@ -99,37 +99,37 @@ Table SwitchCapabilities::capTable(&stateDb, STATE_SWITCH_CAPABILITY_TABLE_NAME) SwitchCapabilities::SwitchCapabilities() { - this->queryHashCapabilities(); - this->querySwitchCapabilities(); + queryHashCapabilities(); + querySwitchCapabilities(); - this->writeHashCapabilitiesToDb(); - this->writeSwitchCapabilitiesToDb(); + writeHashCapabilitiesToDb(); + writeSwitchCapabilitiesToDb(); } bool SwitchCapabilities::isSwitchEcmpHashSupported() const { - const auto &nativeHashFieldList = this->hashCapabilities.nativeHashFieldList; - const auto &ecmpHash = this->switchCapabilities.ecmpHash; + const auto &nativeHashFieldList = hashCapabilities.nativeHashFieldList; + const auto &ecmpHash = switchCapabilities.ecmpHash; return nativeHashFieldList.isAttrSupported && ecmpHash.isAttrSupported; } bool SwitchCapabilities::isSwitchLagHashSupported() const { - const auto &nativeHashFieldList = this->hashCapabilities.nativeHashFieldList; - const auto &lagHash = this->switchCapabilities.lagHash; + const auto &nativeHashFieldList = hashCapabilities.nativeHashFieldList; + const auto &lagHash = switchCapabilities.lagHash; return nativeHashFieldList.isAttrSupported && lagHash.isAttrSupported; } bool SwitchCapabilities::validateSwitchHashFieldCap(const std::set &hfSet) const { - if (!this->hashCapabilities.nativeHashFieldList.isEnumSupported) + if (!hashCapabilities.nativeHashFieldList.isEnumSupported) { return true; } - if (this->hashCapabilities.nativeHashFieldList.hfSet.empty()) + if (hashCapabilities.nativeHashFieldList.hfSet.empty()) { SWSS_LOG_ERROR("Failed to validate hash field: no hash field capabilities"); return false; @@ -137,7 +137,7 @@ bool SwitchCapabilities::validateSwitchHashFieldCap(const std::sethashCapabilities.nativeHashFieldList.hfSet.count(cit) == 0) + if (hashCapabilities.nativeHashFieldList.hfSet.count(cit) == 0) { SWSS_LOG_ERROR("Failed to validate hash field: value(%s) is not supported"); return false; @@ -149,7 +149,7 @@ bool SwitchCapabilities::validateSwitchHashFieldCap(const std::sethashCapabilities.nativeHashFieldList; + const auto &nativeHashFieldList = hashCapabilities.nativeHashFieldList; auto field = SWITCH_CAPABILITY_HASH_NATIVE_HASH_FIELD_LIST_FIELD; auto value = nativeHashFieldList.isEnumSupported ? toStr(nativeHashFieldList.hfSet) : "N/A"; @@ -160,7 +160,7 @@ FieldValueTuple SwitchCapabilities::makeHashFieldCapDbEntry() const FieldValueTuple SwitchCapabilities::makeEcmpHashCapDbEntry() const { auto field = SWITCH_CAPABILITY_ECMP_HASH_CAPABLE_FIELD; - auto value = toStr(this->isSwitchEcmpHashSupported()); + auto value = toStr(isSwitchEcmpHashSupported()); return FieldValueTuple(field, value); } @@ -168,7 +168,7 @@ FieldValueTuple SwitchCapabilities::makeEcmpHashCapDbEntry() const FieldValueTuple SwitchCapabilities::makeLagHashCapDbEntry() const { auto field = SWITCH_CAPABILITY_LAG_HASH_CAPABLE_FIELD; - auto value = toStr(this->isSwitchLagHashSupported()); + auto value = toStr(isSwitchLagHashSupported()); return FieldValueTuple(field, value); } @@ -199,7 +199,7 @@ void SwitchCapabilities::queryHashNativeHashFieldListEnumCapabilities() SWSS_LOG_ENTER(); std::vector hfList; - auto status = this->queryEnumCapabilitiesSai( + auto status = queryEnumCapabilitiesSai( hfList, SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST ); if (status != SAI_STATUS_SUCCESS) @@ -211,13 +211,13 @@ void SwitchCapabilities::queryHashNativeHashFieldListEnumCapabilities() return; } - auto &hfSet = this->hashCapabilities.nativeHashFieldList.hfSet; + auto &hfSet = hashCapabilities.nativeHashFieldList.hfSet; std::transform( hfList.cbegin(), hfList.cend(), std::inserter(hfSet, hfSet.begin()), [](sai_int32_t value) { return static_cast(value); } ); - this->hashCapabilities.nativeHashFieldList.isEnumSupported = true; + hashCapabilities.nativeHashFieldList.isEnumSupported = true; } void SwitchCapabilities::queryHashNativeHashFieldListAttrCapabilities() @@ -226,7 +226,7 @@ void SwitchCapabilities::queryHashNativeHashFieldListAttrCapabilities() sai_attr_capability_t attrCap; - auto status = this->queryAttrCapabilitiesSai( + auto status = queryAttrCapabilitiesSai( attrCap, SAI_OBJECT_TYPE_HASH, SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST ); if (status != SAI_STATUS_SUCCESS) @@ -247,13 +247,13 @@ void SwitchCapabilities::queryHashNativeHashFieldListAttrCapabilities() return; } - this->hashCapabilities.nativeHashFieldList.isAttrSupported = true; + hashCapabilities.nativeHashFieldList.isAttrSupported = true; } void SwitchCapabilities::queryHashCapabilities() { - this->queryHashNativeHashFieldListEnumCapabilities(); - this->queryHashNativeHashFieldListAttrCapabilities(); + queryHashNativeHashFieldListEnumCapabilities(); + queryHashNativeHashFieldListAttrCapabilities(); } void SwitchCapabilities::querySwitchEcmpHashCapabilities() @@ -262,7 +262,7 @@ void SwitchCapabilities::querySwitchEcmpHashCapabilities() sai_attr_capability_t attrCap; - auto status = this->queryAttrCapabilitiesSai( + auto status = queryAttrCapabilitiesSai( attrCap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH ); if (status != SAI_STATUS_SUCCESS) @@ -283,7 +283,7 @@ void SwitchCapabilities::querySwitchEcmpHashCapabilities() return; } - this->switchCapabilities.ecmpHash.isAttrSupported = true; + switchCapabilities.ecmpHash.isAttrSupported = true; } void SwitchCapabilities::querySwitchLagHashCapabilities() @@ -292,7 +292,7 @@ void SwitchCapabilities::querySwitchLagHashCapabilities() sai_attr_capability_t attrCap; - auto status = this->queryAttrCapabilitiesSai( + auto status = queryAttrCapabilitiesSai( attrCap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH ); if (status != SAI_STATUS_SUCCESS) @@ -313,13 +313,13 @@ void SwitchCapabilities::querySwitchLagHashCapabilities() return; } - this->switchCapabilities.lagHash.isAttrSupported = true; + switchCapabilities.lagHash.isAttrSupported = true; } void SwitchCapabilities::querySwitchCapabilities() { - this->querySwitchEcmpHashCapabilities(); - this->querySwitchLagHashCapabilities(); + querySwitchEcmpHashCapabilities(); + querySwitchLagHashCapabilities(); } void SwitchCapabilities::writeHashCapabilitiesToDb() @@ -329,7 +329,7 @@ void SwitchCapabilities::writeHashCapabilitiesToDb() auto key = SwitchCapabilities::capTable.getKeyName(SWITCH_CAPABILITY_KEY); std::vector fvList = { - this->makeHashFieldCapDbEntry() + makeHashFieldCapDbEntry() }; SwitchCapabilities::capTable.set(SWITCH_CAPABILITY_KEY, fvList); @@ -344,8 +344,8 @@ void SwitchCapabilities::writeSwitchCapabilitiesToDb() auto key = SwitchCapabilities::capTable.getKeyName(SWITCH_CAPABILITY_KEY); std::vector fvList = { - this->makeEcmpHashCapDbEntry(), - this->makeLagHashCapDbEntry() + makeEcmpHashCapDbEntry(), + makeLagHashCapDbEntry() }; SwitchCapabilities::capTable.set(SWITCH_CAPABILITY_KEY, fvList); diff --git a/orchagent/switch/swcap.h b/orchagent/switch/switch_capabilities.h similarity index 100% rename from orchagent/switch/swcap.h rename to orchagent/switch/switch_capabilities.h diff --git a/orchagent/switch/swcnt.h b/orchagent/switch/switch_container.h similarity index 100% rename from orchagent/switch/swcnt.h rename to orchagent/switch/switch_container.h diff --git a/orchagent/switch/swhlpr.cpp b/orchagent/switch/switch_helper.cpp similarity index 91% rename from orchagent/switch/swhlpr.cpp rename to orchagent/switch/switch_helper.cpp index 071f3b98b9..d91f382b25 100644 --- a/orchagent/switch/swhlpr.cpp +++ b/orchagent/switch/switch_helper.cpp @@ -7,8 +7,8 @@ #include #include -#include "swschema.h" -#include "swhlpr.h" +#include "switch_schema.h" +#include "switch_helper.h" using namespace swss; @@ -40,12 +40,12 @@ static const std::unordered_map swHashHash const SwitchHash& SwitchHelper::getSwHash() const { - return this->swHash; + return swHash; } void SwitchHelper::setSwHash(const SwitchHash &hash) { - this->swHash = hash; + swHash = hash; } template @@ -88,12 +88,12 @@ bool SwitchHelper::parseSwHashFieldList(T &obj, const std::string &field, const bool SwitchHelper::parseSwHashEcmpHash(SwitchHash &hash, const std::string &field, const std::string &value) const { - return this->parseSwHashFieldList(hash.ecmp_hash, field, value); + return parseSwHashFieldList(hash.ecmp_hash, field, value); } bool SwitchHelper::parseSwHashLagHash(SwitchHash &hash, const std::string &field, const std::string &value) const { - return this->parseSwHashFieldList(hash.lag_hash, field, value); + return parseSwHashFieldList(hash.lag_hash, field, value); } bool SwitchHelper::parseSwHash(SwitchHash &hash) const @@ -107,14 +107,14 @@ bool SwitchHelper::parseSwHash(SwitchHash &hash) const if (field == SWITCH_HASH_ECMP_HASH) { - if (!this->parseSwHashEcmpHash(hash, field, value)) + if (!parseSwHashEcmpHash(hash, field, value)) { return false; } } else if (field == SWITCH_HASH_LAG_HASH) { - if (!this->parseSwHashLagHash(hash, field, value)) + if (!parseSwHashLagHash(hash, field, value)) { return false; } @@ -125,7 +125,7 @@ bool SwitchHelper::parseSwHash(SwitchHash &hash) const } } - return this->validateSwHash(hash); + return validateSwHash(hash); } bool SwitchHelper::validateSwHash(SwitchHash &hash) const diff --git a/orchagent/switch/swhlpr.h b/orchagent/switch/switch_helper.h similarity index 95% rename from orchagent/switch/swhlpr.h rename to orchagent/switch/switch_helper.h index e9fd80756e..611ce2b6fb 100644 --- a/orchagent/switch/swhlpr.h +++ b/orchagent/switch/switch_helper.h @@ -1,6 +1,6 @@ #pragma once -#include "swcnt.h" +#include "switch_container.h" class SwitchHelper final { diff --git a/orchagent/switch/swschema.h b/orchagent/switch/switch_schema.h similarity index 100% rename from orchagent/switch/swschema.h rename to orchagent/switch/switch_schema.h diff --git a/orchagent/switchorch.cpp b/orchagent/switchorch.cpp index 6a57aa6525..76c17812d4 100644 --- a/orchagent/switchorch.cpp +++ b/orchagent/switchorch.cpp @@ -14,9 +14,6 @@ using namespace std; using namespace swss; -#define CONFIG_DB_NAME "CONFIG_DB" -#define APPL_DB_NAME "APPL_DB" - extern sai_object_id_t gSwitchId; extern sai_switch_api_t *sai_switch_api; extern sai_acl_api_t *sai_acl_api; @@ -479,22 +476,10 @@ void SwitchOrch::doAppSwitchTableTask(Consumer &consumer) } } -bool SwitchOrch::setSwitchHashFieldListSai(sai_object_id_t oid, std::vector &hfList) const +bool SwitchOrch::setSwitchHashFieldListSai(const SwitchHash &hash, bool isEcmpHash) const { - sai_attribute_t attr; - - attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; - attr.value.s32list.list = hfList.data(); - attr.value.s32list.count = static_cast(hfList.size()); - - auto status = sai_hash_api->set_hash_attribute(oid, &attr); - return status == SAI_STATUS_SUCCESS; -} - -bool SwitchOrch::setSwitchHashEcmpHash(const SwitchHash &hash) const -{ - const auto &oid = this->m_switchHashDefaults.ecmpHash.oid; - const auto &hfSet = hash.ecmp_hash.value; + const auto &oid = isEcmpHash ? m_switchHashDefaults.ecmpHash.oid : m_switchHashDefaults.lagHash.oid; + const auto &hfSet = isEcmpHash ? hash.ecmp_hash.value : hash.lag_hash.value; std::vector hfList; std::transform( @@ -502,43 +487,36 @@ bool SwitchOrch::setSwitchHashEcmpHash(const SwitchHash &hash) const [](sai_native_hash_field_t value) { return static_cast(value); } ); - return this->setSwitchHashFieldListSai(oid, hfList); -} - -bool SwitchOrch::setSwitchHashLagHash(const SwitchHash &hash) const -{ - const auto &oid = this->m_switchHashDefaults.lagHash.oid; - const auto &hfSet = hash.lag_hash.value; + sai_attribute_t attr; - std::vector hfList; - std::transform( - hfSet.cbegin(), hfSet.cend(), std::back_inserter(hfList), - [](sai_native_hash_field_t value) { return static_cast(value); } - ); + attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST; + attr.value.s32list.list = hfList.data(); + attr.value.s32list.count = static_cast(hfList.size()); - return this->setSwitchHashFieldListSai(oid, hfList); + auto status = sai_hash_api->set_hash_attribute(oid, &attr); + return status == SAI_STATUS_SUCCESS; } bool SwitchOrch::setSwitchHash(const SwitchHash &hash) { SWSS_LOG_ENTER(); - auto hObj = this->swHlpr.getSwHash(); + auto hObj = swHlpr.getSwHash(); auto cfgUpd = false; if (hash.ecmp_hash.is_set) { if (hObj.ecmp_hash.value != hash.ecmp_hash.value) { - if (this->swCap.isSwitchEcmpHashSupported()) + if (swCap.isSwitchEcmpHashSupported()) { - if (!this->swCap.validateSwitchHashFieldCap(hash.ecmp_hash.value)) + if (!swCap.validateSwitchHashFieldCap(hash.ecmp_hash.value)) { SWSS_LOG_ERROR("Failed to validate switch ECMP hash: capability is not supported"); return false; } - if (!this->setSwitchHashEcmpHash(hash)) + if (!setSwitchHashFieldListSai(hash, true)) { SWSS_LOG_ERROR("Failed to set switch ECMP hash in SAI"); return false; @@ -565,15 +543,15 @@ bool SwitchOrch::setSwitchHash(const SwitchHash &hash) { if (hObj.lag_hash.value != hash.lag_hash.value) { - if (this->swCap.isSwitchLagHashSupported()) + if (swCap.isSwitchLagHashSupported()) { - if (!this->swCap.validateSwitchHashFieldCap(hash.lag_hash.value)) + if (!swCap.validateSwitchHashFieldCap(hash.lag_hash.value)) { SWSS_LOG_ERROR("Failed to validate switch LAG hash: capability is not supported"); return false; } - if (!this->setSwitchHashLagHash(hash)) + if (!setSwitchHashFieldListSai(hash, false)) { SWSS_LOG_ERROR("Failed to set switch LAG hash in SAI"); return false; @@ -596,13 +574,14 @@ bool SwitchOrch::setSwitchHash(const SwitchHash &hash) } } + // Don't update internal cache when config remains unchanged if (!cfgUpd) { SWSS_LOG_NOTICE("Switch hash in SAI is up-to-date"); return true; } - this->swHlpr.setSwHash(hash); + swHlpr.setSwHash(hash); SWSS_LOG_NOTICE("Set switch hash in SAI"); @@ -645,9 +624,9 @@ void SwitchOrch::doCfgSwitchHashTableTask(Consumer &consumer) hash.fieldValueMap[fieldName] = fieldValue; } - if (this->swHlpr.parseSwHash(hash)) + if (swHlpr.parseSwHash(hash)) { - if (!this->setSwitchHash(hash)) + if (!setSwitchHash(hash)) { SWSS_LOG_ERROR("Failed to set switch hash: ASIC and CONFIG DB are diverged"); } @@ -670,38 +649,23 @@ void SwitchOrch::doTask(Consumer &consumer) { SWSS_LOG_ENTER(); - const std::string &dbName = consumer.getDbName(); - const std::string &tableName = consumer.getTableName(); + const auto &tableName = consumer.getTableName(); - if (dbName == CONFIG_DB_NAME) + if (tableName == APP_SWITCH_TABLE_NAME) { - if (tableName == CFG_SWITCH_HASH_TABLE_NAME) - { - doCfgSwitchHashTableTask(consumer); - } - else if (tableName == CFG_ASIC_SENSORS_TABLE_NAME) - { - doCfgSensorsTableTask(consumer); - } - else - { - SWSS_LOG_ERROR("Unknown table : %s", tableName.c_str()); - } + doAppSwitchTableTask(consumer); } - else if (dbName == APPL_DB_NAME) + else if (tableName == CFG_ASIC_SENSORS_TABLE_NAME) { - if (tableName == APP_SWITCH_TABLE_NAME) - { - doAppSwitchTableTask(consumer); - } - else - { - SWSS_LOG_ERROR("Unknown table : %s", tableName.c_str()); - } + doCfgSensorsTableTask(consumer); + } + else if (tableName == CFG_SWITCH_HASH_TABLE_NAME) + { + doCfgSwitchHashTableTask(consumer); } else { - SWSS_LOG_ERROR("Unknown DB : %s", dbName.c_str()); + SWSS_LOG_ERROR("Unknown table : %s", tableName.c_str()); } } @@ -1026,50 +990,36 @@ void SwitchOrch::querySwitchTpidCapability() } } -bool SwitchOrch::getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHashOid) const +bool SwitchOrch::getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHash) const { sai_attribute_t attr; - attr.id = isEcmpHashOid ? SAI_SWITCH_ATTR_ECMP_HASH : SAI_SWITCH_ATTR_LAG_HASH; + attr.id = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH : SAI_SWITCH_ATTR_LAG_HASH; attr.value.oid = SAI_NULL_OBJECT_ID; auto status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr); + if (status != SAI_STATUS_SUCCESS) + { + return false; + } + oid = attr.value.oid; - return status == SAI_STATUS_SUCCESS; + return true; } -void SwitchOrch::getSwitchHashEcmpOid() +void SwitchOrch::querySwitchHashDefaults() { SWSS_LOG_ENTER(); - sai_object_id_t oid = SAI_NULL_OBJECT_ID; - - if (!this->getSwitchHashOidSai(oid, true)) + if (!getSwitchHashOidSai(m_switchHashDefaults.ecmpHash.oid, true)) { - SWSS_LOG_THROW("Failed to get switch ECMP hash OID"); + SWSS_LOG_WARN("Failed to get switch ECMP hash OID"); } - this->m_switchHashDefaults.ecmpHash.oid = oid; -} - -void SwitchOrch::getSwitchHashLagOid() -{ - SWSS_LOG_ENTER(); - - sai_object_id_t oid = SAI_NULL_OBJECT_ID; - - if (!this->getSwitchHashOidSai(oid, false)) + if (!getSwitchHashOidSai(m_switchHashDefaults.lagHash.oid, false)) { - SWSS_LOG_THROW("Failed to get switch LAG hash OID"); + SWSS_LOG_WARN("Failed to get switch LAG hash OID"); } - - this->m_switchHashDefaults.lagHash.oid = oid; -} - -void SwitchOrch::querySwitchHashDefaults() -{ - this->getSwitchHashEcmpOid(); - this->getSwitchHashLagOid(); } bool SwitchOrch::querySwitchCapability(sai_object_type_t sai_object, sai_attr_id_t attr_id) diff --git a/orchagent/switchorch.h b/orchagent/switchorch.h index 2063371c9f..c6ee9997f9 100644 --- a/orchagent/switchorch.h +++ b/orchagent/switchorch.h @@ -3,8 +3,8 @@ #include "acltable.h" #include "orch.h" #include "timer.h" -#include "switch/swcap.h" -#include "switch/swhlpr.h" +#include "switch/switch_capabilities.h" +#include "switch/switch_helper.h" #define DEFAULT_ASIC_SENSORS_POLLER_INTERVAL 60 #define ASIC_SENSORS_POLLER_STATUS "ASIC_SENSORS_POLLER_STATUS" @@ -57,14 +57,10 @@ class SwitchOrch : public Orch void querySwitchPortEgressSampleCapability(); // Switch hash - bool setSwitchHashFieldListSai(sai_object_id_t oid, std::vector &hfList) const; - bool setSwitchHashEcmpHash(const SwitchHash &hash) const; - bool setSwitchHashLagHash(const SwitchHash &hash) const; + bool setSwitchHashFieldListSai(const SwitchHash &hash, bool isEcmpHash) const; bool setSwitchHash(const SwitchHash &hash); - bool getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHashOid) const; - void getSwitchHashEcmpOid(); - void getSwitchHashLagOid(); + bool getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHash) const; void querySwitchHashDefaults(); sai_status_t setSwitchTunnelVxlanParams(swss::FieldValueTuple &val); diff --git a/tests/mock_tests/Makefile.am b/tests/mock_tests/Makefile.am index 7c272c18d4..47bcacaa74 100644 --- a/tests/mock_tests/Makefile.am +++ b/tests/mock_tests/Makefile.am @@ -83,8 +83,8 @@ tests_SOURCES = aclorch_ut.cpp \ $(top_srcdir)/orchagent/pbhorch.cpp \ $(top_srcdir)/orchagent/saihelper.cpp \ $(top_srcdir)/orchagent/saiattr.cpp \ - $(top_srcdir)/orchagent/switch/swcap.cpp \ - $(top_srcdir)/orchagent/switch/swhlpr.cpp \ + $(top_srcdir)/orchagent/switch/switch_capabilities.cpp \ + $(top_srcdir)/orchagent/switch/switch_helper.cpp \ $(top_srcdir)/orchagent/switchorch.cpp \ $(top_srcdir)/orchagent/pfcwdorch.cpp \ $(top_srcdir)/orchagent/pfcactionhandler.cpp \