void check_non_object_id_object_types()

in meta/saisanitycheck.c [3694:3855]


void check_non_object_id_object_types()
{
    META_LOG_ENTER();

    size_t idx = 1;

    for (; sai_metadata_all_object_type_infos[idx]; ++idx)
    {
        const sai_object_type_info_t* info = sai_metadata_all_object_type_infos[idx];

        if (!info->isnonobjectid)
        {
            if (info->structmemberscount != 0 ||
                    info->structmembers != NULL)
            {
                META_ASSERT_FAIL("object type %u is non object id but struct members defined", info->objecttype);
            }

            continue;
        }

        META_ASSERT_TRUE(info->structmemberscount != 0, "non object id should have members defined");
        META_ASSERT_NOT_NULL(info->structmembers);

        /* check each member of the struct */

        size_t j = 0;

        int member_supports_switch_id = 0;

        int lastoffset = -1;

        for (; j < info->structmemberscount; ++j)
        {
            META_ASSERT_NOT_NULL(info->structmembers[j]);

            const sai_struct_member_info_t *m = info->structmembers[j];

            META_ASSERT_NOT_NULL(m->membername);

            META_ASSERT_TRUE(m->size > 0, "struct member size must be greater than zero");
            META_ASSERT_TRUE((int)m->offset > lastoffset, "struct member offset must increase from member to member");

            lastoffset = (int)m->offset;

            switch (m->membervaluetype)
            {
                case SAI_ATTR_VALUE_TYPE_MAC:
                case SAI_ATTR_VALUE_TYPE_INT32:
                case SAI_ATTR_VALUE_TYPE_UINT32:
                case SAI_ATTR_VALUE_TYPE_UINT16:
                case SAI_ATTR_VALUE_TYPE_UINT8:
                case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
                case SAI_ATTR_VALUE_TYPE_IP_ADDRESS:
                case SAI_ATTR_VALUE_TYPE_IP_PREFIX:
                case SAI_ATTR_VALUE_TYPE_OBJECT_ID:
                case SAI_ATTR_VALUE_TYPE_NAT_ENTRY_DATA:
                case SAI_ATTR_VALUE_TYPE_ENCRYPT_KEY:
                case SAI_ATTR_VALUE_TYPE_AUTH_KEY:
                case SAI_ATTR_VALUE_TYPE_MACSEC_SAK:
                case SAI_ATTR_VALUE_TYPE_MACSEC_AUTH_KEY:
                case SAI_ATTR_VALUE_TYPE_MACSEC_SALT:
                case SAI_ATTR_VALUE_TYPE_IPV6:
                    break;

                default:

                    /*
                     * On struct members only primitive types should be
                     * supported so no other structs or lists.
                     */

                    META_ASSERT_FAIL("struct member %s have invalid value type %d", m->membername, m->membervaluetype);
            }

            if (m->isenum)
            {
                META_ASSERT_NOT_NULL(m->enummetadata);

                META_ASSERT_TRUE(m->membervaluetype == SAI_ATTR_VALUE_TYPE_INT32,
                        "when enum is defined in struct member non objectid its type must be INT32");
            }
            else
            {
                META_ASSERT_NULL(m->enummetadata);
            }

            if (m->isvlan)
            {
                META_ASSERT_TRUE(m->membervaluetype == SAI_ATTR_VALUE_TYPE_UINT16, "member marked as vlan, but wrong type specified");
            }

            if (m->membervaluetype == SAI_ATTR_VALUE_TYPE_OBJECT_ID)
            {
                META_ASSERT_NOT_NULL(m->getoid);
                META_ASSERT_NOT_NULL(m->setoid);
                META_ASSERT_NOT_NULL(m->allowedobjecttypes);
                META_ASSERT_TRUE(m->allowedobjecttypeslength > 0, "struct member object id, should specify some object types");

                size_t k = 0;

                for (; k < m->allowedobjecttypeslength; k++)
                {
                    sai_object_type_t ot = m->allowedobjecttypes[k];

                    if (ot == SAI_OBJECT_TYPE_FDB_FLUSH || ot == SAI_OBJECT_TYPE_HOSTIF_PACKET)
                    {
                        META_ASSERT_FAIL("fdb flush or hostif packet can't be used as object in nonobjectid struct");
                    }

                    if (is_valid_object_type(ot))
                    {
                        if (ot == SAI_OBJECT_TYPE_SWITCH)
                        {
                            /*
                             * to make struct object type complete, at least
                             * one struct member should be type of switch
                             */

                            member_supports_switch_id++;

                            if (strcmp("switch_id", m->membername) != 0)
                            {
                                META_ASSERT_FAIL("struct member %s supports object type SWITCH, should be named switch_id", m->membername);
                            }

                            META_ASSERT_TRUE(m->allowedobjecttypeslength == 1, "switch_id member should only support object type SWITCH");
                        }

                        /* non object id struct can't contain object id which is also non object id */

                        const sai_object_type_info_t* sinfo = sai_metadata_get_object_type_info(ot);

                        META_ASSERT_NOT_NULL(sinfo);

                        if (sinfo->isnonobjectid)
                        {
                            META_ASSERT_FAIL("struct member %s of non object id type can't be used as object id in non object id struct: %s",
                                    m->membername,
                                    sai_metadata_get_object_type_name(ot));
                        }

                        continue;
                    }

                    META_ASSERT_FAIL("invalid object type specified on file %s: %d", m->membername, ot);
                }
            }
            else
            {
                META_ASSERT_NULL(m->getoid);
                META_ASSERT_NULL(m->setoid);
                META_ASSERT_NULL(m->allowedobjecttypes);
                META_ASSERT_TRUE(m->allowedobjecttypeslength == 0, "member is not object id, should not specify object types");
            }
        }

        META_ASSERT_TRUE(member_supports_switch_id == 1, "there should be only one struct member that support switch id object type");

        META_ASSERT_NULL(info->structmembers[j]);
    }
}