void Meta::meta_generic_validation_post_create()

in meta/Meta.cpp [5608:5928]


void Meta::meta_generic_validation_post_create(
        _In_ const sai_object_meta_key_t& meta_key,
        _In_ sai_object_id_t switch_id,
        _In_ const uint32_t attr_count,
        _In_ const sai_attribute_t *attr_list)
{
    SWSS_LOG_ENTER();

    bool connectToSwitch = false;

    if (meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH)
    {
        auto attr = sai_metadata_get_attr_by_id(SAI_SWITCH_ATTR_INIT_SWITCH, attr_count, attr_list);

        if (attr && attr->value.booldata == false)
        {
            SWSS_LOG_NOTICE("connecting to existing switch %s",
                    sai_serialize_object_id(switch_id).c_str());

            connectToSwitch = true;
        }
    }

    if (m_saiObjectCollection.objectExists(meta_key))
    {
        if (m_warmBoot && meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH)
        {
            SWSS_LOG_NOTICE("post switch create after WARM BOOT");
        }
        else if (connectToSwitch)
        {
            // ok, object already exists since we are connecting to existing switch
        }
        else
        {
            SWSS_LOG_ERROR("object key %s already exists (vendor bug?)",
                    sai_serialize_object_meta_key(meta_key).c_str());

            // this may produce inconsistency
        }
    }

    if (m_warmBoot && meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH)
    {
        SWSS_LOG_NOTICE("skipping create switch on WARM BOOT since it was already created");
    }
    else if (connectToSwitch)
    {
        // don't create object, since it already exists and we are connecting to existing switch
    }
    else
    {
        m_saiObjectCollection.createObject(meta_key);
    }

    auto info = sai_metadata_get_object_type_info(meta_key.objecttype);

    if (info->isnonobjectid)
    {
        /*
         * Increase object reference count for all object ids in non object id
         * members.
         */

        for (size_t j = 0; j < info->structmemberscount; ++j)
        {
            const sai_struct_member_info_t *m = info->structmembers[j];

            if (m->membervaluetype != SAI_ATTR_VALUE_TYPE_OBJECT_ID)
            {
                continue;
            }

            m_oids.objectReferenceIncrement(m->getoid(&meta_key));
        }
    }
    else
    {
        /*
         * Check if object created was expected type as the type of CRATE
         * function.
         */

        do
        {
            sai_object_id_t oid = meta_key.objectkey.key.object_id;

            if (oid == SAI_NULL_OBJECT_ID)
            {
                SWSS_LOG_ERROR("created oid is null object id (vendor bug?)");
                break;
            }

            sai_object_type_t object_type = objectTypeQuery(oid);

            if (object_type == SAI_NULL_OBJECT_ID)
            {
                SWSS_LOG_ERROR("created oid 0x%" PRIx64 " is not valid object type after create (null) (vendor bug?)", oid);
                break;
            }

            if (object_type != meta_key.objecttype)
            {
                SWSS_LOG_ERROR("created oid 0x%" PRIx64 " type %s, expected %s (vendor bug?)",
                        oid,
                        sai_serialize_object_type(object_type).c_str(),
                        sai_serialize_object_type(meta_key.objecttype).c_str());
                break;
            }

            if (meta_key.objecttype != SAI_OBJECT_TYPE_SWITCH)
            {
                /*
                 * Check if created object switch is the same as input switch.
                 */

                sai_object_id_t query_switch_id = switchIdQuery(meta_key.objectkey.key.object_id);

                if (!m_oids.objectReferenceExists(query_switch_id))
                {
                    SWSS_LOG_ERROR("switch id 0x%" PRIx64 " doesn't exist", query_switch_id);
                    break;
                }

                if (switch_id != query_switch_id)
                {
                    SWSS_LOG_ERROR("created oid 0x%" PRIx64 " switch id 0x%" PRIx64 " is different than requested 0x%" PRIx64 "",
                            oid, query_switch_id, switch_id);
                    break;
                }
            }

            if (m_warmBoot && meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH)
            {
                SWSS_LOG_NOTICE("skip insert switch reference insert in WARM_BOOT");
            }
            else if (connectToSwitch)
            {
                // don't create object reference, since we are connecting to existing switch
            }
            else
            {
                m_oids.objectReferenceInsert(oid);
            }

        } while (false);
    }

    if (m_warmBoot)
    {
        SWSS_LOG_NOTICE("m_warmBoot = false");

        m_warmBoot = false;
    }

    bool haskeys = false;

    for (uint32_t idx = 0; idx < attr_count; ++idx)
    {
        const sai_attribute_t* attr = &attr_list[idx];

        auto mdp = sai_metadata_get_attr_metadata(meta_key.objecttype, attr->id);

        const sai_attribute_value_t& value = attr->value;

        const sai_attr_metadata_t& md = *mdp;

        if (SAI_HAS_FLAG_KEY(md.flags))
        {
            haskeys = true;
            META_LOG_DEBUG(md, "attr is key");
        }

        // increase reference on object id types

        switch (md.attrvaluetype)
        {
            case SAI_ATTR_VALUE_TYPE_BOOL:
            case SAI_ATTR_VALUE_TYPE_CHARDATA:
            case SAI_ATTR_VALUE_TYPE_UINT8:
            case SAI_ATTR_VALUE_TYPE_INT8:
            case SAI_ATTR_VALUE_TYPE_UINT16:
            case SAI_ATTR_VALUE_TYPE_INT16:
            case SAI_ATTR_VALUE_TYPE_UINT32:
            case SAI_ATTR_VALUE_TYPE_INT32:
            case SAI_ATTR_VALUE_TYPE_UINT64:
            case SAI_ATTR_VALUE_TYPE_INT64:
            case SAI_ATTR_VALUE_TYPE_MAC:
            case SAI_ATTR_VALUE_TYPE_IPV4:
            case SAI_ATTR_VALUE_TYPE_IPV6:
            case SAI_ATTR_VALUE_TYPE_IP_ADDRESS:
            case SAI_ATTR_VALUE_TYPE_IP_PREFIX:
            case SAI_ATTR_VALUE_TYPE_POINTER:
                // primitives
                break;

            case SAI_ATTR_VALUE_TYPE_OBJECT_ID:
                m_oids.objectReferenceIncrement(value.oid);
                break;

            case SAI_ATTR_VALUE_TYPE_OBJECT_LIST:
                m_oids.objectReferenceIncrement(value.objlist);
                break;

            case SAI_ATTR_VALUE_TYPE_VLAN_LIST:
                break;

                // ACL FIELD

            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_BOOL:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT8:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT16:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_INT32:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT32:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT64:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_MAC:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV4:
            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_IPV6:
                // primitives
                break;

            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_ID:
                if (value.aclfield.enable)
                {
                    m_oids.objectReferenceIncrement(value.aclfield.data.oid);
                }
                break;

            case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_OBJECT_LIST:
                if (value.aclfield.enable)
                {
                    m_oids.objectReferenceIncrement(value.aclfield.data.objlist);
                }
                break;

                // case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8_LIST:

                // ACL ACTION

            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_BOOL:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT8:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT8:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT16:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT16:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_UINT32:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_INT32:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_MAC:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV4:
            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_IPV6:
                // primitives
                break;

            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID:
                if (value.aclaction.enable)
                {
                    m_oids.objectReferenceIncrement(value.aclaction.parameter.oid);
                }
                break;

            case SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_LIST:
                if (value.aclaction.enable)
                {
                    m_oids.objectReferenceIncrement(value.aclaction.parameter.objlist);
                }
                break;

                // ACL END

            case SAI_ATTR_VALUE_TYPE_UINT8_LIST:
            case SAI_ATTR_VALUE_TYPE_INT8_LIST:
            case SAI_ATTR_VALUE_TYPE_UINT16_LIST:
            case SAI_ATTR_VALUE_TYPE_INT16_LIST:
            case SAI_ATTR_VALUE_TYPE_UINT32_LIST:
            case SAI_ATTR_VALUE_TYPE_INT32_LIST:
            case SAI_ATTR_VALUE_TYPE_QOS_MAP_LIST:
            case SAI_ATTR_VALUE_TYPE_MAP_LIST:
            case SAI_ATTR_VALUE_TYPE_IP_ADDRESS_LIST:
            case SAI_ATTR_VALUE_TYPE_UINT32_RANGE:
            case SAI_ATTR_VALUE_TYPE_INT32_RANGE:
            case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST:
            case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST:
            case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST:
            case SAI_ATTR_VALUE_TYPE_JSON:
                // no special action required
                break;

            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_MACSEC_SCI:
            case SAI_ATTR_VALUE_TYPE_MACSEC_SSCI:
                break;

            case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG:
            case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST:
                // no special action required
                break;

            case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST:
                // no special action required
                break;

            default:

                META_LOG_THROW(md, "serialization type is not supported yet FIXME");
        }

        m_saiObjectCollection.setObjectAttr(meta_key, md, attr);
    }

    if (haskeys)
    {
        auto mKey = sai_serialize_object_meta_key(meta_key);

        auto attrKey = AttrKeyMap::constructKey(switch_id, meta_key, attr_count, attr_list);

        m_attrKeys.insert(mKey, attrKey);
    }
}