From 8fbcba68e9de892d92d48ab9169a9489bda64d08 Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Fri, 16 Sep 2022 09:13:50 +0800 Subject: [PATCH] [202205][vslib]: Add SAI_PORT_ATTR_OPER_SPEED get #1123 Add SAI_PORT_ATTR_OPER_SPEED get in vslib. If the SAI_PORT_ATTR_OPER_STATUS is DOWN, SAI_PORT_ATTR_OPER_SPEED should be 0, otherwise its value comes from /sys/class/net/eth{X}/speed Fixing the PR(#1107) conflict with 202205 Signed-off-by: Ze Gan --- unittest/vslib/TestSwitchBCM81724.cpp | 32 ++++++++++++++++++++++ vslib/SwitchBCM81724.cpp | 3 +++ vslib/SwitchStateBase.cpp | 36 +++++++++++++++++++++++++ vslib/SwitchStateBase.h | 7 +++++ vslib/SwitchStateBaseHostif.cpp | 39 +++++++++++++++++++++++++++ 5 files changed, 117 insertions(+) diff --git a/unittest/vslib/TestSwitchBCM81724.cpp b/unittest/vslib/TestSwitchBCM81724.cpp index 416967615..44aa3268f 100644 --- a/unittest/vslib/TestSwitchBCM81724.cpp +++ b/unittest/vslib/TestSwitchBCM81724.cpp @@ -117,6 +117,38 @@ TEST(SwitchBCM81724, refresh_read_only) EXPECT_EQ(sw.get(SAI_OBJECT_TYPE_PORT, strPortId, 1, &attr), SAI_STATUS_SUCCESS); + char fakeinfo_buffer[sizeof(HostInterfaceInfo)] = { 0 }; + HostInterfaceInfo *fakeinfo = reinterpret_cast(reinterpret_cast(fakeinfo_buffer)); + fakeinfo->m_portId = portId; + sw.m_hostif_info_map[""] = std::shared_ptr(fakeinfo, [](HostInterfaceInfo *){}); + sw.m_switchConfig->m_laneMap->m_lane_to_ifname[1] = "eth0"; + + attr.id = SAI_PORT_ATTR_OPER_STATUS; + attr.value.s32 = SAI_PORT_OPER_STATUS_DOWN; + + EXPECT_EQ(sw.set(SAI_OBJECT_TYPE_PORT, strPortId, &attr), SAI_STATUS_SUCCESS); + + attr.id = SAI_PORT_ATTR_OPER_SPEED; + + EXPECT_EQ(sw.get(SAI_OBJECT_TYPE_PORT, strPortId, 1, &attr), SAI_STATUS_SUCCESS); + EXPECT_EQ(attr.value.u32, 0); + + attr.id = SAI_PORT_ATTR_OPER_STATUS; + attr.value.s32 = SAI_PORT_OPER_STATUS_UP; + + EXPECT_EQ(sw.set(SAI_OBJECT_TYPE_PORT, strPortId, &attr), SAI_STATUS_SUCCESS); + + attr.id = SAI_PORT_ATTR_OPER_SPEED; + + EXPECT_EQ(sw.get(SAI_OBJECT_TYPE_PORT, strPortId, 1, &attr), SAI_STATUS_SUCCESS); + EXPECT_GE(attr.value.u32, 0); + + sw.m_hostif_info_map.clear(); + + attr.id = SAI_PORT_ATTR_OPER_SPEED; + + EXPECT_NE(sw.get(SAI_OBJECT_TYPE_PORT, strPortId, 1, &attr), SAI_STATUS_SUCCESS); + //std::cout << sw.dump_switch_database_for_warm_restart(); } diff --git a/vslib/SwitchBCM81724.cpp b/vslib/SwitchBCM81724.cpp index 0b1e8bf8e..8c6b91a46 100644 --- a/vslib/SwitchBCM81724.cpp +++ b/vslib/SwitchBCM81724.cpp @@ -274,6 +274,9 @@ sai_status_t SwitchBCM81724::refresh_read_only( case SAI_PORT_ATTR_OPER_STATUS: return SAI_STATUS_SUCCESS; + + case SAI_PORT_ATTR_OPER_SPEED: + return refresh_port_oper_speed(object_id); } } diff --git a/vslib/SwitchStateBase.cpp b/vslib/SwitchStateBase.cpp index 2fe6d93f2..9cbf1645c 100644 --- a/vslib/SwitchStateBase.cpp +++ b/vslib/SwitchStateBase.cpp @@ -2182,6 +2182,36 @@ sai_status_t SwitchStateBase::refresh_port_serdes_id( return SAI_STATUS_SUCCESS; } +sai_status_t SwitchStateBase::refresh_port_oper_speed( + _In_ sai_object_id_t port_id) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + + attr.id = SAI_PORT_ATTR_OPER_STATUS; + + CHECK_STATUS(get(SAI_OBJECT_TYPE_PORT, port_id, 1, &attr)); + + if (attr.value.s32 == SAI_PORT_OPER_STATUS_DOWN) + { + attr.value.u32 = 0; + } + else + { + if (!vs_get_oper_speed(port_id, attr.value.u32)) + { + return SAI_STATUS_FAILURE; + } + } + + attr.id = SAI_PORT_ATTR_OPER_SPEED; + + CHECK_STATUS(set(SAI_OBJECT_TYPE_PORT, port_id, &attr)); + + return SAI_STATUS_SUCCESS; +} + // XXX extra work may be needed on GET api if N on list will be > then actual /* @@ -2291,6 +2321,12 @@ sai_status_t SwitchStateBase::refresh_read_only( case SAI_PORT_ATTR_PORT_SERDES_ID: return refresh_port_serdes_id(object_id); + + case SAI_PORT_ATTR_SUPPORTED_AUTO_NEG_MODE: + return SAI_STATUS_SUCCESS; + + case SAI_PORT_ATTR_OPER_SPEED: + return refresh_port_oper_speed(object_id); } } diff --git a/vslib/SwitchStateBase.h b/vslib/SwitchStateBase.h index 76f2527c8..f25ca09a8 100644 --- a/vslib/SwitchStateBase.h +++ b/vslib/SwitchStateBase.h @@ -163,6 +163,9 @@ namespace saivs virtual sai_status_t refresh_port_serdes_id( _In_ sai_object_id_t bridge_id); + virtual sai_status_t refresh_port_oper_speed( + _In_ sai_object_id_t port_id); + public: virtual sai_status_t warm_boot_initialize_objects(); @@ -484,6 +487,10 @@ namespace saivs bool hasIfIndex( _In_ int ifIndex) const; + bool vs_get_oper_speed( + _In_ sai_object_id_t port_id, + _Out_ uint32_t& speed); + public: // TODO move inside warm boot load state sai_status_t vs_recreate_hostif_tap_interfaces(); diff --git a/vslib/SwitchStateBaseHostif.cpp b/vslib/SwitchStateBaseHostif.cpp index 01f44a17b..855ac43e7 100644 --- a/vslib/SwitchStateBaseHostif.cpp +++ b/vslib/SwitchStateBaseHostif.cpp @@ -25,6 +25,7 @@ #include #include +#include using namespace saivs; @@ -871,6 +872,44 @@ bool SwitchStateBase::hasIfIndex( return false; } +bool SwitchStateBase::vs_get_oper_speed( + _In_ sai_object_id_t port_id, + _Out_ uint32_t& speed) + +{ + SWSS_LOG_ENTER(); + + auto info = findHostInterfaceInfoByPort(port_id); + + if (!info) + { + SWSS_LOG_ERROR("Port %s don't exists", + sai_serialize_object_id(port_id).c_str()); + + return false; + } + + auto veth_name = vs_get_veth_name(info->m_name, port_id); + std::string veth_speed_filename = "/sys/class/net/"; + + veth_speed_filename += veth_name; + veth_speed_filename += "/speed"; + + std::ifstream ifs(veth_speed_filename); + + if (!ifs.is_open()) + { + SWSS_LOG_ERROR("Failed to open %s", veth_speed_filename.c_str()); + + return false; + } + + ifs >> speed; + ifs.close(); + + return true; +} + void SwitchStateBase::syncOnLinkMsg( _In_ std::shared_ptr payload) {