void test_bulk_route_set()

in syncd/tests.cpp [614:781]


void test_bulk_route_set()
{
    SWSS_LOG_ENTER();


    sai_reinit();


    sai_status_t    status;

    sai_route_api_t  *sai_route_api = NULL;
    sai_switch_api_t *sai_switch_api = NULL;
    sai_virtual_router_api_t * sai_virtual_router_api = NULL;
    sai_next_hop_api_t  *sai_next_hop_api = NULL;
    sai_lag_api_t *sai_lag_api = NULL;
    sai_router_interface_api_t *sai_rif_api = NULL;

    sai_api_query(SAI_API_ROUTE, (void**)&sai_route_api);
    sai_api_query(SAI_API_SWITCH, (void**)&sai_switch_api);
    sai_api_query(SAI_API_VIRTUAL_ROUTER, (void**)&sai_virtual_router_api);
    sai_api_query(SAI_API_NEXT_HOP, (void**)&sai_next_hop_api);
    sai_api_query(SAI_API_ROUTER_INTERFACE, (void **)&sai_rif_api);
    sai_api_query(SAI_API_LAG, (void**)&sai_lag_api);

    uint32_t count = 3;

    std::vector<sai_route_entry_t> routes;
    std::vector<sai_attribute_t> attrs;

    uint32_t index = 15;

    sai_attribute_t swattr;

    swattr.id = SAI_SWITCH_ATTR_INIT_SWITCH;
    swattr.value.booldata = true;

    sai_object_id_t switch_id;
    status = sai_switch_api->create_switch(&switch_id, 1, &swattr);

    ASSERT_SUCCESS("Failed to create switch");

    std::vector<std::vector<sai_attribute_t>> route_attrs;
    std::vector<const sai_attribute_t *> route_attrs_array;
    std::vector<uint32_t> route_attrs_count;

    for (uint32_t i = index; i < index + count; ++i)
    {
        sai_route_entry_t route_entry;

        // virtual router
        sai_object_id_t vr;

        status = sai_virtual_router_api->create_virtual_router(&vr, switch_id, 0, NULL);

        ASSERT_SUCCESS("failed to create virtual router");

        // create lag
        sai_object_id_t lag;
        status = sai_lag_api->create_lag(&lag, switch_id, 0, NULL);

        // create router interface
        sai_object_id_t rif;
        sai_attribute_t rifattr[3];
        rifattr[0].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID;
        rifattr[0].value.oid = vr;
        rifattr[1].id = SAI_ROUTER_INTERFACE_ATTR_TYPE;
        rifattr[1].value.s32 = SAI_ROUTER_INTERFACE_TYPE_PORT;
        rifattr[2].id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID;
        rifattr[2].value.oid = lag;
        status = sai_rif_api->create_router_interface(&rif, switch_id, 3, rifattr);
        ASSERT_SUCCESS("Failed to create router interface");

        // next hop
        sai_object_id_t hop;

        sai_attribute_t nhattr[3] = { };

        nhattr[0].id = SAI_NEXT_HOP_ATTR_TYPE;
        nhattr[0].value.s32 = SAI_NEXT_HOP_TYPE_IP;
        nhattr[1].id = SAI_NEXT_HOP_ATTR_IP;
        nhattr[1].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
        nhattr[1].value.ipaddr.addr.ip4 = 0x10000001;
        nhattr[2].id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID;
        nhattr[2].value.oid = rif;

        status = sai_next_hop_api->create_next_hop(&hop, switch_id, 3, nhattr);

        ASSERT_SUCCESS("failed to create next hop");

        route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
        route_entry.destination.addr.ip4 = htonl(0x0a000000 | i);
        route_entry.destination.mask.ip4 = htonl(0xffffffff);
        route_entry.vr_id = vr;
        route_entry.switch_id = switch_id;
        route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
        routes.push_back(route_entry);

        std::vector<sai_attribute_t> list(2);
        sai_attribute_t &attr1 = list[0];
        sai_attribute_t &attr2 = list[1];

        attr1.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID;
        attr1.value.oid = hop;
        attr2.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION;
        attr2.value.s32 = SAI_PACKET_ACTION_FORWARD;
        route_attrs.push_back(list);
        route_attrs_count.push_back(2);
    }

    for (size_t j = 0; j < route_attrs.size(); j++)
    {
        route_attrs_array.push_back(route_attrs[j].data());
    }

    std::vector<sai_status_t> statuses(count);
    status = sai_route_api->create_route_entries(count, routes.data(), route_attrs_count.data(), route_attrs_array.data(), SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, statuses.data());
    ASSERT_SUCCESS("Failed to create route");
    for (size_t j = 0; j < statuses.size(); j++)
    {
        status = statuses[j];
        ASSERT_SUCCESS("Failed to create route # %zu", j);
    }

    for (uint32_t i = index; i < index + count; ++i)
    {
        sai_attribute_t attr;
        attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION;
        attr.value.s32 = SAI_PACKET_ACTION_DROP;

        status = sai_route_api->set_route_entry_attribute(&routes[i - index], &attr);

        attrs.push_back(attr);

        ASSERT_SUCCESS("Failed to set route");
    }

    statuses.clear();
    statuses.resize(attrs.size());

    for (auto &attr: attrs)
    {
        attr.value.s32 = SAI_PACKET_ACTION_FORWARD;
    }

    status = sai_route_api->set_route_entries_attribute(
        count,
        routes.data(),
        attrs.data(),
        SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,
        statuses.data());

    ASSERT_SUCCESS("Failed to bulk set route");

    for (auto s: statuses)
    {
        status = s;

        ASSERT_SUCCESS("Failed to bulk set route on one of the routes");
    }

    // TODO we need to add consumer producer test here to see
    // if after consume we get pop we get expected parameters

    // TODO in async mode this api will always return success
    // Remove route entry
    status = sai_route_api->remove_route_entries(count, routes.data(), SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, statuses.data());
    ASSERT_SUCCESS("Failed to bulk remove route entry");
}