From ac642f12c457841b7d598585042e19e0016065f1 Mon Sep 17 00:00:00 2001 From: Ravi Vantipalli Date: Wed, 4 Dec 2024 10:28:49 -0800 Subject: [PATCH] SAI UDF ACL switch changes Summary: Include UDF groups in the ACL table from udfGroups config. UDF fields in ACL entries have to match the attribute ID offset where group is defined in the ACL table. If udfGroup1 is at (SAI_ACL_TABLE_ATTR_USER_DEFINED_FIELD_GROUP_MIN + 1), the corresponding ACL entry data fields should also use (SAI_ACL_ENTRY_ATTR_USER_DEFINED_FIELD_GROUP_MIN + 1) https://github.com/opencomputeproject/SAI/blob/master/doc/ACL/UDF-based-ACL.md#example-1 Reviewed By: zechengh09 Differential Revision: D65044880 fbshipit-source-id: ccd4cad3968afdcc037d872a31cf3db54c7dccf9 --- .../hw/sai/switch/SaiAclTableManager.cpp | 129 +++++++++++++++++- .../agent/hw/sai/switch/SaiAclTableManager.h | 42 ++++++ .../hw/sai/switch/npu/SaiAclTableManager.cpp | 20 ++- 3 files changed, 181 insertions(+), 10 deletions(-) diff --git a/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp b/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp index 8a573ae5154c6..676f085dd8407 100644 --- a/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp +++ b/fboss/agent/hw/sai/switch/SaiAclTableManager.cpp @@ -22,6 +22,7 @@ #include "fboss/agent/hw/sai/switch/SaiPortManager.h" #include "fboss/agent/hw/sai/switch/SaiSwitch.h" #include "fboss/agent/hw/sai/switch/SaiSwitchManager.h" +#include "fboss/agent/hw/sai/switch/SaiUdfManager.h" #include "fboss/agent/hw/switch_asics/HwAsic.h" #include "fboss/agent/platforms/sai/SaiPlatform.h" @@ -562,6 +563,96 @@ SaiAclTableManager::addAclCounter( return std::make_pair(saiAclCounter, aclCounterTypeAndName); } +#if ( \ + (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ + (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ + !defined(TAJO_SDK)) +void SaiAclTableManager::updateUdfGroupAttributes( + const std::shared_ptr& addedAclEntry, + const std::string& aclTableName, + std::optional& udfGroup0, + std::optional& udfGroup1, + std::optional& udfGroup2, + std::optional& udfGroup3, + std::optional& udfGroup4) { + auto convertSignedCharsToUnsignedChars = + [](const std::vector& vec) { + std::vector unsignedVec; + + std::transform( + vec.begin(), + vec.end(), + std::back_inserter(unsignedVec), + [](signed char c) { return static_cast(c); }); + + return unsignedVec; + }; + + /* + * UDF fields in ACL entries have to match the attribute ID offset where + * group is defined in the ACL table + * If udfGroup1 is at (SAI_ACL_TABLE_ATTR_USER_DEFINED_FIELD_GROUP_MIN + 1), + * the corresponding ACL entry fields should also use + * (SAI_ACL_ENTRY_ATTR_USER_DEFINED_FIELD_GROUP_MIN + 1) + * https://github.com/opencomputeproject/SAI/blob/master/doc/ACL/UDF-based-ACL.md#example-1 + * + * We have capability to program 5 UDF fields. The below code will try + * to match the UDF group SAI ID currently processed with the attribute used + * in the ACL table + */ + if (addedAclEntry->getUdfTable()) { + auto& aclApi = SaiApiTable::getInstance()->aclApi(); + auto aclTableHandle = getAclTableHandle(aclTableName); + auto aclTableSaiId = aclTableHandle->aclTable->adapterKey(); + // Get the udfGroup IDs, if programmed, from each of the 5 attributes + auto udfGroupId0 = aclApi.getAttribute(aclTableSaiId, AclTableUdfGroup0()); + auto udfGroupId1 = aclApi.getAttribute(aclTableSaiId, AclTableUdfGroup1()); + auto udfGroupId2 = aclApi.getAttribute(aclTableSaiId, AclTableUdfGroup2()); + auto udfGroupId3 = aclApi.getAttribute(aclTableSaiId, AclTableUdfGroup3()); + auto udfGroupId4 = aclApi.getAttribute(aclTableSaiId, AclTableUdfGroup4()); + + const auto udfTable = addedAclEntry->getUdfTable().value(); + for (const auto& udfEntry : udfTable) { + auto data = convertSignedCharsToUnsignedChars(*udfEntry.roceBytes()); + auto mask = convertSignedCharsToUnsignedChars(*udfEntry.roceMask()); + auto udfData = std::make_pair(std::move(data), std::move(mask)); + + std::vector udfGroupNames = {*udfEntry.udfGroup()}; + auto udfGroupSaiIds = + managerTable_->udfManager().getUdfGroupIds(udfGroupNames); + if (udfGroupSaiIds.size() == 0) { + throw FbossError( + "Invalid UdfGroup {} in ACL entry", *udfEntry.udfGroup()); + } + auto udfGroupSaiId = udfGroupSaiIds[0]; + + // for each udfGroup used in this ACL entry, check which attribute it + // uses in the ACL table and use the same ACL entry attribute + if (udfGroupSaiId == udfGroupId0) { + udfGroup0 = AclEntryUdfGroup0{AclEntryFieldU8List{udfData}}; + continue; + } + if (udfGroupSaiId == udfGroupId1) { + udfGroup1 = AclEntryUdfGroup1{AclEntryFieldU8List{udfData}}; + continue; + } + if (udfGroupSaiId == udfGroupId2) { + udfGroup2 = AclEntryUdfGroup2{AclEntryFieldU8List{udfData}}; + continue; + } + if (udfGroupSaiId == udfGroupId3) { + udfGroup3 = AclEntryUdfGroup3{AclEntryFieldU8List{udfData}}; + continue; + } + if (udfGroupSaiId == udfGroupId4) { + udfGroup4 = AclEntryUdfGroup4{AclEntryFieldU8List{udfData}}; + continue; + } + } + } +} +#endif + AclEntrySaiId SaiAclTableManager::addAclEntry( const std::shared_ptr& addedAclEntry, const std::string& aclTableName) { @@ -876,6 +967,26 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( addedAclEntry->getLookupClassL2().value()))}; } +#if ( \ + (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ + (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ + !defined(TAJO_SDK)) + std::optional userDefinedGroup0{std::nullopt}; + std::optional userDefinedGroup1{std::nullopt}; + std::optional userDefinedGroup2{std::nullopt}; + std::optional userDefinedGroup3{std::nullopt}; + std::optional userDefinedGroup4{std::nullopt}; + + updateUdfGroupAttributes( + addedAclEntry, + aclTableName, + userDefinedGroup0, + userDefinedGroup1, + userDefinedGroup2, + userDefinedGroup3, + userDefinedGroup4); +#endif + // TODO(skhare) Support all other ACL actions std::optional aclActionPacketAction{std::nullopt}; @@ -1136,6 +1247,14 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( #endif #if !defined(TAJO_SDK) && !defined(BRCM_SAI_SDK_XGS) fieldIpv6NextHeader.has_value() || +#endif +#if ( \ + (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ + (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ + !defined(TAJO_SDK)) + userDefinedGroup0.has_value() || userDefinedGroup1.has_value() || + userDefinedGroup2.has_value() || userDefinedGroup3.has_value() || + userDefinedGroup4.has_value() || #endif platform_->getAsic()->isSupported(HwAsic::Feature::EMPTY_ACL_MATCHER)); if (fieldSrcPort.has_value()) { @@ -1205,11 +1324,11 @@ AclEntrySaiId SaiAclTableManager::addAclEntry( (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ !defined(TAJO_SDK)) - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, + userDefinedGroup0, + userDefinedGroup1, + userDefinedGroup2, + userDefinedGroup3, + userDefinedGroup4, #endif aclActionPacketAction, aclActionCounter, diff --git a/fboss/agent/hw/sai/switch/SaiAclTableManager.h b/fboss/agent/hw/sai/switch/SaiAclTableManager.h index 3e31f63e42ca2..02bee3e3a1b14 100644 --- a/fboss/agent/hw/sai/switch/SaiAclTableManager.h +++ b/fboss/agent/hw/sai/switch/SaiAclTableManager.h @@ -38,6 +38,33 @@ using SaiAclTable = SaiObject; using SaiAclEntry = SaiObject; using SaiAclCounter = SaiObject; +#if ( \ + (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ + (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ + !defined(TAJO_SDK)) +using AclTableUdfGroup0 = + SaiAclTableTraits::Attributes::UserDefinedFieldGroupMin0; +using AclTableUdfGroup1 = + SaiAclTableTraits::Attributes::UserDefinedFieldGroupMin1; +using AclTableUdfGroup2 = + SaiAclTableTraits::Attributes::UserDefinedFieldGroupMin2; +using AclTableUdfGroup3 = + SaiAclTableTraits::Attributes::UserDefinedFieldGroupMin3; +using AclTableUdfGroup4 = + SaiAclTableTraits::Attributes::UserDefinedFieldGroupMin4; + +using AclEntryUdfGroup0 = + SaiAclEntryTraits::Attributes::UserDefinedFieldGroupMin0; +using AclEntryUdfGroup1 = + SaiAclEntryTraits::Attributes::UserDefinedFieldGroupMin1; +using AclEntryUdfGroup2 = + SaiAclEntryTraits::Attributes::UserDefinedFieldGroupMin2; +using AclEntryUdfGroup3 = + SaiAclEntryTraits::Attributes::UserDefinedFieldGroupMin3; +using AclEntryUdfGroup4 = + SaiAclEntryTraits::Attributes::UserDefinedFieldGroupMin4; +#endif + struct SaiAclEntryHandle { /* * In FBOSS implementation, an ACL counter is always associated with single @@ -83,6 +110,8 @@ class SaiAclTableManager { */ static auto constexpr kDscpMask = 0x3F; + static auto constexpr kMaxUdfGroups = 5; + /* * L4 Src/Dst Port Mask. * L4 Src/Dst Port is 16-bit. @@ -138,6 +167,19 @@ class SaiAclTableManager { SaiAclTableHandle* FOLLY_NULLABLE getAclTableHandle(const std::string& aclTableName); +#if ( \ + (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ + (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ + !defined(TAJO_SDK)) + void updateUdfGroupAttributes( + const std::shared_ptr& addedAclEntry, + const std::string& aclTableName, + std::optional& udfGroup0, + std::optional& udfGroup1, + std::optional& udfGroup2, + std::optional& udfGroup3, + std::optional& udfGroup4); +#endif AclEntrySaiId addAclEntry( const std::shared_ptr& addedAclEntry, const std::string& aclTableName); diff --git a/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp b/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp index 65aea1e6d3675..61881035853e5 100644 --- a/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp +++ b/fboss/agent/hw/sai/switch/npu/SaiAclTableManager.cpp @@ -15,6 +15,7 @@ #include "fboss/agent/hw/sai/switch/SaiMirrorManager.h" #include "fboss/agent/hw/sai/switch/SaiPortManager.h" #include "fboss/agent/hw/sai/switch/SaiSwitchManager.h" +#include "fboss/agent/hw/sai/switch/SaiUdfManager.h" #include "fboss/agent/hw/switch_asics/HwAsic.h" #include "fboss/agent/platforms/sai/SaiPlatform.h" @@ -153,6 +154,15 @@ std:: return qualifierSet.find(qualifier) != qualifierSet.end(); }; + std::vector> udfGroupIds( + SaiAclTableManager::kMaxUdfGroups, std::nullopt); + int i = 0; + auto udfGroupSaiIds = managerTable_->udfManager().getUdfGroupIds( + addedAclTable->getUdfGroups()->toThrift()); + for (const auto udfGroupSaiId : udfGroupSaiIds) { + udfGroupIds[i++] = udfGroupSaiId; + } + SaiAclTableTraits::CreateAttributes attributes{ tableStage, bindPointList, @@ -191,11 +201,11 @@ std:: (SAI_API_VERSION >= SAI_VERSION(1, 14, 0) || \ (defined(BRCM_SAI_SDK_GTE_11_0) && defined(BRCM_SAI_SDK_XGS))) && \ !defined(TAJO_SDK)) - std::nullopt, // UserDefinedFieldGroupMin0 - std::nullopt, // UserDefinedFieldGroupMin1 - std::nullopt, // UserDefinedFieldGroupMin2 - std::nullopt, // UserDefinedFieldGroupMin3 - std::nullopt, // UserDefinedFieldGroupMin4 + udfGroupIds[0], // UserDefinedFieldGroupMin0 + udfGroupIds[1], // UserDefinedFieldGroupMin1 + udfGroupIds[2], // UserDefinedFieldGroupMin2 + udfGroupIds[3], // UserDefinedFieldGroupMin3 + udfGroupIds[4], // UserDefinedFieldGroupMin4 #endif };