sai_status_t SaiPlayer::handle_bulk_entry()

in saiplayer/SaiPlayer.cpp [1610:2231]


sai_status_t SaiPlayer::handle_bulk_entry(
        _In_ const std::vector<std::string> &object_ids,
        _In_ sai_object_type_t object_type,
        _In_ sai_common_api_t api,
        _In_ const std::vector<std::shared_ptr<SaiAttributeList>> &attributes,
        _Out_ std::vector<sai_status_t>& statuses)
{
    SWSS_LOG_ENTER();

    sai_bulk_op_error_mode_t mode = SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR; // TODO we need to get that from recording

    uint32_t object_count = (uint32_t) object_ids.size();

    sai_status_t status = SAI_STATUS_SUCCESS;

    if (api == SAI_COMMON_API_BULK_CREATE)
    {
        std::vector<uint32_t> attr_counts(object_count);
        std::vector<const sai_attribute_t*> attr_lists(object_count);

        for (uint32_t idx = 0; idx < object_count; idx++)
        {
            attr_counts[idx] = attributes[idx]->get_attr_count();
            attr_lists[idx] = attributes[idx]->get_attr_list();
        }

        switch ((int)object_type)
        {
            case SAI_OBJECT_TYPE_ROUTE_ENTRY:
            {
                std::vector<sai_route_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_route_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vr_id = translate_local_to_redis(entries[it].vr_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("route_entry");

            }
            break;

            case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
            {
                std::vector<sai_neighbor_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_neighbor_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].rif_id = translate_local_to_redis(entries[it].rif_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("neighbor_entry");

            }
            break;

            case SAI_OBJECT_TYPE_FDB_ENTRY:
            {

                std::vector<sai_fdb_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_fdb_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].bv_id = translate_local_to_redis(entries[it].bv_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("fdb_entry");

            }
            break;

            case SAI_OBJECT_TYPE_NAT_ENTRY:
            {

                std::vector<sai_nat_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_nat_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vr_id = translate_local_to_redis(entries[it].vr_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("nat_entry");

            }
            break;

            case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
            {
                std::vector<sai_direction_lookup_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_direction_lookup_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("direction_lookup_entry");

            }
            break;

            case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
            {
                std::vector<sai_eni_ether_address_map_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_eni_ether_address_map_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("eni_ether_address_map_entry");

            }
            break;

            case SAI_OBJECT_TYPE_VIP_ENTRY:
            {
                std::vector<sai_vip_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_vip_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("vip_entry");

            }
            break;

            case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
            {
                std::vector<sai_inbound_routing_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_inbound_routing_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].eni_id = translate_local_to_redis(entries[it].eni_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("inbound_routing_entry");

            }
            break;

            case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
            {
                std::vector<sai_pa_validation_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_pa_validation_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vnet_id = translate_local_to_redis(entries[it].vnet_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("pa_validation_entry");

            }
            break;

            case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
            {
                std::vector<sai_outbound_routing_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_outbound_routing_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].outbound_routing_group_id = translate_local_to_redis(entries[it].outbound_routing_group_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("outbound_routing_entry");

            }
            break;

            case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
            {
                std::vector<sai_outbound_ca_to_pa_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_outbound_ca_to_pa_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].dst_vnet_id = translate_local_to_redis(entries[it].dst_vnet_id);
                }

                CALL_BULK_CREATE_API_WITH_TIMER("outbound_ca_to_pa_entry");

            }
            break;

            default:
                SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str());
        }
    }
    else if (api == SAI_COMMON_API_BULK_REMOVE)
    {
        switch ((int)object_type)
        {
            case SAI_OBJECT_TYPE_ROUTE_ENTRY:
            {

                std::vector<sai_route_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_route_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vr_id = translate_local_to_redis(entries[it].vr_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("route_entry");

            }
            break;

            case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
            {
                std::vector<sai_neighbor_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_neighbor_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].rif_id = translate_local_to_redis(entries[it].rif_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("neighbor_entry");

            }
            break;

            case SAI_OBJECT_TYPE_FDB_ENTRY:
            {

                std::vector<sai_fdb_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_fdb_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].bv_id = translate_local_to_redis(entries[it].bv_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("fdb_entry");

            }
            break;

            case SAI_OBJECT_TYPE_NAT_ENTRY:
            {

                std::vector<sai_nat_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_nat_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vr_id = translate_local_to_redis(entries[it].vr_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("nat_entry");

            }
            break;

            case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
            {
                std::vector<sai_direction_lookup_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_direction_lookup_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("direction_lookup_entry");

            }
            break;

            case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
            {
                std::vector<sai_eni_ether_address_map_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_eni_ether_address_map_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("eni_ether_address_map_entry");

            }
            break;

            case SAI_OBJECT_TYPE_VIP_ENTRY:
            {
                std::vector<sai_vip_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_vip_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("vip_entry");

            }
            break;

            case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
            {
                std::vector<sai_inbound_routing_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_inbound_routing_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].eni_id = translate_local_to_redis(entries[it].eni_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("inbound_routing_entry");

            }
            break;

            case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
            {
                std::vector<sai_pa_validation_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_pa_validation_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vnet_id = translate_local_to_redis(entries[it].vnet_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("pa_validation_entry");

            }
            break;

            case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
            {
                std::vector<sai_outbound_routing_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_outbound_routing_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].outbound_routing_group_id = translate_local_to_redis(entries[it].outbound_routing_group_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("outbound_routing_entry");

            }
            break;

            case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
            {
                std::vector<sai_outbound_ca_to_pa_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_outbound_ca_to_pa_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].dst_vnet_id = translate_local_to_redis(entries[it].dst_vnet_id);
                }

                CALL_BULK_REMOVE_API_WITH_TIMER("outbound_ca_to_pa_entry");

            }
            break;

            default:
                SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str());

        }
    }
    else if (api == SAI_COMMON_API_BULK_SET)
    {
        std::vector<sai_attribute_t> attr_lists;

        for (size_t it = 0; it < object_count; it++)
        {
            attr_lists.push_back(attributes[it]->get_attr_list()[0]);
        }
        switch ((int)object_type)
        {
            case SAI_OBJECT_TYPE_ROUTE_ENTRY:
            {

                std::vector<sai_route_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_route_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vr_id = translate_local_to_redis(entries[it].vr_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("route_entry");

            }
            break;

            case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
            {
                std::vector<sai_neighbor_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_neighbor_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].rif_id = translate_local_to_redis(entries[it].rif_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("neighbor_entry");

            }
            break;

            case SAI_OBJECT_TYPE_FDB_ENTRY:
            {

                std::vector<sai_fdb_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_fdb_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].bv_id = translate_local_to_redis(entries[it].bv_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("fdb_entry");

            }
            break;

            case SAI_OBJECT_TYPE_NAT_ENTRY:
            {

                std::vector<sai_nat_entry_t> entries(object_count);

                for (size_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_nat_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vr_id = translate_local_to_redis(entries[it].vr_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("nat_entry");

            }
            break;

            case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
            {
                std::vector<sai_direction_lookup_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_direction_lookup_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("direction_lookup_entry");

            }
            break;

            case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
            {
                std::vector<sai_eni_ether_address_map_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_eni_ether_address_map_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("eni_ether_address_map_entry");

            }
            break;

            case SAI_OBJECT_TYPE_VIP_ENTRY:
            {
                std::vector<sai_vip_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_vip_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("vip_entry");

            }
            break;

            case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
            {
                std::vector<sai_inbound_routing_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_inbound_routing_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].eni_id = translate_local_to_redis(entries[it].eni_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("inbound_routing_entry");

            }
            break;

            case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
            {
                std::vector<sai_pa_validation_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_pa_validation_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].vnet_id = translate_local_to_redis(entries[it].vnet_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("pa_validation_entry");

            }
            break;

            case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
            {
                std::vector<sai_outbound_routing_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_outbound_routing_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].outbound_routing_group_id = translate_local_to_redis(entries[it].outbound_routing_group_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("outbound_routing_entry");

            }
            break;

            case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
            {
                std::vector<sai_outbound_ca_to_pa_entry_t> entries(object_count);

                for (uint32_t it = 0; it < object_count; it++)
                {
                    sai_deserialize_outbound_ca_to_pa_entry(object_ids[it], entries[it]);

                    entries[it].switch_id = translate_local_to_redis(entries[it].switch_id);
                    entries[it].dst_vnet_id = translate_local_to_redis(entries[it].dst_vnet_id);
                }

                CALL_BULK_SET_API_WITH_TIMER("outbound_ca_to_pa_entry");

            }
            break;

            default:
                SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str());
        }
    }
    else
    {
        SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str());
    }

    return status;
}