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");
}