in saidiscovery/saidiscovery.cpp [74:327]
static int discover(
_In_ std::shared_ptr<sairedis::SaiInterface> sai,
_In_ sai_object_id_t id,
_Inout_ std::map<sai_object_id_t, std::map<std::string, std::string>> &discovered)
{
SWSS_LOG_ENTER();
int callCount = 0;
if (id == SAI_NULL_OBJECT_ID)
{
return callCount;
}
if (discovered.find(id) != discovered.end())
{
return callCount;
}
sai_object_type_t ot = sai->objectTypeQuery(id);
if (ot == SAI_OBJECT_TYPE_NULL)
{
SWSS_LOG_ERROR("oid %s returned NULL object type",
sai_serialize_object_id(id).c_str());
return callCount;
}
SWSS_LOG_INFO("processing %s: %s",
sai_serialize_object_type(ot).c_str(),
sai_serialize_object_id(id).c_str());
discovered[id] = {};
const sai_object_type_info_t *info = sai_metadata_all_object_type_infos[ot];
for (int idx = 0; info->attrmetadata[idx] != NULL; ++idx)
{
const sai_attr_metadata_t *md = info->attrmetadata[idx];
if (md->objecttype == SAI_OBJECT_TYPE_PORT &&
md->attrid == SAI_PORT_ATTR_HW_LANE_LIST)
{
// XXX workaround for brcm
continue;
}
/*
* Note that we don't care about ACL object id's since we assume that
* there are no ACLs on switch after init.
*/
sai_attribute_t attr;
attr.id = md->attrid;
if (md->attrvaluetype == SAI_ATTR_VALUE_TYPE_OBJECT_ID)
{
if (md->objecttype == SAI_OBJECT_TYPE_STP &&
md->attrid == SAI_STP_ATTR_BRIDGE_ID)
{
SWSS_LOG_WARN("skipping %s since it causes crash", md->attridname);
continue;
}
SWSS_LOG_DEBUG("getting %s for %s", md->attridname,
sai_serialize_object_id(id).c_str());
callCount++;
sai_status_t status = sai->get(ot, id, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
if (gOptions.logWarnings)
{
SWSS_LOG_WARN("%s: %s",
md->attridname,
sai_serialize_status(status).c_str());
}
continue;
}
if (md->defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_CONST
&& attr.value.oid != SAI_NULL_OBJECT_ID)
{
if (gOptions.logWarnings)
{
SWSS_LOG_WARN("const null, but got value %s on %s",
sai_serialize_object_id(attr.value.oid).c_str(),
md->attridname);
}
}
if (!md->allownullobjectid && attr.value.oid == SAI_NULL_OBJECT_ID)
{
if (gOptions.logWarnings)
{
SWSS_LOG_WARN("dont allow null, but got null on %s", md->attridname);
}
}
discovered[id][md->attridname] = sai_serialize_attr_value(*md, attr);
SWSS_LOG_DEBUG("result on %s: %s: %s",
sai_serialize_object_id(id).c_str(),
md->attridname,
discovered[id][md->attridname].c_str());
callCount += discover(sai, attr.value.oid, discovered); // recursion
}
else if (md->attrvaluetype == SAI_ATTR_VALUE_TYPE_OBJECT_LIST)
{
SWSS_LOG_DEBUG("getting %s for %s", md->attridname,
sai_serialize_object_id(id).c_str());
sai_object_id_t list[MAX_ELEMENTS];
attr.value.objlist.count = MAX_ELEMENTS;
attr.value.objlist.list = list;
callCount++;
sai_status_t status = sai->get(ot, id, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
if (gOptions.logWarnings)
{
SWSS_LOG_WARN("%s: %s",
md->attridname,
sai_serialize_status(status).c_str());
}
continue;
}
if (md->defaultvaluetype == SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST
&& attr.value.objlist.count != 0)
{
if (gOptions.logWarnings)
{
SWSS_LOG_WARN("default is empty list, but got count %u on %s",
attr.value.objlist.count,
md->attridname);
}
}
discovered[id][md->attridname] = sai_serialize_attr_value(*md, attr);
SWSS_LOG_INFO("list count %s: %u", md->attridname, attr.value.objlist.count);
SWSS_LOG_DEBUG("result on %s: %s: %s",
sai_serialize_object_id(id).c_str(),
md->attridname,
discovered[id][md->attridname].c_str());
for (uint32_t i = 0; i < attr.value.objlist.count; ++i)
{
callCount += discover(sai, attr.value.objlist.list[i], discovered); // recursion
}
}
else
{
if (!gOptions.fullDiscovery)
{
continue;
}
if ((md->objecttype == SAI_OBJECT_TYPE_PORT && md->attrid == SAI_PORT_ATTR_FEC_MODE) ||
(md->objecttype == SAI_OBJECT_TYPE_PORT && md->attrid == SAI_PORT_ATTR_GLOBAL_FLOW_CONTROL_MODE) ||
(md->objecttype == SAI_OBJECT_TYPE_SWITCH && md->attrid == SAI_SWITCH_ATTR_INIT_SWITCH))
{
// workaround since return invalid values
continue;
}
/*
* Discover non oid attributes as well.
*
* TODO lists!
*/
sai_object_id_t list[MAX_ELEMENTS];
switch (md->attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_INT8:
case SAI_ATTR_VALUE_TYPE_INT16:
case SAI_ATTR_VALUE_TYPE_INT32:
case SAI_ATTR_VALUE_TYPE_INT64:
case SAI_ATTR_VALUE_TYPE_UINT8:
case SAI_ATTR_VALUE_TYPE_UINT16:
case SAI_ATTR_VALUE_TYPE_UINT32:
case SAI_ATTR_VALUE_TYPE_UINT64:
case SAI_ATTR_VALUE_TYPE_POINTER:
case SAI_ATTR_VALUE_TYPE_BOOL:
case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
case SAI_ATTR_VALUE_TYPE_MAC:
break;
case SAI_ATTR_VALUE_TYPE_INT8_LIST:
case SAI_ATTR_VALUE_TYPE_INT32_LIST:
case SAI_ATTR_VALUE_TYPE_UINT32_LIST:
case SAI_ATTR_VALUE_TYPE_VLAN_LIST:
attr.value.objlist.count = MAX_ELEMENTS;
attr.value.objlist.list = list;
break;
case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY:
attr.value.aclcapability.action_list.count = MAX_ELEMENTS;
attr.value.aclcapability.action_list.list = (int32_t*)list;
break;
default:
SWSS_LOG_WARN("attr value: %s not supported",
sai_serialize_attr_value_type(md->attrvaluetype).c_str());
continue;
}
SWSS_LOG_DEBUG("getting %s for %s", md->attridname,
sai_serialize_object_id(id).c_str());
callCount++;
sai_status_t status = sai->get(ot, id, 1, &attr);
if (status == SAI_STATUS_SUCCESS)
{
discovered[id][md->attridname] = sai_serialize_attr_value(*md, attr);
SWSS_LOG_DEBUG("result on %s: %s: %s",
sai_serialize_object_id(id).c_str(),
md->attridname,
discovered[id][md->attridname].c_str());
}
else
{
if (gOptions.logWarnings)
{
SWSS_LOG_WARN("%s: %s", md->attridname, sai_serialize_status(status).c_str());
}
}
}
}
return callCount;
}