std::shared_ptr BestCandidateFinder::getSaiAttrFromDefaultValue()

in syncd/BestCandidateFinder.cpp [2898:3089]


std::shared_ptr<SaiAttr> BestCandidateFinder::getSaiAttrFromDefaultValue(
        _In_ const AsicView &currentView,
        _In_ std::shared_ptr<const SaiSwitchInterface> sw,
        _In_ const sai_attr_metadata_t &meta)
{
    SWSS_LOG_ENTER();

    /*
     * Worth notice, that this is only helper, since metadata on attributes
     * tell default value for example for oid object as SAI_NULL_OBJECT_ID but
     * maybe on the switch vendor actually assigned some value, so default
     * value will not be NULL after creation.
     *
     * We can check that by using SAI discovery.
     *
     * TODO Default value also must depend on dependency tree !
     * This will be tricky, we need to revisit that !
     */

    if (meta.objecttype == SAI_OBJECT_TYPE_SWITCH &&
            meta.attrid == SAI_SWITCH_ATTR_SRC_MAC_ADDRESS)
    {
        /*
         * Same will apply for default values which are pointing to
         * different attributes.
         *
         * Default value is stored in SaiSwitch class.
         */

        // XXX we have only 1 switch, so we can get away with this

        sai_attribute_t attr;

        memset(&attr, 0, sizeof(sai_attribute_t));

        attr.id = meta.attrid;

        sw->getDefaultMacAddress(attr.value.mac);

        std::string str_attr_value = sai_serialize_attr_value(meta, attr, false);

        SWSS_LOG_NOTICE("bringing default %s", meta.attridname);

        return std::make_shared<SaiAttr>(meta.attridname, str_attr_value);
    }

    /*
     * Move this method to asicview class.
     */

    switch (meta.defaultvaluetype)
    {
        case SAI_DEFAULT_VALUE_TYPE_EMPTY_LIST:

            {
                /*
                 * For empty list we can use trick here, just set attr to all
                 * zeros, then all count's will be zeros and all lists pointers
                 * will be NULL.
                 *
                 * TODO: If this is executed on existing attribute then we need
                 * Dependency tree since initially that list may not be empty!
                 */

                sai_attribute_t attr;

                memset(&attr, 0, sizeof(sai_attribute_t));

                attr.id = meta.attrid;

                std::string str_attr_value = sai_serialize_attr_value(meta, attr, false);

                return std::make_shared<SaiAttr>(meta.attridname, str_attr_value);
            }


        case SAI_DEFAULT_VALUE_TYPE_CONST:

            /*
             * Only primitives can be supported on CONST.
             */

            switch (meta.attrvaluetype)
            {
                case SAI_ATTR_VALUE_TYPE_BOOL:
                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_POINTER:
                case SAI_ATTR_VALUE_TYPE_OBJECT_ID:

                    {
                        sai_attribute_t attr;

                        attr.id = meta.attrid;
                        attr.value = *meta.defaultvalue;

                        std::string str_attr_value = sai_serialize_attr_value(meta, attr, false);

                        return std::make_shared<SaiAttr>(meta.attridname, str_attr_value);
                    }

                case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8:
                case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16:

                    // ACL field data don't have default values (disabled)

                    return nullptr;

                default:

                    SWSS_LOG_ERROR("serialization type %s is not supported yet, FIXME",
                            sai_serialize_attr_value_type(meta.attrvaluetype).c_str());
                    break;
            }

            /*
             * NOTE: default for acl flags or action is disabled.
             */

            break;

        case SAI_DEFAULT_VALUE_TYPE_ATTR_VALUE:

            /*
             * TODO normally we need check default object type and value but
             * this is only available in metadata sai 1.0.
             *
             * We need to look at attrvalue in metadata and object type if it's switch.
             * then get it from switch
             *
             * And all those values we should keep in double map object type
             * and attribute id, and auto select from attr value.
             */

            // TODO double check that, to make it generic (check attr value type is oid)
            if (meta.objecttype == SAI_OBJECT_TYPE_HOSTIF_TRAP && meta.attrid == SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP)
            {
                /*
                 * Default trap group is set on traps by default, so to bring them to
                 * default state we need to explicitly set this.
                 */

                SWSS_LOG_NOTICE("bring default trap group on %s", meta.attridname);

                const auto &tg = currentView.m_ridToVid.find(currentView.m_defaultTrapGroupRid);

                if (tg == currentView.m_ridToVid.end())
                {
                    SWSS_LOG_THROW("default trap group RID 0x%" PRIx64 " doesn't exist in current view", currentView.m_defaultTrapGroupRid);
                }

                sai_attribute_t at;

                at.id = meta.attrid;
                at.value.oid = tg->second; // default trap group VID

                std::string str_attr_value = sai_serialize_attr_value(meta, at, false);

                return std::make_shared<SaiAttr>(meta.attridname, str_attr_value);
            }

            SWSS_LOG_ERROR("default value type %d is not supported yet for %s, FIXME",
                    meta.defaultvaluetype,
                    meta.attridname);

            return nullptr;

        case SAI_DEFAULT_VALUE_TYPE_NONE:

            /*
             * No default value present.
             */

            return nullptr;

        default:

            SWSS_LOG_ERROR("default value type %d is not supported yet for %s, FIXME",
                    meta.defaultvaluetype,
                    meta.attridname);

            return nullptr;
    }

    return nullptr;
}