From 3b550a847d7c8d2d9acaea07c590dada07e49fd7 Mon Sep 17 00:00:00 2001 From: Nikola Dancejic Date: Fri, 20 Dec 2024 01:40:56 +0000 Subject: [PATCH] [syncd] Enable bulk api for next hop objects swss code change in 202411 uses nexthop bulk api to process dualtor mux switchover. Adds support in syncd for nexthop bulk api, which is present in SAI. Signed-off-by: Nikola Dancejic --- syncd/VendorSai.cpp | 8 +++ syncd/tests.cpp | 109 +++++++++++++++++++++++++++++++ syncd/tests/TestSyncdBrcm.cpp | 116 +++++++++++++++++++++++++++++++++ tests/BCM56850/bulk_object.rec | 7 ++ 4 files changed, 240 insertions(+) diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index c0cb5683a..388cf6b8e 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -465,6 +465,10 @@ sai_status_t VendorSai::bulkCreate( ptr = m_apis.next_hop_group_api->create_next_hop_group_members; break; + case SAI_OBJECT_TYPE_NEXT_HOP: + ptr = m_apis.next_hop_api->create_next_hops; + break; + case SAI_OBJECT_TYPE_SRV6_SIDLIST: ptr = m_apis.srv6_api->create_srv6_sidlists; break; @@ -548,6 +552,10 @@ sai_status_t VendorSai::bulkRemove( ptr = m_apis.next_hop_group_api->remove_next_hop_group_members; break; + case SAI_OBJECT_TYPE_NEXT_HOP: + ptr = m_apis.next_hop_api->remove_next_hops; + break; + case SAI_OBJECT_TYPE_SRV6_SIDLIST: ptr = m_apis.srv6_api->remove_srv6_sidlists; break; diff --git a/syncd/tests.cpp b/syncd/tests.cpp index 801a21334..0bb1aa0f8 100644 --- a/syncd/tests.cpp +++ b/syncd/tests.cpp @@ -373,6 +373,113 @@ void test_bulk_next_hop_group_member_create() ASSERT_SUCCESS("Failed to bulk remove nhgm"); } +void test_bulk_next_hop_create() +{ + SWSS_LOG_ENTER(); + + + sai_reinit(); + + sai_status_t status; + + sai_next_hop_api_t *sai_next_hop_api = NULL; + sai_switch_api_t *sai_switch_api = NULL; + sai_lag_api_t *sai_lag_api = NULL; + sai_router_interface_api_t *sai_rif_api = NULL; + sai_virtual_router_api_t * sai_virtual_router_api = NULL; + + sai_api_query(SAI_API_NEXT_HOP, (void**)&sai_next_hop_api); + sai_api_query(SAI_API_SWITCH, (void**)&sai_switch_api); + sai_api_query(SAI_API_ROUTER_INTERFACE, (void **)&sai_rif_api); + sai_api_query(SAI_API_LAG, (void**)&sai_lag_api); + sai_api_query(SAI_API_VIRTUAL_ROUTER, (void**)&sai_virtual_router_api); + + uint32_t count = 3; + + std::vector 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"); + + // 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"); + + std::vector> nh_attrs; + std::vector nh_attrs_array; + std::vector nh_attrs_count; + for (uint32_t i = 0; i < count; ++i) + { + std::vector list(3); + sai_attribute_t &nhattr0 = list[0]; + sai_attribute_t &nhattr1 = list[1]; + sai_attribute_t &nhattr2 = list[2]; + + nhattr0.id = SAI_NEXT_HOP_ATTR_TYPE; + nhattr0.value.s32 = SAI_NEXT_HOP_TYPE_IP; + nhattr1.id = SAI_NEXT_HOP_ATTR_IP; + nhattr1.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + nhattr1.value.ipaddr.addr.ip4 = 0x10000001; + nhattr2.id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; + nhattr2.value.oid = rif; + + nh_attrs.push_back(list); + nh_attrs_count.push_back(3); + } + + for (size_t j = 0; j < nh_attrs.size(); j++) + { + nh_attrs_array.push_back(nh_attrs[j].data()); + } + + std::vector statuses(count); + std::vector object_id(count); + sai_next_hop_api->create_next_hops(switch_id, count, nh_attrs_count.data(), nh_attrs_array.data(), SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, object_id.data(), statuses.data()); + ASSERT_SUCCESS("Failed to bulk create nh"); + + for (size_t j = 0; j < statuses.size(); j++) + { + status = statuses[j]; + ASSERT_SUCCESS("Failed to create nh # %zu", j); + } + + statuses.clear(); + + status = sai_next_hop_api->remove_next_hops(count, object_id.data(), SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, statuses.data()); + ASSERT_SUCCESS("Failed to bulk remove nh"); + for (size_t j = 0; j < statuses.size(); j++) + { + status = statuses[j]; + ASSERT_SUCCESS("Failed to remove nh # %zu", j); + } +} + void test_bulk_fdb_create() { SWSS_LOG_ENTER(); @@ -907,6 +1014,8 @@ int main() test_bulk_next_hop_group_member_create(); + test_bulk_next_hop_create(); + test_bulk_fdb_create(); test_bulk_neighbor_set(); diff --git a/syncd/tests/TestSyncdBrcm.cpp b/syncd/tests/TestSyncdBrcm.cpp index 892a3ca0e..24ab293f7 100644 --- a/syncd/tests/TestSyncdBrcm.cpp +++ b/syncd/tests/TestSyncdBrcm.cpp @@ -389,3 +389,119 @@ TEST_F(SyncdBrcmTest, neighborBulkTest) ASSERT_EQ(status, SAI_STATUS_SUCCESS); } } + +TEST_F(SyncdBrcmTest, nexthopBulkTest) +{ + sai_object_id_t switchId; + sai_object_id_t rif; + sai_object_id_t port; + sai_attribute_t attrs[3]; + + // init view + + attrs[0].id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD; + attrs[0].value.s32 = SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW; + + auto status = m_sairedis->set(SAI_OBJECT_TYPE_SWITCH, SAI_NULL_OBJECT_ID, attrs); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + // create switch + + attrs[0].id = SAI_SWITCH_ATTR_INIT_SWITCH; + attrs[0].value.booldata = true; + + status = m_sairedis->create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, attrs); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + attrs[0].id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + status = m_sairedis->get(SAI_OBJECT_TYPE_SWITCH, switchId, 1, attrs); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + sai_object_id_t vr = attrs[0].value.oid; + + // create port + static uint32_t id = 1; + id++; + + uint32_t hw_lane_list[1] = { id }; + + attrs[0].id = SAI_PORT_ATTR_HW_LANE_LIST; + attrs[0].value.u32list.count = 1; + attrs[0].value.u32list.list = hw_lane_list; + + attrs[1].id = SAI_PORT_ATTR_SPEED; + attrs[1].value.u32 = 10000; + + status = m_sairedis->create(SAI_OBJECT_TYPE_PORT, &port, switchId, 2, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + // create rif + attrs[0].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; + attrs[0].value.oid = vr; + + attrs[1].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; + attrs[1].value.s32 = SAI_ROUTER_INTERFACE_TYPE_PORT; + + attrs[2].id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID; + attrs[2].value.oid = port; + + status = m_sairedis->create(SAI_OBJECT_TYPE_ROUTER_INTERFACE, &rif, switchId, 3, attrs); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + std::vector> nh_attrs; + std::vector nh_attrs_array; + std::vector nh_attrs_count; + uint32_t count = 3; + for (uint32_t i = 0; i < count; ++i) + { + std::vector list(3); + sai_attribute_t &nhattr0 = list[0]; + sai_attribute_t &nhattr1 = list[1]; + sai_attribute_t &nhattr2 = list[2]; + + nhattr0.id = SAI_NEXT_HOP_ATTR_TYPE; + nhattr0.value.s32 = SAI_NEXT_HOP_TYPE_IP; + nhattr1.id = SAI_NEXT_HOP_ATTR_IP; + nhattr1.value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + nhattr1.value.ipaddr.addr.ip4 = 0x10000001; + nhattr2.id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; + nhattr2.value.oid = rif; + + nh_attrs.push_back(list); + nh_attrs_count.push_back(3); + } + + for (size_t j = 0; j < nh_attrs.size(); j++) + { + nh_attrs_array.push_back(nh_attrs[j].data()); + } + + std::vector statuses(count); + std::vector object_id(count); + status = m_sairedis->bulkCreate( + (sai_object_type_t) SAI_OBJECT_TYPE_NEXT_HOP, switchId, + count, nh_attrs_count.data(), nh_attrs_array.data(), + SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, + object_id.data(), statuses.data()); + + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + for (size_t j = 0; j < statuses.size(); j++) + { + status = statuses[j]; + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + } + + statuses.clear(); + + status = m_sairedis->bulkRemove( + (sai_object_type_t) SAI_OBJECT_TYPE_NEXT_HOP, + count, object_id.data(), + SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, + statuses.data()); + for (size_t j = 0; j < statuses.size(); j++) + { + status = statuses[j]; + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + } +} diff --git a/tests/BCM56850/bulk_object.rec b/tests/BCM56850/bulk_object.rec index eacbbb9da..ee7da929c 100644 --- a/tests/BCM56850/bulk_object.rec +++ b/tests/BCM56850/bulk_object.rec @@ -5,5 +5,12 @@ 2017-06-14.01:55:56.555975|C|SAI_OBJECT_TYPE_NEXT_HOP_GROUP||oid:0x5000000000005|SAI_NEXT_HOP_GROUP_ATTR_TYPE=SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP||oid:0x5000000000006|SAI_NEXT_HOP_GROUP_ATTR_TYPE=SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP||oid:0x5000000000007|SAI_NEXT_HOP_GROUP_ATTR_TYPE=SAI_NEXT_HOP_GROUP_TYPE_DYNAMIC_UNORDERED_ECMP 2017-06-14.01:55:56.555975|S|SAI_OBJECT_TYPE_NEXT_HOP_GROUP||oid:0x5000000000005|SAI_NEXT_HOP_GROUP_ATTR_SET_SWITCHOVER=true||oid:0x5000000000006|SAI_NEXT_HOP_GROUP_ATTR_SET_SWITCHOVER=true||oid:0x5000000000007|SAI_NEXT_HOP_GROUP_ATTR_SET_SWITCHOVER=true 2017-06-14.01:55:56.555975|R|SAI_OBJECT_TYPE_NEXT_HOP_GROUP||oid:0x5000000000005||oid:0x5000000000006||oid:0x5000000000007 +2017-06-14.01:55:56.555975|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID=oid:0x0 +2017-06-14.01:55:56.555975|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID=oid:0x3000000000022 +2017-06-14.01:55:56.555975|c|SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x60000000005bc|SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID=oid:0x3000000000022|SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS=00:E0:EC:C2:AD:F1|SAI_ROUTER_INTERFACE_ATTR_TYPE=SAI_ROUTER_INTERFACE_TYPE_PORT|SAI_ROUTER_INTERFACE_ATTR_PORT_ID=oid:0x1000000000009|SAI_ROUTER_INTERFACE_ATTR_MTU=9100 +2017-06-14.01:55:56.555975|c|SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x600000000065d|SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID=oid:0x3000000000022|SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS=00:E0:EC:C2:AD:F1|SAI_ROUTER_INTERFACE_ATTR_TYPE=SAI_ROUTER_INTERFACE_TYPE_PORT|SAI_ROUTER_INTERFACE_ATTR_PORT_ID=oid:0x100000000001e|SAI_ROUTER_INTERFACE_ATTR_MTU=9100 +2017-06-14.01:55:56.555975|c|SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x6000000000663|SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID=oid:0x3000000000022|SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS=00:E0:EC:C2:AD:F1|SAI_ROUTER_INTERFACE_ATTR_TYPE=SAI_ROUTER_INTERFACE_TYPE_PORT|SAI_ROUTER_INTERFACE_ATTR_PORT_ID=oid:0x1000000000005|SAI_ROUTER_INTERFACE_ATTR_MTU=9100 +2017-06-14.01:55:56.555975|C|SAI_OBJECT_TYPE_NEXT_HOP||oid:0x4000000000667|SAI_NEXT_HOP_ATTR_TYPE=SAI_NEXT_HOP_TYPE_IP|SAI_NEXT_HOP_ATTR_IP=10.0.0.55|SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID=oid:0x60000000005bc||oid:0x4000000000668|SAI_NEXT_HOP_ATTR_TYPE=SAI_NEXT_HOP_TYPE_IP|SAI_NEXT_HOP_ATTR_IP=10.0.0.47|SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID=oid:0x6000000000663||oid:0x4000000000669|SAI_NEXT_HOP_ATTR_TYPE=SAI_NEXT_HOP_TYPE_IP|SAI_NEXT_HOP_ATTR_IP=10.0.0.57|SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID=oid:0x600000000065d +2017-06-14.01:55:56.555975|R|SAI_OBJECT_TYPE_NEXT_HOP||oid:0x4000000000667||oid:0x4000000000668||oid:0x4000000000669 2017-06-14.01:56:06.151337|a|APPLY_VIEW 2017-06-14.01:56:06.156740|A|SAI_STATUS_SUCCESS