From 78f36138e14e1ed0f0f772950f03420327ef1b1c Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Wed, 15 Sep 2021 10:54:47 -0700 Subject: [PATCH] Added query Enum value capability for vxlan EVPN feature (#920) --- unittest/vslib/TestSwitchBCM56850.cpp | 150 ++++++++++++++++++++++++++ unittest/vslib/TestSwitchMLNX2700.cpp | 144 +++++++++++++++++++++++++ vslib/SwitchMLNX2700.cpp | 34 ++++++ vslib/SwitchMLNX2700.h | 7 ++ vslib/SwitchStateBase.cpp | 55 ++++++++++ vslib/SwitchStateBase.h | 14 +++ vslib/VirtualSwitchSaiInterface.cpp | 3 +- 7 files changed, 406 insertions(+), 1 deletion(-) diff --git a/unittest/vslib/TestSwitchBCM56850.cpp b/unittest/vslib/TestSwitchBCM56850.cpp index 6c049259ffa9..df4e3d17f16e 100644 --- a/unittest/vslib/TestSwitchBCM56850.cpp +++ b/unittest/vslib/TestSwitchBCM56850.cpp @@ -268,3 +268,153 @@ TEST(SwitchBCM56850, warm_update_queues) EXPECT_EQ(sw.get(SAI_OBJECT_TYPE_BRIDGE, sboid, 1, &attr), SAI_STATUS_SUCCESS); } + +TEST(SwitchBCM56850, test_tunnel_term_capability) +{ + auto sc = std::make_shared(0, ""); + auto signal = std::make_shared(); + auto eventQueue = std::make_shared(signal); + + sc->m_saiSwitchType = SAI_SWITCH_TYPE_NPU; + sc->m_switchType = SAI_VS_SWITCH_TYPE_BCM56850; + sc->m_bootType = SAI_VS_BOOT_TYPE_COLD; + sc->m_useTapDevice = false; + sc->m_laneMap = LaneMap::getDefaultLaneMap(0); + sc->m_eventQueue = eventQueue; + + auto scc = std::make_shared(); + + scc->insert(sc); + + SwitchBCM56850 sw( + 0x2100000000, + std::make_shared(0, scc), + sc); + + + sai_s32_list_t enum_val_cap; + int32_t list[2]; + + enum_val_cap.count = 2; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_TUNNEL, + SAI_TUNNEL_ATTR_PEER_MODE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 2); + + int modes_found = 0; + + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_TUNNEL_PEER_MODE_P2MP || enum_val_cap.list[i] == SAI_TUNNEL_PEER_MODE_P2P) + { + modes_found++; + } + } + + EXPECT_EQ(modes_found, 2); +} + +TEST(SwitchBCM56850, test_vlan_flood_capability) +{ + auto sc = std::make_shared(0, ""); + auto signal = std::make_shared(); + auto eventQueue = std::make_shared(signal); + + sc->m_saiSwitchType = SAI_SWITCH_TYPE_NPU; + sc->m_switchType = SAI_VS_SWITCH_TYPE_BCM56850; + sc->m_bootType = SAI_VS_BOOT_TYPE_COLD; + sc->m_useTapDevice = false; + sc->m_laneMap = LaneMap::getDefaultLaneMap(0); + sc->m_eventQueue = eventQueue; + + auto scc = std::make_shared(); + + scc->insert(sc); + + SwitchBCM56850 sw( + 0x2100000000, + std::make_shared(0, scc), + sc); + + sai_s32_list_t enum_val_cap; + int32_t list[4]; + + enum_val_cap.count = 4; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_VLAN, + SAI_VLAN_ATTR_UNKNOWN_UNICAST_FLOOD_CONTROL_TYPE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 3); + + int flood_types_found = 0; + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_ALL || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_NONE || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP) + { + flood_types_found++; + } + } + + EXPECT_EQ(flood_types_found, 3); + + memset(list, 0, sizeof(list)); + flood_types_found = 0; + enum_val_cap.count = 4; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_VLAN, + SAI_VLAN_ATTR_UNKNOWN_MULTICAST_FLOOD_CONTROL_TYPE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 3); + + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_ALL || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_NONE || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP) + { + flood_types_found++; + } + } + + EXPECT_EQ(flood_types_found, 3); + + memset(list, 0, sizeof(list)); + flood_types_found = 0; + enum_val_cap.count = 4; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_VLAN, + SAI_VLAN_ATTR_BROADCAST_FLOOD_CONTROL_TYPE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 3); + + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_ALL || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_NONE || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP) + { + flood_types_found++; + } + } + + EXPECT_EQ(flood_types_found, 3); +} diff --git a/unittest/vslib/TestSwitchMLNX2700.cpp b/unittest/vslib/TestSwitchMLNX2700.cpp index 8086ea69227f..d271b4c627e8 100644 --- a/unittest/vslib/TestSwitchMLNX2700.cpp +++ b/unittest/vslib/TestSwitchMLNX2700.cpp @@ -267,3 +267,147 @@ TEST(SwitchMLNX2700, warm_update_queues) EXPECT_EQ(sw.get(SAI_OBJECT_TYPE_BRIDGE, sboid, 1, &attr), SAI_STATUS_SUCCESS); } + +TEST(SwitchMLNX2700, test_tunnel_term_capability) +{ + auto sc = std::make_shared(0, ""); + auto signal = std::make_shared(); + auto eventQueue = std::make_shared(signal); + + sc->m_saiSwitchType = SAI_SWITCH_TYPE_NPU; + sc->m_switchType = SAI_VS_SWITCH_TYPE_MLNX2700; + sc->m_bootType = SAI_VS_BOOT_TYPE_COLD; + sc->m_useTapDevice = false; + sc->m_laneMap = LaneMap::getDefaultLaneMap(0); + sc->m_eventQueue = eventQueue; + + auto scc = std::make_shared(); + + scc->insert(sc); + + SwitchMLNX2700 sw( + 0x2100000000, + std::make_shared(0, scc), + sc); + + sai_s32_list_t enum_val_cap; + int32_t list[2]; + + enum_val_cap.count = 2; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_TUNNEL, + SAI_TUNNEL_ATTR_PEER_MODE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 1); + + EXPECT_EQ(enum_val_cap.list[0], SAI_TUNNEL_PEER_MODE_P2MP); + +} + +TEST(SwitchMLNX2700, test_vlan_flood_capability) +{ + auto sc = std::make_shared(0, ""); + auto signal = std::make_shared(); + auto eventQueue = std::make_shared(signal); + + sc->m_saiSwitchType = SAI_SWITCH_TYPE_NPU; + sc->m_switchType = SAI_VS_SWITCH_TYPE_MLNX2700; + sc->m_bootType = SAI_VS_BOOT_TYPE_COLD; + sc->m_useTapDevice = false; + sc->m_laneMap = LaneMap::getDefaultLaneMap(0); + sc->m_eventQueue = eventQueue; + + auto scc = std::make_shared(); + + scc->insert(sc); + + SwitchMLNX2700 sw( + 0x2100000000, + std::make_shared(0, scc), + sc); + + sai_s32_list_t enum_val_cap; + int32_t list[4]; + + enum_val_cap.count = 4; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_VLAN, + SAI_VLAN_ATTR_UNKNOWN_UNICAST_FLOOD_CONTROL_TYPE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 4); + + int flood_types_found = 0; + + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_ALL || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_NONE || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_COMBINED) + { + flood_types_found++; + } + } + + EXPECT_EQ(flood_types_found, 4); + + memset(list, 0, sizeof(list)); + flood_types_found = 0; + enum_val_cap.count = 4; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_VLAN, + SAI_VLAN_ATTR_UNKNOWN_MULTICAST_FLOOD_CONTROL_TYPE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 4); + + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_ALL || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_NONE || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_COMBINED) + { + flood_types_found++; + } + } + + EXPECT_EQ(flood_types_found, 4); + + memset(list, 0, sizeof(list)); + flood_types_found = 0; + enum_val_cap.count = 4; + enum_val_cap.list = list; + + EXPECT_EQ(sw.queryAttrEnumValuesCapability(0x2100000000, + SAI_OBJECT_TYPE_VLAN, + SAI_VLAN_ATTR_BROADCAST_FLOOD_CONTROL_TYPE, + &enum_val_cap), + SAI_STATUS_SUCCESS); + + EXPECT_EQ(enum_val_cap.count, 4); + + for (uint32_t i = 0; i < enum_val_cap.count; i++) + { + if (enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_ALL || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_NONE || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP || + enum_val_cap.list[i] == SAI_VLAN_FLOOD_CONTROL_TYPE_COMBINED) + { + flood_types_found++; + } + } + + EXPECT_EQ(flood_types_found, 4); +} diff --git a/vslib/SwitchMLNX2700.cpp b/vslib/SwitchMLNX2700.cpp index b3ab808aaa25..de709e6f9ae7 100644 --- a/vslib/SwitchMLNX2700.cpp +++ b/vslib/SwitchMLNX2700.cpp @@ -424,3 +424,37 @@ sai_status_t SwitchMLNX2700::warm_update_queues() return SAI_STATUS_SUCCESS; } + +sai_status_t SwitchMLNX2700::queryVlanfloodTypeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) +{ + SWSS_LOG_ENTER(); + + if (enum_values_capability->count < 4) + { + return SAI_STATUS_BUFFER_OVERFLOW; + } + + enum_values_capability->count = 4; + enum_values_capability->list[0] = SAI_VLAN_FLOOD_CONTROL_TYPE_ALL; + enum_values_capability->list[1] = SAI_VLAN_FLOOD_CONTROL_TYPE_NONE; + enum_values_capability->list[2] = SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP; + enum_values_capability->list[3] = SAI_VLAN_FLOOD_CONTROL_TYPE_COMBINED; + + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchMLNX2700::queryTunnelPeerModeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) +{ + SWSS_LOG_ENTER(); + + if (enum_values_capability->count < 1) + { + return SAI_STATUS_BUFFER_OVERFLOW; + } + + enum_values_capability->count = 1; + enum_values_capability->list[0] = SAI_TUNNEL_PEER_MODE_P2MP; + return SAI_STATUS_SUCCESS; +} diff --git a/vslib/SwitchMLNX2700.h b/vslib/SwitchMLNX2700.h index 52f18bc9a77b..9ef0f9f07a25 100644 --- a/vslib/SwitchMLNX2700.h +++ b/vslib/SwitchMLNX2700.h @@ -43,5 +43,12 @@ namespace saivs _In_ sai_object_id_t bridge_id) override; virtual sai_status_t warm_update_queues() override; + + protected: + virtual sai_status_t queryTunnelPeerModeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) override; + virtual sai_status_t queryVlanfloodTypeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) override; + }; } diff --git a/vslib/SwitchStateBase.cpp b/vslib/SwitchStateBase.cpp index 7ca4bff259a6..02aa7c3ed6aa 100644 --- a/vslib/SwitchStateBase.cpp +++ b/vslib/SwitchStateBase.cpp @@ -3296,3 +3296,58 @@ bool SwitchStateBase::dumpObject( return true; } + +sai_status_t SwitchStateBase::queryTunnelPeerModeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) +{ + SWSS_LOG_ENTER(); + + if (enum_values_capability->count < 2) + { + return SAI_STATUS_BUFFER_OVERFLOW; + } + + enum_values_capability->count = 2; + enum_values_capability->list[0] = SAI_TUNNEL_PEER_MODE_P2MP; + enum_values_capability->list[1] = SAI_TUNNEL_PEER_MODE_P2P; + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase::queryVlanfloodTypeCapability( + _Inout_ sai_s32_list_t *enum_values_capability) +{ + SWSS_LOG_ENTER(); + + if (enum_values_capability->count < 3) + { + return SAI_STATUS_BUFFER_OVERFLOW; + } + + enum_values_capability->count = 3; + enum_values_capability->list[0] = SAI_VLAN_FLOOD_CONTROL_TYPE_ALL; + enum_values_capability->list[1] = SAI_VLAN_FLOOD_CONTROL_TYPE_NONE; + enum_values_capability->list[2] = SAI_VLAN_FLOOD_CONTROL_TYPE_L2MC_GROUP; + + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase::queryAttrEnumValuesCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Inout_ sai_s32_list_t *enum_values_capability) +{ + SWSS_LOG_ENTER(); + + if (object_type == SAI_OBJECT_TYPE_TUNNEL && attr_id == SAI_TUNNEL_ATTR_PEER_MODE) + { + return queryTunnelPeerModeCapability(enum_values_capability); + } + else if (object_type == SAI_OBJECT_TYPE_VLAN && (attr_id == SAI_VLAN_ATTR_UNKNOWN_UNICAST_FLOOD_CONTROL_TYPE || + attr_id == SAI_VLAN_ATTR_UNKNOWN_MULTICAST_FLOOD_CONTROL_TYPE || + attr_id == SAI_VLAN_ATTR_BROADCAST_FLOOD_CONTROL_TYPE)) + { + return queryVlanfloodTypeCapability(enum_values_capability); + } + return SAI_STATUS_NOT_SUPPORTED; +} diff --git a/vslib/SwitchStateBase.h b/vslib/SwitchStateBase.h index d870deaabd84..666c106f041f 100644 --- a/vslib/SwitchStateBase.h +++ b/vslib/SwitchStateBase.h @@ -268,6 +268,12 @@ namespace saivs _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses); + virtual sai_status_t queryAttrEnumValuesCapability( + _In_ sai_object_id_t switch_id, + _In_ sai_object_type_t object_type, + _In_ sai_attr_id_t attr_id, + _Inout_ sai_s32_list_t *enum_values_capability); + protected: virtual sai_status_t remove_internal( @@ -633,6 +639,14 @@ namespace saivs constexpr static const int m_maxAclTables = 3; constexpr static const int m_maxAclTableGroups = 200; + protected: + + virtual sai_status_t queryTunnelPeerModeCapability( + _Inout_ sai_s32_list_t *enum_values_capability); + + virtual sai_status_t queryVlanfloodTypeCapability( + _Inout_ sai_s32_list_t *enum_values_capability); + public: // TODO private std::set m_fdb_info_set; diff --git a/vslib/VirtualSwitchSaiInterface.cpp b/vslib/VirtualSwitchSaiInterface.cpp index 14bd9dce1065..58df841e1ded 100644 --- a/vslib/VirtualSwitchSaiInterface.cpp +++ b/vslib/VirtualSwitchSaiInterface.cpp @@ -831,8 +831,9 @@ sai_status_t VirtualSwitchSaiInterface::queryAattributeEnumValuesCapability( return SAI_STATUS_SUCCESS; } + auto ss = m_switchStateMap.at(switch_id); + return ss->queryAttrEnumValuesCapability(switch_id, object_type, attr_id, enum_values_capability); - return SAI_STATUS_NOT_SUPPORTED; } sai_status_t VirtualSwitchSaiInterface::getStats(