From 76f90a081e694c3ebc1da92ac5d959db368542d9 Mon Sep 17 00:00:00 2001 From: Serhiy Boiko Date: Mon, 8 Jul 2024 10:39:17 +0300 Subject: [PATCH] [sonic-sairedis] Add support for PoE Add SwitchPoe to vslib Add a python script to spawn the PoE syncd process Signed-off-by: Serhiy Boiko --- meta/Meta.cpp | 24 ++ syncd/SaiSwitch.cpp | 7 +- syncd/scripts/poesyncdmgrd | 76 ++++++ vslib/Makefile.am | 1 + vslib/SwitchConfig.cpp | 12 +- vslib/SwitchConfig.h | 2 + vslib/SwitchPoE.cpp | 370 ++++++++++++++++++++++++++++ vslib/SwitchPoE.h | 71 ++++++ vslib/SwitchStateBase.cpp | 26 ++ vslib/SwitchStateBase.h | 6 + vslib/VirtualSwitchSaiInterface.cpp | 6 + vslib/saivs.h | 2 + 12 files changed, 601 insertions(+), 2 deletions(-) create mode 100755 syncd/scripts/poesyncdmgrd create mode 100644 vslib/SwitchPoE.cpp create mode 100644 vslib/SwitchPoE.h diff --git a/meta/Meta.cpp b/meta/Meta.cpp index bd3f1b010..336ca0c47 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -1937,6 +1937,10 @@ void Meta::meta_generic_validation_post_remove( // no special action required break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + // no special action required + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); } @@ -3573,6 +3577,9 @@ sai_status_t Meta::meta_generic_validation_create( VALIDATION_LIST(md, value.ipprefixlist); break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -4248,6 +4255,9 @@ sai_status_t Meta::meta_generic_validation_set( VALIDATION_LIST(md, value.ipprefixlist); break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -4635,6 +4645,9 @@ sai_status_t Meta::meta_generic_validation_get( VALIDATION_LIST(md, value.ipprefixlist); break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + break; + default: // acl capability will is more complex since is in/out we need to check stage @@ -4908,6 +4921,9 @@ void Meta::meta_generic_validation_post_get( VALIDATION_LIST_GET(md, value.ipprefixlist); break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -5802,6 +5818,10 @@ void Meta::meta_generic_validation_post_create( // no special action required break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + // no special action required + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -6041,6 +6061,10 @@ void Meta::meta_generic_validation_post_set( // no special action required break; + case SAI_ATTR_VALUE_TYPE_POE_PORT_POWER_CONSUMPTION: + // no special action required + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); } diff --git a/syncd/SaiSwitch.cpp b/syncd/SaiSwitch.cpp index fb711db4d..7f23c4b44 100644 --- a/syncd/SaiSwitch.cpp +++ b/syncd/SaiSwitch.cpp @@ -150,7 +150,12 @@ sai_switch_type_t SaiSwitch::getSwitchType() const attr.value.s32 = SAI_SWITCH_TYPE_NPU; } - SWSS_LOG_INFO("switch type: '%s'", (attr.value.s32 == SAI_SWITCH_TYPE_NPU ? "SAI_SWITCH_TYPE_NPU" : "SAI_SWITCH_TYPE_PHY")); + if (attr.value.s32 == SAI_SWITCH_TYPE_NPU) + SWSS_LOG_INFO("switch type: 'SAI_SWITCH_TYPE_NPU'"); + else if (attr.value.s32 == SAI_SWITCH_TYPE_PHY) + SWSS_LOG_INFO("switch type: 'SAI_SWITCH_TYPE_PHY'"); + else if (attr.value.s32 == SAI_SWITCH_TYPE_POE) + SWSS_LOG_INFO("switch type: 'SAI_SWITCH_TYPE_POE'"); return (sai_switch_type_t) attr.value.s32; } diff --git a/syncd/scripts/poesyncdmgrd b/syncd/scripts/poesyncdmgrd new file mode 100755 index 000000000..8a5b92039 --- /dev/null +++ b/syncd/scripts/poesyncdmgrd @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +import os +import signal +import subprocess +import sys +import syslog +import time + + +SYSLOG_IDENTIFIER = os.path.basename(__file__) + +EXIT_SUCCESS = 0 +EXIT_INSUFFICIENT_PERMISSIONS = 1 +EXIT_UNKNOWN = 2 + +running = True +exit_code = EXIT_UNKNOWN + + +def fatal_signal_handler(sig, frame): + global running + + signal_name = signal.Signals(sig).name + + syslog.syslog(syslog.LOG_NOTICE, 'Caught signal {} - exiting...'.format(signal_name)) + exit_code = sig + 128 + running = False + + +def main(): + # Only privileged users can run this daemon + if os.geteuid() != 0: + print('Root privileges required for this operation') + return EXIT_INSUFFICIENT_PERMISSIONS + + syslog.openlog(SYSLOG_IDENTIFIER) + + # Register our signal handlers + signal.signal(signal.SIGTERM, fatal_signal_handler) + + # Check if a poe config exists + if not os.path.isfile('/usr/share/sonic/hwsku/poe_config.json'): + syslog.syslog(syslog.LOG_NOTICE, 'PoE is not supported on this platform. Exiting ...') + syslog.closelog() + time.sleep(2) + return EXIT_SUCCESS + + # Spawn poe syncd process + cmd = '/usr/bin/syncd -s -p /etc/sai.d/poe.profile -x /usr/share/sonic/hwsku/context_config.json -g 1' + proc = subprocess.Popen(cmd.split(), close_fds=True) + + global running + + # Check all of our subprocesses. If any exit, we should too. + while running: + proc.poll() + if proc.returncode is not None: + syslog.syslog(syslog.LOG_NOTICE, 'Subprocess PID {} exited. Shutting down ...'.format(proc.pid)) + running = False + break + time.sleep(1) + + # If we get here, either the subprocess exited or we recieved a signal to exit + # so we send SIGTERM to the subprocesses (if it is still running) before exiting + if proc.returncode is None: + syslog.syslog(syslog.LOG_INFO, 'Terminating PID {} ...'.format(proc.pid)) + proc.terminate() + + syslog.closelog() + + return exit_code + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/vslib/Makefile.am b/vslib/Makefile.am index ab6b68a31..64f20e237 100644 --- a/vslib/Makefile.am +++ b/vslib/Makefile.am @@ -49,6 +49,7 @@ libSaiVS_a_SOURCES = \ SwitchContainer.cpp \ Switch.cpp \ SwitchMLNX2700.cpp \ + SwitchPoE.cpp \ SwitchNvdaMBF2H536C.cpp \ SwitchStateBase.cpp \ SwitchStateBaseFdb.cpp \ diff --git a/vslib/SwitchConfig.cpp b/vslib/SwitchConfig.cpp index 88eeebd52..e4959399c 100644 --- a/vslib/SwitchConfig.cpp +++ b/vslib/SwitchConfig.cpp @@ -40,11 +40,16 @@ bool SwitchConfig::parseSaiSwitchType( { saiSwitchType = SAI_SWITCH_TYPE_PHY; } + else if (st == SAI_VALUE_SAI_SWITCH_TYPE_POE) + { + saiSwitchType = SAI_SWITCH_TYPE_POE; + } else { - SWSS_LOG_ERROR("unknown SAI switch type: '%s', expected (%s|%s)", + SWSS_LOG_ERROR("unknown SAI switch type: '%s', expected (%s|%s|%s)", saiSwitchTypeStr, SAI_VALUE_SAI_SWITCH_TYPE_NPU, + SAI_VALUE_SAI_SWITCH_TYPE_POE, SAI_VALUE_SAI_SWITCH_TYPE_PHY); return false; @@ -73,6 +78,10 @@ bool SwitchConfig::parseSwitchType( { switchType = SAI_VS_SWITCH_TYPE_BCM81724; } + else if (st == SAI_VALUE_VS_SWITCH_TYPE_POE_VS) + { + switchType = SAI_VS_SWITCH_TYPE_POE_VS; + } else if (st == SAI_VALUE_VS_SWITCH_TYPE_MLNX2700) { switchType = SAI_VS_SWITCH_TYPE_MLNX2700; @@ -96,6 +105,7 @@ bool SwitchConfig::parseSwitchType( SAI_VALUE_VS_SWITCH_TYPE_BCM81724, SAI_VALUE_VS_SWITCH_TYPE_BCM56850, SAI_VALUE_VS_SWITCH_TYPE_BCM56971B0, + SAI_VALUE_VS_SWITCH_TYPE_POE_VS, SAI_VALUE_VS_SWITCH_TYPE_MLNX2700, SAI_VALUE_VS_SWITCH_TYPE_NVDA_MBF2H536C, SAI_VALUE_VS_SWITCH_TYPE_DPU_SIMU_2P diff --git a/vslib/SwitchConfig.h b/vslib/SwitchConfig.h index 8509eabf3..6e1698680 100644 --- a/vslib/SwitchConfig.h +++ b/vslib/SwitchConfig.h @@ -28,6 +28,8 @@ namespace saivs SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C, + SAI_VS_SWITCH_TYPE_POE_VS, + } sai_vs_switch_type_t; typedef enum _sai_vs_boot_type_t diff --git a/vslib/SwitchPoE.cpp b/vslib/SwitchPoE.cpp new file mode 100644 index 000000000..e8c8c58b4 --- /dev/null +++ b/vslib/SwitchPoE.cpp @@ -0,0 +1,370 @@ +#include "SwitchPoE.h" + +#include "swss/logger.h" +#include "meta/sai_serialize.h" + +using namespace saivs; + +SwitchPoE::SwitchPoE( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config): + SwitchStateBase(switch_id, manager, config) +{ + SWSS_LOG_ENTER(); + + // empty +} + +SwitchPoE::SwitchPoE( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config, + _In_ std::shared_ptr warmBootState): + SwitchStateBase(switch_id, manager, config, warmBootState) +{ + SWSS_LOG_ENTER(); + + // empty +} + +SwitchPoE::~SwitchPoE() +{ + SWSS_LOG_ENTER(); + + // empty +} + +sai_status_t SwitchPoE::set_switch_default_attributes() +{ + SWSS_LOG_ENTER(); + + sai_status_t ret; + + // Fill this with supported SAI_OBJECT_TYPEs + int32_t supported_obj_list[] = { + SAI_OBJECT_TYPE_NULL, + SAI_OBJECT_TYPE_POE_DEVICE, + SAI_OBJECT_TYPE_POE_PSE, + SAI_OBJECT_TYPE_POE_PORT, + }; + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS; + attr.value.u32 = 0; + CHECK_STATUS(set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr)); + + attr.id = SAI_SWITCH_ATTR_WARM_RECOVER; + attr.value.booldata = false; + CHECK_STATUS(set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr)); + + attr.id = SAI_SWITCH_ATTR_TYPE; + attr.value.s32 = SAI_SWITCH_TYPE_POE; + CHECK_STATUS(set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr)); + + // v0.1 + attr.id = SAI_SWITCH_ATTR_FIRMWARE_MAJOR_VERSION; + attr.value.u32 = 0; + CHECK_STATUS(set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr)); + + attr.id = SAI_SWITCH_ATTR_FIRMWARE_MINOR_VERSION; + attr.value.u32 = 1; + CHECK_STATUS(set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr)); + + attr.id = SAI_SWITCH_ATTR_SUPPORTED_OBJECT_TYPE_LIST; + attr.value.s32list.count = sizeof(supported_obj_list) / sizeof(int32_t); + attr.value.s32list.list = supported_obj_list; + ret = set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr); + + return ret; +} + +sai_status_t SwitchPoE::initialize_default_objects( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + CHECK_STATUS(set_switch_default_attributes()); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchPoE::create( + _In_ sai_object_type_t object_type, + _In_ const std::string &serializedObjectId, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + if (object_type == SAI_OBJECT_TYPE_POE_DEVICE) + { + sai_object_id_t object_id; + sai_deserialize_object_id(serializedObjectId, object_id); + return createPoeDevice(object_id, switch_id, attr_count, attr_list); + } + + if (object_type == SAI_OBJECT_TYPE_POE_PORT) + { + sai_object_id_t object_id; + sai_deserialize_object_id(serializedObjectId, object_id); + return createPoePort(object_id, switch_id, attr_count, attr_list); + } + + return create_internal(object_type, serializedObjectId, switch_id, attr_count, attr_list); +} + +sai_status_t SwitchPoE::createPoeDevice( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + auto sid = sai_serialize_object_id(object_id); + + auto power_limit = sai_metadata_get_attr_by_id(SAI_POE_DEVICE_ATTR_POWER_LIMIT_MODE, attr_count, attr_list); + + CHECK_STATUS(create_internal(SAI_OBJECT_TYPE_POE_DEVICE, sid, switch_id, attr_count, attr_list)); + + sai_attribute_t attr; + + /* if not set in create_internal then use default values*/ + if (!power_limit) + { + attr.id = SAI_POE_DEVICE_ATTR_POWER_LIMIT_MODE; + attr.value.u32 = SAI_POE_DEVICE_LIMIT_MODE_CLASS; + CHECK_STATUS(set(SAI_OBJECT_TYPE_POE_DEVICE, object_id, &attr)); + } + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchPoE::createPoePort( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + auto sid = sai_serialize_object_id(object_id); + + auto power_limit = sai_metadata_get_attr_by_id(SAI_POE_PORT_ATTR_POWER_LIMIT, attr_count, attr_list); + auto power_priority = sai_metadata_get_attr_by_id(SAI_POE_PORT_ATTR_POWER_PRIORITY, attr_count, attr_list); + + CHECK_STATUS(create_internal(SAI_OBJECT_TYPE_POE_PORT, sid, switch_id, attr_count, attr_list)); + + sai_attribute_t attr; + + /* default admin state is down as defined in SAI */ + attr.id = SAI_POE_PORT_ATTR_ADMIN_ENABLED_STATE; + attr.value.booldata = false; + CHECK_STATUS(set(SAI_OBJECT_TYPE_POE_PORT, object_id, &attr)); + + /* if not set in create_internal then use default values*/ + if (!power_limit) + { + attr.id = SAI_POE_PORT_ATTR_POWER_LIMIT; + attr.value.u32 = 0; + CHECK_STATUS(set(SAI_OBJECT_TYPE_POE_PORT, object_id, &attr)); + } + if (!power_priority) + { + attr.id = SAI_POE_PORT_ATTR_POWER_PRIORITY; + attr.value.u32 = SAI_POE_PORT_POWER_PRIORITY_TYPE_HIGH; + CHECK_STATUS(set(SAI_OBJECT_TYPE_POE_PORT, object_id, &attr)); + } + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchPoE::refresh_read_only( + _In_ const sai_attr_metadata_t *meta, + _In_ sai_object_id_t object_id) +{ + SWSS_LOG_ENTER(); + + if (meta->objecttype == SAI_OBJECT_TYPE_SWITCH) + { + switch (meta->attrid) + { + case SAI_SWITCH_ATTR_POE_DEVICE_LIST: + return refresh_poe_device_list(meta); + } + } + + sai_attribute_t attr; + attr.id = meta->attrid; + if (meta->objecttype == SAI_OBJECT_TYPE_POE_DEVICE) + { + switch (meta->attrid) + { + case SAI_POE_DEVICE_ATTR_HARDWARE_INFO: + strncpy(attr.value.chardata, "hardware info", sizeof(attr.value.chardata)); + return set(meta->objecttype, object_id, &attr); + case SAI_POE_DEVICE_ATTR_POE_PSE_LIST: + return refresh_poe_pse_list(meta, object_id); + case SAI_POE_DEVICE_ATTR_POE_PORT_LIST: + return refresh_poe_port_list(meta, object_id); + case SAI_POE_DEVICE_ATTR_TOTAL_POWER: + attr.value.u32 = 100; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_DEVICE_ATTR_POWER_CONSUMPTION: + attr.value.u32 = 10000; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_DEVICE_ATTR_VERSION: + strncpy(attr.value.chardata, "version", sizeof(attr.value.chardata)); + return set(meta->objecttype, object_id, &attr); + } + + } + if (meta->objecttype == SAI_OBJECT_TYPE_POE_PSE) + { + switch (meta->attrid) + { + case SAI_POE_PSE_ATTR_TEMPERATURE: + attr.value.u32 = 25; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PSE_ATTR_STATUS: + attr.value.u32 = SAI_POE_PSE_STATUS_TYPE_ACTIVE; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PSE_ATTR_SOFTWARE_VERSION: + strncpy(attr.value.chardata, "software version", sizeof(attr.value.chardata)); + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PSE_ATTR_HARDWARE_VERSION: + strncpy(attr.value.chardata, "hardware version", sizeof(attr.value.chardata)); + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PSE_ATTR_ID: + case SAI_POE_PSE_ATTR_DEVICE_ID: + return SAI_STATUS_SUCCESS; + } + } + if (meta->objecttype == SAI_OBJECT_TYPE_POE_PORT) + { + switch (meta->attrid) + { + case SAI_POE_PORT_ATTR_STANDARD: + attr.value.u32 = SAI_POE_PORT_STANDARD_TYPE_BT_TYPE3; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PORT_ATTR_CONSUMPTION: + /* random values */ + attr.value.portpowerconsumption = (sai_poe_port_power_consumption_t){ + .active_channel=SAI_POE_PORT_ACTIVE_CHANNEL_TYPE_A_AND_B, + .voltage=50000, + .current=200, + .consumption=10000, + .signature_type=SAI_POE_PORT_SIGNATURE_TYPE_DUAL, + .class_method=SAI_POE_PORT_CLASS_METHOD_TYPE_AUTO_CLASS, + .measured_class_a=1, + .assigned_class_a=2, + .measured_class_b=3, + .assigned_class_b=4 + }; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PORT_ATTR_STATUS: + attr.value.u32 = SAI_POE_PORT_STATUS_TYPE_DELIVERING_POWER; + return set(meta->objecttype, object_id, &attr); + case SAI_POE_PORT_ATTR_FRONT_PANEL_ID: + case SAI_POE_PORT_ATTR_DEVICE_ID: + return SAI_STATUS_SUCCESS; + } + } + + auto mmeta = m_meta.lock(); + + if (mmeta) + { + if (mmeta->meta_unittests_enabled()) + { + SWSS_LOG_NOTICE("unittests enabled, SET could be performed on %s, not recalculating", meta->attridname); + + return SAI_STATUS_SUCCESS; + } + } + else + { + SWSS_LOG_WARN("meta pointer expired"); + } + + SWSS_LOG_WARN("need to recalculate RO: %s", meta->attridname); + + return SAI_STATUS_NOT_IMPLEMENTED; +} + +sai_status_t SwitchPoE::refresh_poe_device_list( + _In_ const sai_attr_metadata_t *meta) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + m_poe_device_list.clear(); + + for (const auto& it: m_objectHash.at(SAI_OBJECT_TYPE_POE_DEVICE)) + { + sai_object_id_t device_oid; + sai_deserialize_object_id(it.first, device_oid); + m_poe_device_list.push_back(device_oid); + } + + auto device_count = (uint32_t)m_poe_device_list.size(); + attr.id = SAI_SWITCH_ATTR_POE_DEVICE_LIST; + attr.value.objlist.count = device_count; + attr.value.objlist.list = m_poe_device_list.data(); + + CHECK_STATUS(set(SAI_OBJECT_TYPE_SWITCH, m_switch_id, &attr)); + + SWSS_LOG_NOTICE("refreshed poe device list, current device number: %lu", device_count); + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchPoE::refresh_poe_pse_list( + _In_ const sai_attr_metadata_t *meta, + _In_ sai_object_id_t poe_device_id) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + attr.id = SAI_POE_PSE_ATTR_DEVICE_ID; + attr.value.oid = poe_device_id; + + findObjects(SAI_OBJECT_TYPE_POE_PSE, attr, m_poe_pse_list); + std::sort(m_poe_pse_list.begin(), m_poe_pse_list.end()); + + auto pse_count = (uint32_t)m_poe_pse_list.size(); + + attr.id = SAI_POE_DEVICE_ATTR_POE_PSE_LIST; + attr.value.objlist.count = pse_count; + attr.value.objlist.list = m_poe_pse_list.data(); + + CHECK_STATUS(set(SAI_OBJECT_TYPE_POE_DEVICE, poe_device_id, &attr)); + + SWSS_LOG_NOTICE("refreshed poe pse list, current pse number: %u", pse_count); + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchPoE::refresh_poe_port_list( + _In_ const sai_attr_metadata_t *meta, + _In_ sai_object_id_t poe_device_id) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + attr.id = SAI_POE_PORT_ATTR_DEVICE_ID; + attr.value.oid = poe_device_id; + + findObjects(SAI_OBJECT_TYPE_POE_PORT, attr, m_poe_port_list); + std::sort(m_poe_port_list.begin(), m_poe_port_list.end()); + + auto port_count = (uint32_t)m_poe_port_list.size(); + + attr.id = SAI_POE_DEVICE_ATTR_POE_PORT_LIST; + attr.value.objlist.count = port_count; + attr.value.objlist.list = m_poe_port_list.data(); + + CHECK_STATUS(set(SAI_OBJECT_TYPE_POE_DEVICE, poe_device_id, &attr)); + + SWSS_LOG_NOTICE("refreshed poe port list, current port number: %u", port_count); + return SAI_STATUS_SUCCESS; +} diff --git a/vslib/SwitchPoE.h b/vslib/SwitchPoE.h new file mode 100644 index 000000000..a49773eae --- /dev/null +++ b/vslib/SwitchPoE.h @@ -0,0 +1,71 @@ +#pragma once + +#include "SwitchStateBase.h" + +namespace saivs +{ + class SwitchPoE: + public SwitchStateBase + { + public: + + SwitchPoE( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config); + + SwitchPoE( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config, + _In_ std::shared_ptr warmBootState); + + virtual ~SwitchPoE(); + + virtual sai_status_t create( + _In_ sai_object_type_t object_type, + _In_ const std::string &serializedObjectId, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) override; + + protected: + std::vector m_poe_device_list; + std::vector m_poe_pse_list; + std::vector m_poe_port_list; + + sai_status_t createPoeDevice( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + + sai_status_t createPoePort( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + + virtual sai_status_t refresh_read_only( + _In_ const sai_attr_metadata_t *meta, + _In_ sai_object_id_t object_id) override; + + virtual sai_status_t refresh_poe_device_list( + _In_ const sai_attr_metadata_t *meta) override; + + virtual sai_status_t refresh_poe_pse_list( + _In_ const sai_attr_metadata_t *meta, + _In_ sai_object_id_t poe_device_id); + + virtual sai_status_t refresh_poe_port_list( + _In_ const sai_attr_metadata_t *meta, + _In_ sai_object_id_t poe_device_id); + + public: + virtual sai_status_t set_switch_default_attributes(); + virtual sai_status_t initialize_default_objects( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) override; + + }; +} diff --git a/vslib/SwitchStateBase.cpp b/vslib/SwitchStateBase.cpp index 8fa4d7761..6e73fd62a 100644 --- a/vslib/SwitchStateBase.cpp +++ b/vslib/SwitchStateBase.cpp @@ -2021,6 +2021,26 @@ sai_status_t SwitchStateBase::refresh_bridge_port_list( return SAI_STATUS_NOT_IMPLEMENTED; } +sai_status_t SwitchStateBase::refresh_poe_device_list( + _In_ const sai_attr_metadata_t *meta) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_ERROR("implement in child class"); + + return SAI_STATUS_NOT_IMPLEMENTED; +} + +sai_status_t SwitchStateBase::refresh_port_poe_port_id( + _In_ sai_object_id_t port_id) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_ERROR("implement in child class"); + + return SAI_STATUS_NOT_IMPLEMENTED; +} + sai_status_t SwitchStateBase::refresh_vlan_member_list( _In_ const sai_attr_metadata_t *meta, _In_ sai_object_id_t vlan_id) @@ -2396,6 +2416,9 @@ sai_status_t SwitchStateBase::refresh_read_only( case SAI_SWITCH_ATTR_SUPPORTED_OBJECT_TYPE_LIST: return SAI_STATUS_SUCCESS; + + case SAI_SWITCH_ATTR_POE_DEVICE_LIST: + return refresh_poe_device_list(meta); } } @@ -2436,6 +2459,9 @@ sai_status_t SwitchStateBase::refresh_read_only( case SAI_PORT_ATTR_OPER_SPEED: return refresh_port_oper_speed(object_id); + + case SAI_PORT_ATTR_POE_PORT_ID: + return refresh_port_poe_port_id(object_id); } } diff --git a/vslib/SwitchStateBase.h b/vslib/SwitchStateBase.h index 22e111a34..7e496c7ac 100644 --- a/vslib/SwitchStateBase.h +++ b/vslib/SwitchStateBase.h @@ -148,6 +148,12 @@ namespace saivs _In_ const sai_attr_metadata_t *meta, _In_ sai_object_id_t bridge_id); + virtual sai_status_t refresh_poe_device_list( + _In_ const sai_attr_metadata_t *meta); + + virtual sai_status_t refresh_port_poe_port_id( + _In_ sai_object_id_t port_id); + virtual sai_status_t refresh_vlan_member_list( _In_ const sai_attr_metadata_t *meta, _In_ sai_object_id_t vlan_id); diff --git a/vslib/VirtualSwitchSaiInterface.cpp b/vslib/VirtualSwitchSaiInterface.cpp index d866f5ac1..a1aef423f 100644 --- a/vslib/VirtualSwitchSaiInterface.cpp +++ b/vslib/VirtualSwitchSaiInterface.cpp @@ -10,6 +10,7 @@ #include "meta/Globals.h" #include "SwitchStateBase.h" +#include "SwitchPoE.h" #include "SwitchBCM81724.h" #include "SwitchBCM56850.h" #include "SwitchBCM56971B0.h" @@ -601,6 +602,11 @@ std::shared_ptr VirtualSwitchSaiInterface::init_switch( m_switchStateMap[switch_id] = std::make_shared(switch_id, m_realObjectIdManager, config, warmBootState); break; + case SAI_VS_SWITCH_TYPE_POE_VS: + + m_switchStateMap[switch_id] = std::make_shared(switch_id, m_realObjectIdManager, config, warmBootState); + break; + default: SWSS_LOG_WARN("unknown switch type: %d", config->m_switchType); diff --git a/vslib/saivs.h b/vslib/saivs.h index a68da6e84..cec62ca83 100644 --- a/vslib/saivs.h +++ b/vslib/saivs.h @@ -9,6 +9,7 @@ extern "C" { #define SAI_VALUE_SAI_SWITCH_TYPE_NPU "SAI_SWITCH_TYPE_NPU" #define SAI_VALUE_SAI_SWITCH_TYPE_PHY "SAI_SWITCH_TYPE_PHY" +#define SAI_VALUE_SAI_SWITCH_TYPE_POE "SAI_SWITCH_TYPE_POE" /** * @def SAI_KEY_VS_INTERFACE_LANE_MAP_FILE @@ -92,6 +93,7 @@ extern "C" { #define SAI_VALUE_VS_SWITCH_TYPE_MLNX2700 "SAI_VS_SWITCH_TYPE_MLNX2700" #define SAI_VALUE_VS_SWITCH_TYPE_NVDA_MBF2H536C "SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C" #define SAI_VALUE_VS_SWITCH_TYPE_DPU_SIMU_2P "SAI_VS_SWITCH_TYPE_DPU_SIMU_2P" +#define SAI_VALUE_VS_SWITCH_TYPE_POE_VS "SAI_VS_SWITCH_TYPE_POE_VS" /* * Values for SAI_KEY_BOOT_TYPE (defined in saiswitch.h)