diff --git a/vslib/SwitchStateBase.cpp b/vslib/SwitchStateBase.cpp index 02aa7c3ed..a9171bdff 100644 --- a/vslib/SwitchStateBase.cpp +++ b/vslib/SwitchStateBase.cpp @@ -4,6 +4,7 @@ #include "meta/sai_serialize.h" #include +#include #include @@ -1120,7 +1121,14 @@ sai_status_t SwitchStateBase::create_ports() return SAI_STATUS_FAILURE; } - auto& lanesVector = map->getLaneVector(); + auto lanesVector = map->getLaneVector(); + + if (m_switchConfig->m_useTapDevice) + { + SWSS_LOG_DEBUG("Check available lane"); + + CHECK_STATUS(filter_available_lanes(lanesVector)); + } uint32_t port_count = (uint32_t)lanesVector.size(); @@ -2939,6 +2947,49 @@ sai_status_t SwitchStateBase::initialize_voq_switch_objects( return SAI_STATUS_SUCCESS; } +sai_status_t SwitchStateBase::filter_available_lanes( + _Inout_ std::vector> &lanes_vector) +{ + SWSS_LOG_ENTER(); + + auto lanes = lanes_vector.begin(); + + while (lanes != lanes_vector.end()) + { + bool available_lane = false; + + for (auto lane: *lanes) + { + std::string ifname = m_switchConfig->m_laneMap->getInterfaceFromLaneNumber(lane); + std::string path = std::string("/sys/class/net/") + ifname + "/operstate"; + + if (access(path.c_str(), F_OK) != 0) + { + SWSS_LOG_WARN("Port %s isn't available", ifname.c_str()); + + available_lane &= false; + + break; + } + else + { + available_lane = true; + } + } + + if (!available_lane) + { + lanes = lanes_vector.erase(lanes); + } + else + { + lanes++; + } + } + + return SAI_STATUS_SUCCESS; +} + sai_status_t SwitchStateBase::create_system_ports( _In_ int32_t voq_switch_id, _In_ uint32_t sys_port_count, diff --git a/vslib/SwitchStateBase.h b/vslib/SwitchStateBase.h index 666c106f0..4ddca8fb3 100644 --- a/vslib/SwitchStateBase.h +++ b/vslib/SwitchStateBase.h @@ -98,6 +98,9 @@ namespace saivs _In_ sai_switch_attr_t acl_resource, _In_ int max_count); + sai_status_t filter_available_lanes( + _Inout_ std::vector> &lanes_vector); + sai_status_t create_system_ports( _In_ int32_t voq_switch_id, _In_ uint32_t sys_port_count,