Skip to content

Commit a7bb225

Browse files
- Enhance the code to account for SAI_SWITCH_ATTR_ECMP/LAG_HASH_IPV4/V6
1 parent 5671e08 commit a7bb225

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
@@ -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
19902095
void 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

orchagent/switchorch.h

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

103103
// Switch hash
104-
bool setSwitchHashFieldListSai(const SwitchHash &hash, bool isEcmpHash) const;
104+
sai_status_t setSwitchHashFieldListSai(const sai_object_id_t oid, const std::set<sai_native_hash_field_t> &hfSet) const;
105+
sai_status_t createHashObjectSai(sai_object_id_t &oid, const std::set<sai_native_hash_field_t> &hfSet) const;
106+
sai_status_t setSwitchHashAttributeSai(sai_attr_id_t attrType, sai_object_id_t oid) const;
107+
bool setSwitchHashFieldList(const SwitchHash &hash, bool isEcmpHash);
105108
bool setSwitchHashAlgorithmSai(const SwitchHash &hash, bool isEcmpHash) const;
106109
bool setSwitchHash(const SwitchHash &hash);
107110

108-
bool getSwitchHashOidSai(sai_object_id_t &oid, bool isEcmpHash) const;
111+
bool getSwitchHashOidSai(sai_object_id_t &oid, sai_attr_id_t attr_id) const;
109112
void querySwitchHashDefaults();
110113
void setSwitchIcmpOffloadCapability();
111114

@@ -174,10 +177,17 @@ class SwitchOrch : public Orch
174177
struct {
175178
struct {
176179
sai_object_id_t oid = SAI_NULL_OBJECT_ID;
180+
sai_object_id_t v4Oid = SAI_NULL_OBJECT_ID;
181+
sai_object_id_t v6Oid = SAI_NULL_OBJECT_ID;
182+
bool platformSupportsOnlyV4V6 = false; // platform supports only V4/V6 attr type
177183
} ecmpHash;
178184
struct {
179185
sai_object_id_t oid = SAI_NULL_OBJECT_ID;
186+
sai_object_id_t v4Oid = SAI_NULL_OBJECT_ID;
187+
sai_object_id_t v6Oid = SAI_NULL_OBJECT_ID;
188+
bool platformSupportsOnlyV4V6 = false; // platform supports only V4/V6 attr type
180189
} lagHash;
190+
181191
} m_switchHashDefaults;
182192

183193
// Statistics

0 commit comments

Comments
 (0)