fboss/agent/hw/sai/switch/SaiPortManager.h (195 lines of code) (raw):

/* * Copyright (c) 2004-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #pragma once #include "fboss/agent/hw/gen-cpp2/hardware_stats_types.h" #include "fboss/agent/hw/sai/api/PortApi.h" #include "fboss/agent/hw/sai/store/SaiObjectWithCounters.h" #include "fboss/agent/hw/sai/switch/SaiBridgeManager.h" #include "fboss/agent/hw/sai/switch/SaiMirrorManager.h" #include "fboss/agent/hw/sai/switch/SaiQosMapManager.h" #include "fboss/agent/hw/sai/switch/SaiQueueManager.h" #include "fboss/agent/hw/sai/switch/SaiSamplePacketManager.h" #include "fboss/agent/state/Port.h" #include "fboss/agent/state/PortQueue.h" #include "fboss/agent/state/StateDelta.h" #include "fboss/agent/types.h" #include "folly/container/F14Map.h" #include "folly/container/F14Set.h" namespace facebook::fboss { struct ConcurrentIndices; class SaiManagerTable; class SaiPlatform; class HwPortFb303Stats; class QosPolicy; class SaiStore; using SaiPort = SaiObjectWithCounters<SaiPortTraits>; using SaiPortSerdes = SaiObject<SaiPortSerdesTraits>; using SaiPortConnector = SaiObject<SaiPortConnectorTraits>; /* * Cache port mirror data from sw switch */ struct SaiPortMirrorInfo { std::optional<std::string> ingressMirror; std::optional<std::string> egressMirror; bool samplingMirror; SaiPortMirrorInfo() {} SaiPortMirrorInfo( std::optional<std::string> ingressMirror, std::optional<std::string> egressMirror, bool samplingMirror) : ingressMirror(ingressMirror), egressMirror(egressMirror), samplingMirror(samplingMirror) {} std::optional<std::string> getIngressMirror() { return ingressMirror; } std::optional<std::string> getEgressMirror() { return egressMirror; } bool isMirrorSampled() { return samplingMirror; } }; /* * For Xphy we create system side port, line side port and a port connector * associating these two. The Line side port is used for all subsequent MacSec * programming and it is kept in PortHandle's port, the system side Sai port is * kept in saiPort and the port connector in connector field. */ struct SaiPortHandle { ~SaiPortHandle(); std::shared_ptr<SaiPort> port; std::shared_ptr<SaiPort> sysPort; std::shared_ptr<SaiPortSerdes> serdes; std::shared_ptr<SaiPortConnector> connector; std::shared_ptr<SaiBridgePort> bridgePort; std::vector<SaiQueueHandle*> configuredQueues; std::shared_ptr<SaiSamplePacket> ingressSamplePacket; std::shared_ptr<SaiSamplePacket> egressSamplePacket; SaiQueueHandles queues; SaiPortMirrorInfo mirrorInfo; }; class SaiPortManager { using Handles = folly::F14FastMap<PortID, std::unique_ptr<SaiPortHandle>>; using Stats = folly::F14FastMap<PortID, std::unique_ptr<HwPortFb303Stats>>; public: SaiPortManager( SaiStore* saiStore, SaiManagerTable* managerTable, SaiPlatform* platform, ConcurrentIndices* concurrentIndices_); ~SaiPortManager(); PortSaiId addPort(const std::shared_ptr<Port>& swPort); void removePort(const std::shared_ptr<Port>& swPort); void changePort( const std::shared_ptr<Port>& oldPort, const std::shared_ptr<Port>& newPort); bool createOnlyAttributeChanged( const SaiPortTraits::CreateAttributes& oldAttributes, const SaiPortTraits::CreateAttributes& newAttributes); SaiPortTraits::CreateAttributes attributesFromSwPort( const std::shared_ptr<Port>& swPort, bool lineSide = false) const; SaiPortSerdesTraits::CreateAttributes serdesAttributesFromSwPinConfigs( PortSaiId portSaid, const std::vector<phy::PinConfig>& pinConfigs, const std::shared_ptr<SaiPortSerdes>& serdes); const SaiPortHandle* getPortHandle(PortID swId) const; SaiPortHandle* getPortHandle(PortID swId); const SaiQueueHandle* getQueueHandle( PortID swId, const SaiQueueConfig& saiQueueConfig) const; SaiQueueHandle* getQueueHandle( PortID swId, const SaiQueueConfig& saiQueueConfig); std::map<PortID, HwPortStats> getPortStats() const; void changeQueue( PortID swId, const QueueConfig& oldQueueConfig, const QueueConfig& newQueueConfig); const HwPortFb303Stats* getLastPortStat(PortID port) const; const Stats& getLastPortStats() const { return portStats_; } cfg::PortSpeed getMaxSpeed(PortID port) const; Handles::const_iterator begin() const { return handles_.begin(); } Handles::const_iterator end() const { return handles_.end(); } void setQosPolicy(); void clearQosPolicy(); std::shared_ptr<PortMap> reconstructPortsFromStore() const; std::shared_ptr<Port> swPortFromAttributes( SaiPortTraits::CreateAttributes attributees) const; void updateStats(PortID portID, bool updateWatermarks = false); void clearStats(PortID portID); void programMirrorOnAllPorts( const std::string& mirrorName, MirrorAction action); void addBridgePort(const std::shared_ptr<Port>& port); void changeBridgePort( const std::shared_ptr<Port>& oldPort, const std::shared_ptr<Port>& newPort); bool isUp(PortID portID) const; bool isUp(PortSaiId saiPortId) const; void setPtpTcEnable(bool enable); bool isPtpTcEnabled() const; sai_port_eye_values_list_t getPortEyeValues(PortSaiId saiPortId) const; void enableAfeAdaptiveMode(PortID portId); private: PortSaiId addPortImpl(const std::shared_ptr<Port>& swPort); void addRemovedHandle(PortID portID); void removeRemovedHandleIf(PortID portID); void releasePorts(); void setQosMaps( QosMapSaiId dscpToTc, QosMapSaiId tcToQueue, const folly::F14FastSet<PortID>& ports); void setQosMapsOnAllPorts(QosMapSaiId dscpToTc, QosMapSaiId tcToQueue); const std::vector<sai_stat_id_t>& supportedStats() const; SaiPortHandle* getPortHandleImpl(PortID swId) const; SaiQueueHandle* getQueueHandleImpl( PortID swId, const SaiQueueConfig& saiQueueConfig) const; void loadPortQueues(SaiPortHandle* portHandle); void programSerdes( std::shared_ptr<SaiPort> saiPort, std::shared_ptr<Port> swPort, SaiPortHandle* portHandle); void programSampling( PortID portId, SamplePacketDirection direction, SamplePacketAction action, uint64_t sampleRate, std::optional<cfg::SampleDestination> sampleDestination); void programMirror( PortID portId, MirrorDirection direction, MirrorAction action, std::optional<std::string> mirrorId); void programSamplingMirror( PortID portId, MirrorDirection direction, MirrorAction action, std::optional<std::string> mirrorId); void addMirror(const std::shared_ptr<Port>& swPort); void removeMirror(const std::shared_ptr<Port>& swPort); void addSamplePacket(const std::shared_ptr<Port>& swPort); void removeSamplePacket(const std::shared_ptr<Port>& swPort); void changeMirror( const std::shared_ptr<Port>& oldPort, const std::shared_ptr<Port>& newPort); void changeSamplePacket( const std::shared_ptr<Port>& oldPort, const std::shared_ptr<Port>& newPort); bool checkPortSerdesAttributes( const SaiPortSerdesTraits::CreateAttributes& fromStore, const SaiPortSerdesTraits::CreateAttributes& fromSwPort); void programMacsec( const std::shared_ptr<Port>& oldPort, const std::shared_ptr<Port>& newPort); void resetSamplePacket(SaiPortHandle* portHandle); SaiStore* saiStore_; SaiManagerTable* managerTable_; SaiPlatform* platform_; // Pure virtual function cannot be called in destructor. Thus, cache it. bool removePortsAtExit_; ConcurrentIndices* concurrentIndices_; Handles handles_; // on some platforms port can not be removed freely. on such platforms // retain removed port handle so it does not invoke remove port api. Handles removedHandles_; Stats portStats_; std::shared_ptr<SaiQosMap> globalDscpToTcQosMap_; std::shared_ptr<SaiQosMap> globalTcToQueueQosMap_; std::optional<SaiPortTraits::Attributes::PtpMode> getPtpMode() const; }; } // namespace facebook::fboss