Skip to content

Commit

Permalink
[syncd] Enable bulk api for neighbor entries (#1373)
Browse files Browse the repository at this point in the history
* [syncd] Enable bulk api for neighbor entries
SAI 1.11.0 added support for bulk neighbor entries. Adding support for
neighbor bulk operations to syncd.
* added neighbor entry capability to bulk operations in syncd
* added unit tests for neighbor bulk operations
* added code coverage for neighbor bulk operations
  • Loading branch information
Ndancejic authored May 30, 2024
1 parent 270fed7 commit c8cede0
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 0 deletions.
52 changes: 52 additions & 0 deletions saiplayer/SaiPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,23 @@ sai_status_t SaiPlayer::handle_bulk_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:
{

Expand Down Expand Up @@ -1876,6 +1893,23 @@ sai_status_t SaiPlayer::handle_bulk_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:
{

Expand Down Expand Up @@ -2061,6 +2095,23 @@ sai_status_t SaiPlayer::handle_bulk_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:
{

Expand Down Expand Up @@ -2452,6 +2503,7 @@ void SaiPlayer::processBulk(
switch ((int)object_type)
{
case SAI_OBJECT_TYPE_ROUTE_ENTRY:
case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
case SAI_OBJECT_TYPE_FDB_ENTRY:
case SAI_OBJECT_TYPE_NAT_ENTRY:
case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
Expand Down
64 changes: 64 additions & 0 deletions syncd/Syncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,27 @@ sai_status_t Syncd::processBulkCreateEntry(
}
break;

case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
{
std::vector<sai_neighbor_entry_t> entries(object_count);
for (uint32_t it = 0; it < object_count; it++)
{
sai_deserialize_neighbor_entry(objectIds[it], entries[it]);

entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id);
entries[it].rif_id = m_translator->translateVidToRid(entries[it].rif_id);
}

status = m_vendorSai->bulkCreate(
object_count,
entries.data(),
attr_counts.data(),
attr_lists.data(),
mode,
statuses.data());
}
break;

case SAI_OBJECT_TYPE_FDB_ENTRY:
{
std::vector<sai_fdb_entry_t> entries(object_count);
Expand Down Expand Up @@ -1301,6 +1322,25 @@ sai_status_t Syncd::processBulkRemoveEntry(
}
break;

case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
{
std::vector<sai_neighbor_entry_t> entries(object_count);
for (uint32_t it = 0; it < object_count; it++)
{
sai_deserialize_neighbor_entry(objectIds[it], entries[it]);

entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id);
entries[it].rif_id = m_translator->translateVidToRid(entries[it].rif_id);
}

status = m_vendorSai->bulkRemove(
object_count,
entries.data(),
mode,
statuses.data());
}
break;

case SAI_OBJECT_TYPE_FDB_ENTRY:
{
std::vector<sai_fdb_entry_t> entries(object_count);
Expand Down Expand Up @@ -1574,6 +1614,26 @@ sai_status_t Syncd::processBulkSetEntry(
}
break;

case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
{
std::vector<sai_neighbor_entry_t> entries(object_count);
for (uint32_t it = 0; it < object_count; it++)
{
sai_deserialize_neighbor_entry(objectIds[it], entries[it]);

entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id);
entries[it].rif_id = m_translator->translateVidToRid(entries[it].rif_id);
}

status = m_vendorSai->bulkSet(
object_count,
entries.data(),
attr_lists.data(),
mode,
statuses.data());
}
break;

case SAI_OBJECT_TYPE_FDB_ENTRY:
{
std::vector<sai_fdb_entry_t> entries(object_count);
Expand Down Expand Up @@ -1730,6 +1790,10 @@ sai_status_t Syncd::processBulkEntry(
sai_deserialize_route_entry(objectIds[idx], metaKey.objectkey.key.route_entry);
break;

case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
sai_deserialize_neighbor_entry(objectIds[idx], metaKey.objectkey.key.neighbor_entry);
break;

case SAI_OBJECT_TYPE_NAT_ENTRY:
sai_deserialize_nat_entry(objectIds[idx], metaKey.objectkey.key.nat_entry);
break;
Expand Down
141 changes: 141 additions & 0 deletions syncd/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,145 @@ void test_bulk_route_set()
ASSERT_SUCCESS("Failed to bulk remove route entry");
}

void test_bulk_neighbor_set()
{
SWSS_LOG_ENTER();


sai_reinit();


sai_status_t status;

sai_neighbor_api_t *sai_neighbor_api = NULL;
sai_switch_api_t *sai_switch_api = NULL;
sai_virtual_router_api_t * sai_virtual_router_api = NULL;
sai_lag_api_t *sai_lag_api = NULL;
sai_router_interface_api_t *sai_rif_api = NULL;

sai_api_query(SAI_API_NEIGHBOR, (void**)&sai_neighbor_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_ROUTER_INTERFACE, (void **)&sai_rif_api);
sai_api_query(SAI_API_LAG, (void**)&sai_lag_api);

uint32_t count = 3;

std::vector<sai_neighbor_entry_t> neighbors;
std::vector<sai_attribute_t> attrs;

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>> neighbor_attrs;
std::vector<const sai_attribute_t *> neighbor_attrs_array;
std::vector<uint32_t> neighbor_attrs_count;

for (uint32_t i = 0; i < count; ++i)
{
sai_neighbor_entry_t neighbor_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");

neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
neighbor_entry.ip_address.addr.ip4 = 0x10000001 + i;
neighbor_entry.rif_id = rif;
neighbor_entry.switch_id = switch_id;
neighbors.push_back(neighbor_entry);

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

sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
attr.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS;
memcpy(attr.value.mac, mac, 6);
neighbor_attrs.push_back(list);
neighbor_attrs_count.push_back(1);
}

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

std::vector<sai_status_t> statuses(count);
status = sai_neighbor_api->create_neighbor_entries(count, neighbors.data(), neighbor_attrs_count.data(), neighbor_attrs_array.data(), SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, statuses.data());
ASSERT_SUCCESS("Failed to create neighbor");
for (size_t j = 0; j < statuses.size(); j++)
{
status = statuses[j];
ASSERT_SUCCESS("Failed to create neighbor # %zu", j);
}

for (uint32_t i = 0; i < count; ++i)
{
sai_attribute_t attr;
attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION;
attr.value.s32 = SAI_PACKET_ACTION_FORWARD;

status = sai_neighbor_api->set_neighbor_entry_attribute(&neighbors[i], &attr);

attrs.push_back(attr);

ASSERT_SUCCESS("Failed to set neighbor");
}

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

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

status = sai_neighbor_api->set_neighbor_entries_attribute(
count,
neighbors.data(),
attrs.data(),
SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,
statuses.data());

ASSERT_SUCCESS("Failed to bulk set neighbor");

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

ASSERT_SUCCESS("Failed to bulk set neighbor on one of the neighbors");
}

status = sai_neighbor_api->remove_neighbor_entries(count, neighbors.data(), SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, statuses.data());
ASSERT_SUCCESS("Failed to bulk remove neighbor entry");
}

void syncdThread()
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -765,6 +904,8 @@ int main()

test_bulk_fdb_create();

test_bulk_neighbor_set();

test_bulk_route_set();

sai_api_uninitialize();
Expand Down
Loading

0 comments on commit c8cede0

Please sign in to comment.