From 59cc1f904555e67635de11df5ba260a062e097d6 Mon Sep 17 00:00:00 2001 From: Nikola Dancejic <26731235+Ndancejic@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:52:52 -0800 Subject: [PATCH] [syncd] Enable bulk api for next hop objects (#1487) * [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. --- 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 4e6ee2d8b..68b64f077 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 7a6e44424..b9998d0c5 100644 --- a/syncd/tests/TestSyncdBrcm.cpp +++ b/syncd/tests/TestSyncdBrcm.cpp @@ -390,6 +390,122 @@ TEST_F(SyncdBrcmTest, neighborBulkTest) } } +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); + } +} + TEST_F(SyncdBrcmTest, portBufferBulkSet) { sai_object_id_t switchId; diff --git a/tests/BCM56850/bulk_object.rec b/tests/BCM56850/bulk_object.rec index 781c1fa28..dc2a339f2 100644 --- a/tests/BCM56850/bulk_object.rec +++ b/tests/BCM56850/bulk_object.rec @@ -16,5 +16,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