in syncd/SingleReiniter.cpp [644:862]
sai_object_id_t SingleReiniter::processSingleVid(
_In_ sai_object_id_t vid)
{
SWSS_LOG_ENTER();
if (vid == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_DEBUG("processed VID 0 to RID 0");
return SAI_NULL_OBJECT_ID;
}
auto it = m_translatedV2R.find(vid);
if (it != m_translatedV2R.end())
{
/*
* This object was already processed, just return real object id.
*/
SWSS_LOG_DEBUG("processed VID %s to RID %s",
sai_serialize_object_id(vid).c_str(),
sai_serialize_object_id(it->second).c_str());
return it->second;
}
sai_object_type_t objectType = VidManager::objectTypeQuery(vid);
std::string strVid = sai_serialize_object_id(vid);
auto oit = m_oids.find(strVid);
if (oit == m_oids.end())
{
SWSS_LOG_THROW("failed to find VID %s in OIDs map", strVid.c_str());
}
std::string asicKey = oit->second;;
std::shared_ptr<SaiAttributeList> list = m_attributesLists[asicKey];
sai_attribute_t *attrList = list->get_attr_list();
uint32_t attrCount = list->get_attr_count();
processAttributesForOids(objectType, attrCount, attrList);
bool createObject = true;
/*
* Now let's determine whether this object need to be created. Default
* objects like default virtual router, queues or cpu can't be created.
* When object exists on the switch (even VLAN member) it will not be
* created, but matched. We just need to watch for RO/CO attributes.
*
* NOTE: this also should be per switch.
*/
auto v2rMapIt = m_vidToRidMap.find(vid);
if (v2rMapIt == m_vidToRidMap.end())
{
SWSS_LOG_THROW("failed to find VID %s in VIDTORID map",
sai_serialize_object_id(vid).c_str());
}
sai_object_id_t rid;
if (m_sw->isDiscoveredRid(v2rMapIt->second))
{
rid = v2rMapIt->second;
createObject = false;
SWSS_LOG_DEBUG("object %s will not be created, processed VID %s to RID %s",
sai_serialize_object_type(objectType).c_str(),
sai_serialize_object_id(vid).c_str(),
sai_serialize_object_id(rid).c_str());
}
if (objectType == SAI_OBJECT_TYPE_HOSTIF_TRAP_GROUP)
{
/*
* We need special case for trap group, look inside for details.
*/
trapGroupWorkaround(vid, rid, createObject, attrCount, attrList);
}
if (createObject)
{
sai_object_meta_key_t meta_key;
meta_key.objecttype = objectType;
/*
* Since we have only one switch, we can get away using m_switch_rid here.
*/
#ifdef ENABLE_PERF
auto start = std::chrono::high_resolution_clock::now();
#endif
sai_status_t status = m_vendorSai->create(meta_key.objecttype, &meta_key.objectkey.key.object_id, m_switch_rid, attrCount, attrList);
#ifdef ENABLE_PERF
auto end = std::chrono::high_resolution_clock::now();
typedef std::chrono::duration<double, std::ratio<1>> second_t;
double duration = std::chrono::duration_cast<second_t>(end - start).count();
std::get<0>(m_perf_create[objectType])++;
std::get<1>(m_perf_create[objectType]) += duration;
#endif
if (status != SAI_STATUS_SUCCESS)
{
listFailedAttributes(objectType, attrCount, attrList);
SWSS_LOG_THROW("failed to create object %s: %s",
sai_serialize_object_type(objectType).c_str(),
sai_serialize_status(status).c_str());
}
rid = meta_key.objectkey.key.object_id;
SWSS_LOG_DEBUG("created object of type %s, processed VID %s to RID %s",
sai_serialize_object_type(objectType).c_str(),
sai_serialize_object_id(vid).c_str(),
sai_serialize_object_id(rid).c_str());
}
else
{
SWSS_LOG_DEBUG("setting attributes on object of type %x, processed VID 0x%" PRIx64 " to RID 0x%" PRIx64 " ", objectType, vid, rid);
for (uint32_t idx = 0; idx < attrCount; idx++)
{
sai_attribute_t *attr = &attrList[idx];
sai_object_meta_key_t meta_key;
meta_key.objecttype = objectType;
meta_key.objectkey.key.object_id = rid;
auto meta = sai_metadata_get_attr_metadata(objectType, attr->id);
if (meta == NULL)
{
SWSS_LOG_THROW("failed to get attribute metadata %s: %d",
sai_serialize_object_type(objectType).c_str(),
attr->id);
}
// XXX workaround
if (meta->objecttype == SAI_OBJECT_TYPE_SWITCH &&
attr->id == SAI_SWITCH_ATTR_SRC_MAC_ADDRESS)
{
SWSS_LOG_WARN("skipping to set MAC address since not supported on Mellanox platforms");
continue;
}
if (SAI_HAS_FLAG_CREATE_ONLY(meta->flags))
{
/*
* If we will be performing this on default existing created
* object then it may happen that during snoop in previous
* iteration we put some attribute that is create only, then
* this set will fail and we need to skip this set.
*
* NOTE: We could do get here to see if it actually matches.
*/
if (m_sw->isDiscoveredRid(rid))
{
continue;
}
SWSS_LOG_WARN("skipping create only attr %s: %s",
meta->attridname,
sai_serialize_attr_value(*meta, *attr).c_str());
continue;
}
#ifdef ENABLE_PERF
auto start = std::chrono::high_resolution_clock::now();
#endif
sai_status_t status = m_vendorSai->set(meta_key.objecttype, meta_key.objectkey.key.object_id, attr);
#ifdef ENABLE_PERF
auto end = std::chrono::high_resolution_clock::now();
typedef std::chrono::duration<double, std::ratio<1>> second_t;
double duration = std::chrono::duration_cast<second_t>(end - start).count();
std::get<0>(m_perf_set[objectType])++;
std::get<1>(m_perf_set[objectType]) += duration;
#endif
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_THROW(
"failed to set %s value %s: %s",
meta->attridname,
sai_serialize_attr_value(*meta, *attr).c_str(),
sai_serialize_status(status).c_str());
}
}
}
m_translatedV2R[vid] = rid;
m_translatedR2V[rid] = vid;
return rid;
}