@@ -710,11 +710,17 @@ void SwitchOrch::doAppSwitchTableTask(Consumer &consumer)
710710 }
711711}
712712
713- bool SwitchOrch::setSwitchHashFieldListSai ( const SwitchHash &hash, bool isEcmpHash ) const
713+ sai_status_t SwitchOrch::setSwitchHashAttributeSai ( sai_attr_id_t attrType, sai_object_id_t oid ) const
714714{
715- const auto &oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .oid : m_switchHashDefaults.lagHash .oid ;
716- const auto &hfSet = isEcmpHash ? hash.ecmp_hash .value : hash.lag_hash .value ;
715+ sai_attribute_t attr;
716+ attr.id = attrType;
717+ attr.value .oid = oid;
718+ auto status = sai_switch_api->set_switch_attribute (gSwitchId , &attr);
719+ return status;
720+ }
717721
722+ sai_status_t SwitchOrch::setSwitchHashFieldListSai (const sai_object_id_t oid, const std::set<sai_native_hash_field_t > &hfSet) const
723+ {
718724 std::vector<sai_int32_t > hfList;
719725 std::transform (
720726 hfSet.cbegin (), hfSet.cend (), std::back_inserter (hfList),
@@ -728,6 +734,104 @@ bool SwitchOrch::setSwitchHashFieldListSai(const SwitchHash &hash, bool isEcmpHa
728734 attr.value .s32list .count = static_cast <sai_uint32_t >(hfList.size ());
729735
730736 auto status = sai_hash_api->set_hash_attribute (oid, &attr);
737+ return status;
738+ }
739+
740+ sai_status_t SwitchOrch::createHashObjectSai (sai_object_id_t &oid, const std::set<sai_native_hash_field_t > &hfSet) const
741+ {
742+ std::vector<sai_int32_t > hfList;
743+ std::transform (
744+ hfSet.cbegin (), hfSet.cend (), std::back_inserter (hfList),
745+ [](sai_native_hash_field_t value) { return static_cast <sai_int32_t >(value); }
746+ );
747+
748+ sai_attribute_t attr;
749+
750+ attr.id = SAI_HASH_ATTR_NATIVE_HASH_FIELD_LIST;
751+ attr.value .s32list .list = hfList.data ();
752+ attr.value .s32list .count = static_cast <sai_uint32_t >(hfList.size ());
753+
754+ auto status = sai_hash_api->create_hash (&oid, gSwitchId , 1 , &attr);
755+ return status;
756+ }
757+
758+ bool SwitchOrch::setSwitchHashFieldList (const SwitchHash &hash, bool isEcmpHash)
759+ {
760+ SWSS_LOG_ENTER ();
761+
762+ const auto &hfSet = isEcmpHash ? hash.ecmp_hash .value : hash.lag_hash .value ;
763+ const auto &oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .oid : m_switchHashDefaults.lagHash .oid ;
764+ const auto &platformSupportsOnlyV4V6 = isEcmpHash ? m_switchHashDefaults.ecmpHash .platformSupportsOnlyV4V6 : m_switchHashDefaults.lagHash .platformSupportsOnlyV4V6 ;
765+ auto &v4Oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .v4Oid : m_switchHashDefaults.lagHash .v4Oid ;
766+ auto &v6Oid = isEcmpHash ? m_switchHashDefaults.ecmpHash .v6Oid : m_switchHashDefaults.lagHash .v6Oid ;
767+
768+ sai_attr_id_t v4HashType = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH_IPV4 : SAI_SWITCH_ATTR_LAG_HASH_IPV4;
769+ sai_attr_id_t v6HashType = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH_IPV6 : SAI_SWITCH_ATTR_LAG_HASH_IPV6;
770+
771+ sai_status_t status;
772+
773+ if (!platformSupportsOnlyV4V6)
774+ {
775+ // oid == SAI_NULL_OBJECT_ID is acceptable for non-platformSupportsOnlyV4V6 platforms
776+ status = setSwitchHashFieldListSai (oid, hfSet);
777+ return status == SAI_STATUS_SUCCESS;
778+ }
779+
780+ // platform (broadcom) supports only V4/V6 attribute type, v4Oid/v6Oid can not be NULL for modifying hash-fields
781+ if (v4Oid == SAI_NULL_OBJECT_ID || v6Oid == SAI_NULL_OBJECT_ID)
782+ {
783+ sai_object_id_t v4OidAllotted, v6OidAllotted;
784+
785+ // clear out the existing default fields which are associated with SAI_NULL_OBJECT_ID
786+ // this step is necessary for broadcom chips
787+ SWSS_LOG_DEBUG (" Creating new oids for IPv4 and IPv6 Hash-fields" );
788+ status = setSwitchHashAttributeSai (v4HashType, SAI_NULL_OBJECT_ID);
789+ if ( status == SAI_STATUS_SUCCESS)
790+ {
791+ status = setSwitchHashAttributeSai (v6HashType, SAI_NULL_OBJECT_ID);
792+ }
793+ if (status != SAI_STATUS_SUCCESS)
794+ {
795+ SWSS_LOG_ERROR (" Failed to reset hash parameters during initialization" );
796+ return status == SAI_STATUS_SUCCESS;
797+ }
798+
799+ // create a new Hash object with given set of hash-fields
800+ status = createHashObjectSai (v4OidAllotted, hfSet);
801+ if (status == SAI_STATUS_SUCCESS)
802+ {
803+ status = createHashObjectSai (v6OidAllotted, hfSet);
804+ }
805+ if (status != SAI_STATUS_SUCCESS)
806+ {
807+ SWSS_LOG_ERROR (" Failed to create hash object, status=%d" , status);
808+ return false ;
809+ }
810+
811+ // set the hash attribute to new object oid
812+ status = setSwitchHashAttributeSai (v4HashType, v4OidAllotted);
813+ if (status == SAI_STATUS_SUCCESS)
814+ {
815+ status = setSwitchHashAttributeSai (v6HashType, v6OidAllotted);
816+ }
817+ if (status == SAI_STATUS_SUCCESS)
818+ {
819+ v4Oid = v4OidAllotted;
820+ v6Oid = v6OidAllotted;
821+ }
822+
823+ return status == SAI_STATUS_SUCCESS;
824+ }
825+
826+ SWSS_LOG_DEBUG (" Re-using IPv4 and IPv6 Hash-field oids" );
827+
828+ // oids are allotted previously, use them now
829+ status = setSwitchHashFieldListSai (v4Oid, hfSet);
830+ if (status == SAI_STATUS_SUCCESS)
831+ {
832+ status = setSwitchHashFieldListSai (v6Oid, hfSet);
833+ }
834+
731835 return status == SAI_STATUS_SUCCESS;
732836}
733837
@@ -761,7 +865,7 @@ bool SwitchOrch::setSwitchHash(const SwitchHash &hash)
761865 return false ;
762866 }
763867
764- if (!setSwitchHashFieldListSai (hash, true ))
868+ if (!setSwitchHashFieldList (hash, true ))
765869 {
766870 SWSS_LOG_ERROR (" Failed to set switch ECMP hash in SAI" );
767871 return false ;
@@ -796,7 +900,7 @@ bool SwitchOrch::setSwitchHash(const SwitchHash &hash)
796900 return false ;
797901 }
798902
799- if (!setSwitchHashFieldListSai (hash, false ))
903+ if (!setSwitchHashFieldList (hash, false ))
800904 {
801905 SWSS_LOG_ERROR (" Failed to set switch LAG hash in SAI" );
802906 return false ;
@@ -1912,15 +2016,16 @@ void SwitchOrch::querySwitchTpidCapability()
19122016 }
19132017}
19142018
1915- bool SwitchOrch::getSwitchHashOidSai (sai_object_id_t &oid, bool isEcmpHash ) const
2019+ bool SwitchOrch::getSwitchHashOidSai (sai_object_id_t &oid, sai_attr_id_t attr_id ) const
19162020{
19172021 sai_attribute_t attr;
1918- attr.id = isEcmpHash ? SAI_SWITCH_ATTR_ECMP_HASH : SAI_SWITCH_ATTR_LAG_HASH ;
2022+ attr.id = attr_id ;
19192023 attr.value .oid = SAI_NULL_OBJECT_ID;
19202024
19212025 auto status = sai_switch_api->get_switch_attribute (gSwitchId , 1 , &attr);
19222026 if (status != SAI_STATUS_SUCCESS)
19232027 {
2028+ SWSS_LOG_WARN (" Failed to get switch hash OID" );
19242029 return false ;
19252030 }
19262031
@@ -1932,15 +2037,40 @@ bool SwitchOrch::getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHash) cons
19322037void SwitchOrch::querySwitchHashDefaults ()
19332038{
19342039 SWSS_LOG_ENTER ();
1935-
1936- if (!getSwitchHashOidSai (m_switchHashDefaults.ecmpHash .oid , true ))
2040+ if (!getSwitchHashOidSai (m_switchHashDefaults.ecmpHash .oid , SAI_SWITCH_ATTR_ECMP_HASH) )
19372041 {
1938- SWSS_LOG_WARN (" Failed to get switch ECMP hash OID" );
2042+ auto rv4 = getSwitchHashOidSai (
2043+ m_switchHashDefaults.ecmpHash .v4Oid , SAI_SWITCH_ATTR_ECMP_HASH_IPV4);
2044+
2045+ auto rv6 = getSwitchHashOidSai (
2046+ m_switchHashDefaults.ecmpHash .v6Oid , SAI_SWITCH_ATTR_ECMP_HASH_IPV6);
2047+
2048+ if (!rv4 && !rv6)
2049+ {
2050+ SWSS_LOG_WARN (" Failed to get switch ECMP hash OID" );
2051+ }
2052+ else
2053+ {
2054+ m_switchHashDefaults.ecmpHash .platformSupportsOnlyV4V6 = true ;
2055+ }
19392056 }
19402057
1941- if (!getSwitchHashOidSai (m_switchHashDefaults.lagHash .oid , false ))
2058+ if (!getSwitchHashOidSai (m_switchHashDefaults.lagHash .oid , SAI_SWITCH_ATTR_LAG_HASH ))
19422059 {
1943- SWSS_LOG_WARN (" Failed to get switch LAG hash OID" );
2060+ auto rv4 = getSwitchHashOidSai (
2061+ m_switchHashDefaults.lagHash .v4Oid , SAI_SWITCH_ATTR_LAG_HASH_IPV4);
2062+
2063+ auto rv6 = getSwitchHashOidSai (
2064+ m_switchHashDefaults.lagHash .v6Oid , SAI_SWITCH_ATTR_LAG_HASH_IPV6);
2065+
2066+ if (!rv4 && !rv6)
2067+ {
2068+ SWSS_LOG_WARN (" Failed to get switch LAG hash OID" );
2069+ }
2070+ else
2071+ {
2072+ m_switchHashDefaults.lagHash .platformSupportsOnlyV4V6 = true ;
2073+ }
19442074 }
19452075}
19462076
0 commit comments