in meta/saisanitycheck.c [1365:1534]
void check_attr_conditions(
_In_ const sai_attr_metadata_t* md)
{
META_LOG_ENTER();
switch (md->conditiontype)
{
case SAI_ATTR_CONDITION_TYPE_NONE:
case SAI_ATTR_CONDITION_TYPE_OR:
case SAI_ATTR_CONDITION_TYPE_AND:
case SAI_ATTR_CONDITION_TYPE_MIXED:
break;
default:
META_MD_ASSERT_FAIL(md, "invalid condition type specified: %d", md->conditiontype);
}
bool conditional = md->conditiontype != SAI_ATTR_CONDITION_TYPE_NONE;
if (!conditional && md->conditions != NULL)
{
META_MD_ASSERT_FAIL(md, "not conditional but conditions specified");
}
if (!conditional)
{
META_ASSERT_FALSE(md->isconditional, "marked conditional but is not");
return;
}
META_ASSERT_TRUE(md->isconditional, "marked not conditional but is");
if (md->conditions == NULL)
{
META_MD_ASSERT_FAIL(md, "marked as conditional but no conditions specified");
}
switch ((int)md->flags)
{
case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_AND_SET:
case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY:
/*
* If attribute is marked as conditional then it must have flags
* mandatory on create, otherwise use validonly condition.
*/
break;
default:
META_MD_ASSERT_FAIL(md, "marked as conditional, but invalid creation flags: 0x%x", md->flags);
}
/* condition must be the same object type as attribute we check */
size_t index = 0;
for (; index < md->conditionslength; ++index)
{
const sai_attr_condition_t* c = md->conditions[index];
if (c->attrid == md->attrid)
{
META_MD_ASSERT_FAIL(md, "conditional attr id %d is the same as condition attribute", c->attrid);
}
if (md->conditiontype == SAI_ATTR_CONDITION_TYPE_MIXED && c->attrid == SAI_INVALID_ATTRIBUTE_ID)
{
switch (c->type)
{
case SAI_ATTR_CONDITION_TYPE_OR:
case SAI_ATTR_CONDITION_TYPE_AND:
break;
default:
META_MD_ASSERT_FAIL(md, "conditionwrong sub condition type: %d (expected AND/OR)", c->type);
}
continue;
}
const sai_attr_metadata_t* cmd = sai_metadata_get_attr_metadata(md->objecttype, c->attrid);
if (cmd == NULL)
{
META_MD_ASSERT_FAIL(md, "conditional attribute id %d was not defined yet in metadata", c->attrid);
}
switch (cmd->attrvaluetype)
{
case SAI_ATTR_VALUE_TYPE_BOOL:
META_LOG_DEBUG("attr id: %d cond.bool: %d", c->attrid, c->condition.booldata);
break;
case SAI_ATTR_VALUE_TYPE_INT32:
/*
* Currently force conditional int32 attributes to be enum.
* This can be relaxed later when needed.
*/
if (!cmd->isenum)
{
META_MD_ASSERT_FAIL(md, "conditional attribute %s is not enum type", cmd->attridname);
}
if (cmd->isenum)
{
/* condition value can be a number or enum */
META_LOG_DEBUG("attr id: %d cond.s32: %d ", c->attrid, c->condition.s32);
/* check if condition enum is in condition attribute range */
if (sai_metadata_get_enum_value_name(cmd->enummetadata, c->condition.s32) == NULL)
{
META_MD_ASSERT_FAIL(md, "condition enum %d not found on condition attribute enum range", c->condition.s32);
}
}
break;
case SAI_ATTR_VALUE_TYPE_INT8:
case SAI_ATTR_VALUE_TYPE_INT16:
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:
/* number conditions */
break;
default:
META_MD_ASSERT_FAIL(md, "attr value type %d of conditional attribute is not supported yet", cmd->attrvaluetype);
}
if (cmd->conditiontype != SAI_ATTR_CONDITION_TYPE_NONE)
{
META_MD_ASSERT_FAIL(md, "conditional attribute is also conditional, not allowed");
}
switch ((int)cmd->flags)
{
case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY | SAI_ATTR_FLAGS_KEY:
case SAI_ATTR_FLAGS_MANDATORY_ON_CREATE | SAI_ATTR_FLAGS_CREATE_ONLY:
case SAI_ATTR_FLAGS_CREATE_ONLY:
/*
* Condition attribute must be create only since if it could
* change then other object may be required to pass on creation
* time that was not passed.
*/
break;
default:
META_MD_ASSERT_FAIL(cmd, "attribute must be create only since used in condition for %s", md->attridname);
}
}
}