Skip to content

Commit 5afa2ca

Browse files
- Enhance the code to account for SAI_SWITCH_ATTR_ECMP/LAG_HASH_IPV4/V6
1 parent 98198d0 commit 5afa2ca

File tree

3 files changed

+225
-27
lines changed

3 files changed

+225
-27
lines changed

orchagent/switch/switch_capabilities.cpp

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -399,29 +399,57 @@ void SwitchCapabilities::querySwitchEcmpHashAttrCapabilities()
399399
{
400400
SWSS_LOG_ENTER();
401401

402-
sai_attr_capability_t attrCap;
402+
sai_attr_capability_t ecmpCap;
403+
auto ecmpStatus = queryAttrCapabilitiesSai(
404+
ecmpCap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH
405+
);
406+
if (ecmpStatus != SAI_STATUS_SUCCESS)
407+
{
408+
SWSS_LOG_WARN(
409+
"Failed to get attribute(%s) capabilities",
410+
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH).c_str()
411+
);
412+
}
413+
else if (ecmpCap.get_implemented)
414+
{
415+
switchCapabilities.ecmpHash.isAttrSupported = true;
416+
return;
417+
}
403418

404-
auto status = queryAttrCapabilitiesSai(
405-
attrCap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH
419+
sai_attr_capability_t ecmpV4Cap;
420+
auto ecmpV4Status = queryAttrCapabilitiesSai(
421+
ecmpV4Cap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH_IPV4
406422
);
407-
if (status != SAI_STATUS_SUCCESS)
423+
if (ecmpV4Status != SAI_STATUS_SUCCESS)
408424
{
409425
SWSS_LOG_ERROR(
410426
"Failed to get attribute(%s) capabilities",
411-
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH).c_str()
427+
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH_IPV4).c_str()
412428
);
413429
return;
414430
}
415431

416-
if (!attrCap.get_implemented)
432+
sai_attr_capability_t ecmpV6Cap;
433+
auto ecmpV6Status = queryAttrCapabilitiesSai(
434+
ecmpV6Cap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH_IPV6
435+
);
436+
if (ecmpV6Status != SAI_STATUS_SUCCESS)
417437
{
418-
SWSS_LOG_WARN(
419-
"Attribute(%s) GET is not implemented in SAI",
420-
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH).c_str()
438+
SWSS_LOG_ERROR(
439+
"Failed to get attribute(%s) capabilities",
440+
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_ECMP_HASH_IPV6).c_str()
421441
);
422442
return;
423443
}
424444

445+
if (!ecmpV4Cap.get_implemented || !ecmpV6Cap.get_implemented)
446+
{
447+
SWSS_LOG_ERROR(
448+
"One or more of required ECMP capabilities not supported %d, %d",
449+
ecmpV4Cap.get_implemented, ecmpV6Cap.get_implemented
450+
);
451+
return;
452+
}
425453
switchCapabilities.ecmpHash.isAttrSupported = true;
426454
}
427455

@@ -440,14 +468,44 @@ void SwitchCapabilities::querySwitchLagHashAttrCapabilities()
440468
"Failed to get attribute(%s) capabilities",
441469
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH).c_str()
442470
);
471+
}
472+
else if (attrCap.get_implemented)
473+
{
474+
switchCapabilities.lagHash.isAttrSupported = true;
443475
return;
444476
}
445477

446-
if (!attrCap.get_implemented)
478+
sai_attr_capability_t lagV4Cap;
479+
auto lagV4Status = queryAttrCapabilitiesSai(
480+
lagV4Cap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH_IPV4
481+
);
482+
if (lagV4Status != SAI_STATUS_SUCCESS)
447483
{
448-
SWSS_LOG_WARN(
449-
"Attribute(%s) GET is not implemented in SAI",
450-
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH).c_str()
484+
SWSS_LOG_ERROR(
485+
"Failed to get attribute(%s) capabilities",
486+
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH_IPV4).c_str()
487+
);
488+
return;
489+
}
490+
491+
sai_attr_capability_t lagV6Cap;
492+
auto lagV6Status = queryAttrCapabilitiesSai(
493+
lagV6Cap, SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH_IPV6
494+
);
495+
if (lagV6Status != SAI_STATUS_SUCCESS)
496+
{
497+
SWSS_LOG_ERROR(
498+
"Failed to get attribute(%s) capabilities",
499+
toStr(SAI_OBJECT_TYPE_SWITCH, SAI_SWITCH_ATTR_LAG_HASH_IPV6).c_str()
500+
);
501+
return;
502+
}
503+
504+
if (!lagV4Cap.get_implemented || !lagV6Cap.get_implemented)
505+
{
506+
SWSS_LOG_ERROR(
507+
"One or more of required LAG capabilities not supported %d, %d",
508+
lagV4Cap.get_implemented, lagV6Cap.get_implemented
451509
);
452510
return;
453511
}

orchagent/switchorch.cpp

Lines changed: 142 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
19322037
void 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

orchagent/switchorch.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,14 @@ class SwitchOrch : public Orch
9494
void generateSwitchCounterNameMap() const;
9595

9696
// Switch hash
97-
bool setSwitchHashFieldListSai(const SwitchHash &hash, bool isEcmpHash) const;
97+
sai_status_t setSwitchHashFieldListSai(const sai_object_id_t oid, const std::set<sai_native_hash_field_t> &hfSet) const;
98+
sai_status_t createHashObjectSai(sai_object_id_t &oid, const std::set<sai_native_hash_field_t> &hfSet) const;
99+
sai_status_t setSwitchHashAttributeSai(sai_attr_id_t attrType, sai_object_id_t oid) const;
100+
bool setSwitchHashFieldList(const SwitchHash &hash, bool isEcmpHash);
98101
bool setSwitchHashAlgorithmSai(const SwitchHash &hash, bool isEcmpHash) const;
99102
bool setSwitchHash(const SwitchHash &hash);
100103

101-
bool getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHash) const;
104+
bool getSwitchHashOidSai(sai_object_id_t &oid, sai_attr_id_t attr_id) const;
102105
void querySwitchHashDefaults();
103106
void setSwitchIcmpOffloadCapability();
104107

@@ -163,10 +166,17 @@ class SwitchOrch : public Orch
163166
struct {
164167
struct {
165168
sai_object_id_t oid = SAI_NULL_OBJECT_ID;
169+
sai_object_id_t v4Oid = SAI_NULL_OBJECT_ID;
170+
sai_object_id_t v6Oid = SAI_NULL_OBJECT_ID;
171+
bool platformSupportsOnlyV4V6 = false; // platform supports only V4/V6 attr type
166172
} ecmpHash;
167173
struct {
168174
sai_object_id_t oid = SAI_NULL_OBJECT_ID;
175+
sai_object_id_t v4Oid = SAI_NULL_OBJECT_ID;
176+
sai_object_id_t v6Oid = SAI_NULL_OBJECT_ID;
177+
bool platformSupportsOnlyV4V6 = false; // platform supports only V4/V6 attr type
169178
} lagHash;
179+
170180
} m_switchHashDefaults;
171181

172182
// Statistics

0 commit comments

Comments
 (0)