@@ -711,11 +711,17 @@ void SwitchOrch::doAppSwitchTableTask(Consumer &consumer)
711711 }
712712}
713713
714- bool SwitchOrch::setSwitchHashFieldListSai ( const SwitchHash &hash, bool isEcmpHash ) const
714+ sai_status_t SwitchOrch::setSwitchHashAttributeSai ( sai_attr_id_t attrType, sai_object_id_t oid ) const
715715{
716- const auto &oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .oid : m_switchHashDefaults.lagHash .oid ;
717- const auto &hfSet = isEcmpHash ? hash.ecmp_hash .value : hash.lag_hash .value ;
716+ sai_attribute_t attr;
717+ attr.id = attrType;
718+ attr.value .oid = oid;
719+ auto status = sai_switch_api->set_switch_attribute (gSwitchId , &attr);
720+ return status;
721+ }
718722
723+ sai_status_t SwitchOrch::setSwitchHashFieldListSai (const sai_object_id_t oid, const std::set<sai_native_hash_field_t > &hfSet) const
724+ {
719725 std::vector<sai_int32_t > hfList;
720726 std::transform (
721727 hfSet.cbegin (), hfSet.cend (), std::back_inserter (hfList),
@@ -729,6 +735,104 @@ bool SwitchOrch::setSwitchHashFieldListSai(const SwitchHash &hash, bool isEcmpHa
729735 attr.value .s32list .count = static_cast <sai_uint32_t >(hfList.size ());
730736
731737 auto status = sai_hash_api->set_hash_attribute (oid, &attr);
738+ return status;
739+ }
740+
741+ sai_status_t SwitchOrch::createHashObjectSai (sai_object_id_t &oid, const std::set<sai_native_hash_field_t > &hfSet) const
742+ {
743+ std::vector<sai_int32_t > hfList;
744+ std::transform (
745+ hfSet.cbegin (), hfSet.cend (), std::back_inserter (hfList),
746+ [](sai_native_hash_field_t value) { return static_cast <sai_int32_t >(value); }
747+ );
748+
749+ sai_attribute_t attr;
750+
751+ attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST;
752+ attr.value .s32list .list = hfList.data ();
753+ attr.value .s32list .count = static_cast <sai_uint32_t >(hfList.size ());
754+
755+ auto status = sai_hash_api->create_hash (&oid, gSwitchId , 1 , &attr);
756+ return status;
757+ }
758+
759+ bool SwitchOrch::setSwitchHashFieldList (const SwitchHash &hash, bool isEcmpHash)
760+ {
761+ SWSS_LOG_ENTER ();
762+
763+ const auto &hfSet = isEcmpHash ? hash.ecmp_hash .value : hash.lag_hash .value ;
764+ const auto &oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .oid : m_switchHashDefaults.lagHash .oid ;
765+ const auto &platformSupportsOnlyV4V6 = isEcmpHash ? m_switchHashDefaults.ecmpHash .platformSupportsOnlyV4V6 : m_switchHashDefaults.lagHash .platformSupportsOnlyV4V6 ;
766+ auto &v4Oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .v4Oid : m_switchHashDefaults.lagHash .v4Oid ;
767+ auto &v6Oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .v6Oid : m_switchHashDefaults.lagHash .v6Oid ;
768+
769+ sai_attr_id_t v4HashType = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH_IPV4 : SAI_SWITCH_ATTR_LAG_HASH_IPV4;
770+ sai_attr_id_t v6HashType = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH_IPV6 : SAI_SWITCH_ATTR_LAG_HASH_IPV6;
771+
772+ sai_status_t status;
773+
774+ if (!platformSupportsOnlyV4V6)
775+ {
776+ // oid == SAI_NULL_OBJECT_ID is acceptable for non-platformSupportsOnlyV4V6 platforms
777+ status = setSwitchHashFieldListSai (oid, hfSet);
778+ return status == SAI_STATUS_SUCCESS;
779+ }
780+
781+ // platform (broadcom) supports only V4/V6 attribute type, v4Oid/v6Oid can not be NULL for modifying hash-fields
782+ if (v4Oid == SAI_NULL_OBJECT_ID || v6Oid == SAI_NULL_OBJECT_ID)
783+ {
784+ sai_object_id_t v4OidAllotted, v6OidAllotted;
785+
786+ // clear out the existing default fields which are associated with SAI_NULL_OBJECT_ID
787+ // this step is necessary for broadcom chips
788+ SWSS_LOG_DEBUG (" Creating new oids for IPv4 and IPv6 Hash-fields" );
789+ status = setSwitchHashAttributeSai (v4HashType, SAI_NULL_OBJECT_ID);
790+ if ( status == SAI_STATUS_SUCCESS)
791+ {
792+ status = setSwitchHashAttributeSai (v6HashType, SAI_NULL_OBJECT_ID);
793+ }
794+ if (status != SAI_STATUS_SUCCESS)
795+ {
796+ SWSS_LOG_ERROR (" Failed to reset hash parameters during initialization" );
797+ return status == SAI_STATUS_SUCCESS;
798+ }
799+
800+ // create a new Hash object with given set of hash-fields
801+ status = createHashObjectSai (v4OidAllotted, hfSet);
802+ if (status == SAI_STATUS_SUCCESS)
803+ {
804+ status = createHashObjectSai (v6OidAllotted, hfSet);
805+ }
806+ if (status != SAI_STATUS_SUCCESS)
807+ {
808+ SWSS_LOG_ERROR (" Failed to create hash object, status=%d" , status);
809+ return false ;
810+ }
811+
812+ // set the hash attribute to new object oid
813+ status = setSwitchHashAttributeSai (v4HashType, v4OidAllotted);
814+ if (status == SAI_STATUS_SUCCESS)
815+ {
816+ status = setSwitchHashAttributeSai (v6HashType, v6OidAllotted);
817+ }
818+ if (status == SAI_STATUS_SUCCESS)
819+ {
820+ v4Oid = v4OidAllotted;
821+ v6Oid = v6OidAllotted;
822+ }
823+
824+ return status == SAI_STATUS_SUCCESS;
825+ }
826+
827+ SWSS_LOG_DEBUG (" Re-using IPv4 and IPv6 Hash-field oids" );
828+
829+ // oids are allotted previously, use them now
830+ status = setSwitchHashFieldListSai (v4Oid, hfSet);
831+ if (status == SAI_STATUS_SUCCESS)
832+ {
833+ status = setSwitchHashFieldListSai (v6Oid, hfSet);
834+ }
835+
732836 return status == SAI_STATUS_SUCCESS;
733837}
734838
@@ -762,7 +866,7 @@ bool SwitchOrch::setSwitchHash(const SwitchHash &hash)
762866 return false ;
763867 }
764868
765- if (!setSwitchHashFieldListSai (hash, true ))
869+ if (!setSwitchHashFieldList (hash, true ))
766870 {
767871 SWSS_LOG_ERROR (" Failed to set switch ECMP hash in SAI" );
768872 return false ;
@@ -797,7 +901,7 @@ bool SwitchOrch::setSwitchHash(const SwitchHash &hash)
797901 return false ;
798902 }
799903
800- if (!setSwitchHashFieldListSai (hash, false ))
904+ if (!setSwitchHashFieldList (hash, false ))
801905 {
802906 SWSS_LOG_ERROR (" Failed to set switch LAG hash in SAI" );
803907 return false ;
@@ -1970,15 +2074,16 @@ void SwitchOrch::querySwitchTpidCapability()
19702074 }
19712075}
19722076
1973- bool SwitchOrch::getSwitchHashOidSai (sai_object_id_t &oid, bool isEcmpHash ) const
2077+ bool SwitchOrch::getSwitchHashOidSai (sai_object_id_t &oid, sai_attr_id_t attr_id ) const
19742078{
19752079 sai_attribute_t attr;
1976- attr.id = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH : SAI_SWITCH_ATTR_LAG_HASH ;
2080+ attr.id = attr_id ;
19772081 attr.value .oid = SAI_NULL_OBJECT_ID;
19782082
19792083 auto status = sai_switch_api->get_switch_attribute (gSwitchId , 1 , &attr);
19802084 if (status != SAI_STATUS_SUCCESS)
19812085 {
2086+ SWSS_LOG_WARN (" Failed to get switch hash OID" );
19822087 return false ;
19832088 }
19842089
@@ -1990,15 +2095,40 @@ bool SwitchOrch::getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHash) cons
19902095void SwitchOrch::querySwitchHashDefaults ()
19912096{
19922097 SWSS_LOG_ENTER ();
1993-
1994- if (!getSwitchHashOidSai (m_switchHashDefaults.ecmpHash .oid , true ))
2098+ if (!getSwitchHashOidSai (m_switchHashDefaults.ecmpHash .oid , SAI_SWITCH_ATTR_ECMP_HASH) )
19952099 {
1996- SWSS_LOG_WARN (" Failed to get switch ECMP hash OID" );
2100+ auto rv4 = getSwitchHashOidSai (
2101+ m_switchHashDefaults.ecmpHash .v4Oid , SAI_SWITCH_ATTR_ECMP_HASH_IPV4);
2102+
2103+ auto rv6 = getSwitchHashOidSai (
2104+ m_switchHashDefaults.ecmpHash .v6Oid , SAI_SWITCH_ATTR_ECMP_HASH_IPV6);
2105+
2106+ if (!rv4 && !rv6)
2107+ {
2108+ SWSS_LOG_WARN (" Failed to get switch ECMP hash OID" );
2109+ }
2110+ else
2111+ {
2112+ m_switchHashDefaults.ecmpHash .platformSupportsOnlyV4V6 = true ;
2113+ }
19972114 }
19982115
1999- if (!getSwitchHashOidSai (m_switchHashDefaults.lagHash .oid , false ))
2116+ if (!getSwitchHashOidSai (m_switchHashDefaults.lagHash .oid , SAI_SWITCH_ATTR_LAG_HASH ))
20002117 {
2001- SWSS_LOG_WARN (" Failed to get switch LAG hash OID" );
2118+ auto rv4 = getSwitchHashOidSai (
2119+ m_switchHashDefaults.lagHash .v4Oid , SAI_SWITCH_ATTR_LAG_HASH_IPV4);
2120+
2121+ auto rv6 = getSwitchHashOidSai (
2122+ m_switchHashDefaults.lagHash .v6Oid , SAI_SWITCH_ATTR_LAG_HASH_IPV6);
2123+
2124+ if (!rv4 && !rv6)
2125+ {
2126+ SWSS_LOG_WARN (" Failed to get switch LAG hash OID" );
2127+ }
2128+ else
2129+ {
2130+ m_switchHashDefaults.lagHash .platformSupportsOnlyV4V6 = true ;
2131+ }
20022132 }
20032133}
20042134
0 commit comments