in syncd/BestCandidateFinder.cpp [217:363]
std::shared_ptr<SaiObj> BestCandidateFinder::findCurrentBestMatchForAclCounter(
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects)
{
SWSS_LOG_ENTER();
/*
* For acl counter we use SAI_ACL_COUNTER_ATTR_TABLE_ID to match exact
* counter since if set, then table id will be matched previously.
*/
std::vector<std::shared_ptr<SaiObj>> objs;
const auto tmpAclTables = m_temporaryView.getObjectsByObjectType(SAI_OBJECT_TYPE_ACL_TABLE);
for (auto& tmpAclTable: tmpAclTables)
{
auto tmpAclCounterTableIdAttr = temporaryObj->tryGetSaiAttr(SAI_ACL_COUNTER_ATTR_TABLE_ID);
if (tmpAclCounterTableIdAttr == nullptr)
continue;
if (tmpAclCounterTableIdAttr->getOid() == SAI_NULL_OBJECT_ID)
continue;
if (tmpAclTable->getVid() != tmpAclCounterTableIdAttr->getOid())
continue; // not this table
if (tmpAclTable->getObjectStatus() != SAI_OBJECT_STATUS_FINAL)
continue; // not processed
sai_object_id_t aclTableRid = m_temporaryView.m_vidToRid.at(tmpAclTable->getVid());
sai_object_id_t curAclTableVid = m_currentView.m_ridToVid.at(aclTableRid);
for (auto c: candidateObjects)
{
auto curAclCounterTableIdAttr = c.obj->tryGetSaiAttr(SAI_ACL_COUNTER_ATTR_TABLE_ID);
if (curAclCounterTableIdAttr == nullptr)
continue;
if (curAclCounterTableIdAttr->getOid() != curAclTableVid)
continue;
objs.push_back(c.obj);
continue;
}
}
if (objs.size() > 1)
{
// in this case more than 1 acl counters has the same acl table associated,
// try to find best acl counter matching same acl entry field
SWSS_LOG_INFO("more than 1 (%zu) best match on acl counter using acl table", objs.size());
const auto tmpAclEntries = m_temporaryView.getObjectsByObjectType(SAI_OBJECT_TYPE_ACL_ENTRY);
for (auto& tmpAclEntry: tmpAclEntries)
{
auto tmpAclEntryActionCounterAttr = tmpAclEntry->tryGetSaiAttr(SAI_ACL_ENTRY_ATTR_ACTION_COUNTER);
if (tmpAclEntryActionCounterAttr == nullptr)
continue; // skip acl entries with no counter
if (tmpAclEntryActionCounterAttr->getOid() != temporaryObj->getVid())
continue; // not the counter we are looking for
// try use priority attribute first since it should be unique
// TODO we should use HASH from all non OID attribute here to have
// better chance for finding best candidate, this could be also
// used in pre match logic
std::vector<std::shared_ptr<const SaiAttr>> values;
if (tmpAclEntry->hasAttr(SAI_ACL_ENTRY_ATTR_PRIORITY))
{
values.push_back(tmpAclEntry->getSaiAttr(SAI_ACL_ENTRY_ATTR_PRIORITY));
}
for (auto&attr: tmpAclEntry->getAllAttributes())
{
values.push_back(attr.second);
}
for (auto&attr: values)
{
auto*meta = attr->getAttrMetadata();
if (!meta->isaclfield && meta->attrid != SAI_ACL_ENTRY_ATTR_PRIORITY)
continue; // looking only for acl fields
if (meta->isoidattribute)
continue; // only non oid fields
auto tmpValue = attr->getStrAttrValue();
const auto curAclEntries = m_currentView.getObjectsByObjectType(SAI_OBJECT_TYPE_ACL_ENTRY);
for (auto& curAclEntry: curAclEntries)
{
auto curAclEntryAclFieldAttr = curAclEntry->tryGetSaiAttr(meta->attrid);
if (curAclEntryAclFieldAttr == nullptr)
continue; // this field is missing from current view
if (curAclEntryAclFieldAttr->getStrAttrValue() != tmpValue)
continue; // values are different, keep looking
auto curAclEntryActionCounterAttr = curAclEntry->tryGetSaiAttr(SAI_ACL_ENTRY_ATTR_ACTION_COUNTER);
if (curAclEntryActionCounterAttr == nullptr)
continue; // no counter
auto curAclCounter = m_currentView.m_oOids.at(curAclEntryActionCounterAttr->getOid());
if (curAclCounter->getObjectStatus() != SAI_OBJECT_STATUS_NOT_PROCESSED)
continue;
for (auto c: candidateObjects)
{
if (c.obj->getVid() == curAclCounter->getVid())
{
SWSS_LOG_NOTICE("found best ACL counter match based on ACL entry field: %s, %s",
c.obj->m_str_object_id.c_str(),
meta->attridname);
return c.obj;
}
}
}
}
}
}
if (objs.size())
{
SWSS_LOG_NOTICE("found best ACL counter match based on ACL table: %s", objs.at(0)->m_str_object_id.c_str());
return objs.at(0);
}
SWSS_LOG_NOTICE("failed to find best candidate for ACL_COUNTER using ACL table");
return nullptr;
}