|  | /* | 
|  | // Copyright (c) 2018 Intel Corporation | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  | */ | 
|  |  | 
|  | #pragma once | 
|  | #include "channel_layer.hpp" | 
|  | #include "ipmid/api-types.hpp" | 
|  |  | 
|  | #include <boost/interprocess/sync/file_lock.hpp> | 
|  | #include <boost/interprocess/sync/named_recursive_mutex.hpp> | 
|  | #include <nlohmann/json.hpp> | 
|  | #include <sdbusplus/bus.hpp> | 
|  |  | 
|  | #include <cstdint> | 
|  | #include <ctime> | 
|  | #include <variant> | 
|  |  | 
|  | namespace ipmi | 
|  | { | 
|  |  | 
|  | using Json = nlohmann::json; | 
|  |  | 
|  | using DbusVariant = std::variant<std::vector<std::string>, std::string, bool>; | 
|  |  | 
|  | using DbusChObjProperties = std::vector<std::pair<std::string, DbusVariant>>; | 
|  |  | 
|  | static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex"; | 
|  | static constexpr const char* ipmiChMutexCleanupLockFile = | 
|  | "/run/ipmi/ipmi_channel_mutex_cleanup"; | 
|  |  | 
|  | /** @struct ChannelAccessData | 
|  | * | 
|  | *  Structure to store both non-volatile and volatile channel access information | 
|  | *  as used by IPMI specification (refer spec sec 22.22 to 22.24) | 
|  | */ | 
|  | struct ChannelAccessData | 
|  | { | 
|  | ChannelAccess chNonVolatileData; | 
|  | ChannelAccess chVolatileData; | 
|  | }; | 
|  |  | 
|  | /** @struct ChannelProperties | 
|  | * | 
|  | *  Structure for channel information - base structure to get all information | 
|  | * about the channel.(refer spec sec 22.22 to 22.24) | 
|  | */ | 
|  | struct ChannelProperties | 
|  | { | 
|  | std::string chName; | 
|  | uint8_t chID; | 
|  | bool isChValid; | 
|  | uint8_t activeSessCount; | 
|  | ChannelInfo chInfo; | 
|  | ChannelAccessData chAccess; | 
|  | size_t maxTransferSize; | 
|  | bool isManagementNIC; | 
|  | }; | 
|  |  | 
|  | class ChannelConfig; | 
|  |  | 
|  | ChannelConfig& getChannelConfigObject(); | 
|  |  | 
|  | class ChannelConfig | 
|  | { | 
|  | public: | 
|  | ChannelConfig(const ChannelConfig&) = delete; | 
|  | ChannelConfig& operator=(const ChannelConfig&) = delete; | 
|  | ChannelConfig(ChannelConfig&&) = delete; | 
|  | ChannelConfig& operator=(ChannelConfig&&) = delete; | 
|  |  | 
|  | ~ChannelConfig(); | 
|  | ChannelConfig(); | 
|  |  | 
|  | /** @brief determines valid channel | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | * | 
|  | *  @return true if valid, false otherwise | 
|  | */ | 
|  | bool isValidChannel(const uint8_t chNum); | 
|  |  | 
|  | /** @brief determines valid authentication type | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[in] authType - authentication type | 
|  | * | 
|  | *  @return true if valid, false otherwise | 
|  | */ | 
|  | bool isValidAuthType(const uint8_t chNum, const EAuthType& authType); | 
|  |  | 
|  | /** @brief function to get channel name from channel number | 
|  | * | 
|  | *  @param[in] chNum - channel number index | 
|  | * | 
|  | *  @return network channel interface name | 
|  | */ | 
|  | std::string getChannelName(const uint8_t chNum); | 
|  |  | 
|  | /** @brief function to get channel number from channel name | 
|  | * | 
|  | *  @param[in] chName - channel name | 
|  | * | 
|  | *  @return network channel interface number | 
|  | */ | 
|  |  | 
|  | uint8_t getChannelByName(const std::string& chName) | 
|  | { | 
|  | return convertToChannelNumberFromChannelName(chName); | 
|  | } | 
|  |  | 
|  | /** @brief determines supported session type of a channel | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | * | 
|  | *  @return EChannelSessSupported - supported session type | 
|  | */ | 
|  | EChannelSessSupported getChannelSessionSupport(const uint8_t chNum); | 
|  |  | 
|  | /** @brief determines number of active sessions on a channel | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | * | 
|  | *  @return numer of active sessions | 
|  | */ | 
|  | int getChannelActiveSessions(const uint8_t chNum); | 
|  |  | 
|  | /** @brief determines maximum transfer size for a channel | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | * | 
|  | *  @return maximum bytes that can be transferred on this channel | 
|  | */ | 
|  | size_t getChannelMaxTransferSize(uint8_t chNum); | 
|  |  | 
|  | /** @brief provides channel info details | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[out] chInfo - channel info details | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo); | 
|  |  | 
|  | /** @brief provides channel access data | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[out] chAccessData - channel access data | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc getChannelAccessData(const uint8_t chNum, ChannelAccess& chAccessData); | 
|  |  | 
|  | /** @brief to set channel access data | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[in] chAccessData - channel access data | 
|  | *  @param[in] setFlag - flag to indicate updatable fields | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc setChannelAccessData(const uint8_t chNum, | 
|  | const ChannelAccess& chAccessData, | 
|  | const uint8_t setFlag); | 
|  |  | 
|  | /** @brief to get channel access data persistent data | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[out] chAccessData - channel access data | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc getChannelAccessPersistData(const uint8_t chNum, | 
|  | ChannelAccess& chAccessData); | 
|  |  | 
|  | /** @brief to set channel access data persistent data | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[in] chAccessData - channel access data | 
|  | *  @param[in] setFlag - flag to indicate updatable fields | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc setChannelAccessPersistData(const uint8_t chNum, | 
|  | const ChannelAccess& chAccessData, | 
|  | const uint8_t setFlag); | 
|  |  | 
|  | /** @brief provides supported authentication type for the channel | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[out] authTypeSupported - supported authentication type | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc getChannelAuthTypeSupported(const uint8_t chNum, | 
|  | uint8_t& authTypeSupported); | 
|  |  | 
|  | /** @brief provides enabled authentication type for the channel | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[in] priv - privilege | 
|  | *  @param[out] authType - enabled authentication type | 
|  | * | 
|  | *  @return ccSuccess for success, others for failure. | 
|  | */ | 
|  | Cc getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv, | 
|  | EAuthType& authType); | 
|  |  | 
|  | /** @brief conver to channel privilege from system privilege | 
|  | * | 
|  | *  @param[in] value - privilege value | 
|  | * | 
|  | *  @return Channel privilege | 
|  | */ | 
|  | CommandPrivilege convertToPrivLimitIndex(const std::string& value); | 
|  |  | 
|  | /** @brief function to write persistent channel configuration to config file | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int writeChannelPersistData(); | 
|  |  | 
|  | /** @brief function to write volatile channel configuration to config file | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int writeChannelVolatileData(); | 
|  |  | 
|  | /** @brief Returns the IPMI channel ID authorized to push IPMI privilege | 
|  | * changes to phosphor-user-manager. Any channel access changes made on | 
|  | * any other channel are ignored. | 
|  | * | 
|  | *  @return IPMI channel ID as defined in channel_config.json | 
|  | */ | 
|  | uint8_t getManagementNICID(); | 
|  |  | 
|  | private: | 
|  | uint32_t signalFlag = 0; | 
|  | std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{ | 
|  | nullptr}; | 
|  | std::array<ChannelProperties, maxIpmiChannels> channelData; | 
|  | std::time_t nvFileLastUpdatedTime; | 
|  | std::time_t voltFileLastUpdatedTime; | 
|  | boost::interprocess::file_lock mutexCleanupLock; | 
|  | sdbusplus::bus_t bus; | 
|  | bool signalHndlrObjectState = false; | 
|  | boost::interprocess::file_lock sigHndlrLock; | 
|  |  | 
|  | /** @brief function to initialize persistent channel configuration | 
|  | * | 
|  | */ | 
|  | void initChannelPersistData(); | 
|  |  | 
|  | /** @brief function to set default channel configuration based on channel | 
|  | * number | 
|  | * | 
|  | *  @param[in] chNum - channel number | 
|  | *  @param[in] chName - channel name | 
|  | */ | 
|  | void setDefaultChannelConfig(const uint8_t chNum, | 
|  | const std::string& chName); | 
|  |  | 
|  | /** @brief function to load all channel configuration | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int loadChannelConfig(); | 
|  |  | 
|  | /** @brief function to read persistent channel data | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int readChannelPersistData(); | 
|  |  | 
|  | /** @brief function to read volatile channel data | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int readChannelVolatileData(); | 
|  |  | 
|  | /** @brief function to check and reload persistent channel data | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int checkAndReloadNVData(); | 
|  |  | 
|  | /** @brief function to check and reload volatile channel data | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int checkAndReloadVolatileData(); | 
|  |  | 
|  | /** @brief function to sync channel privilege with system network channel | 
|  | * privilege | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int syncNetworkChannelConfig(); | 
|  |  | 
|  | /** @brief function to set D-Bus property value | 
|  | * | 
|  | *  @param[in] service - service name | 
|  | *  @param[in] objPath - object path | 
|  | *  @param[in] interface - interface | 
|  | *  @param[in] property - property name | 
|  | *  @param[in] value - property value | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int setDbusProperty(const std::string& service, const std::string& objPath, | 
|  | const std::string& interface, | 
|  | const std::string& property, const DbusVariant& value); | 
|  |  | 
|  | /** @brief function to read json config file | 
|  | * | 
|  | *  @param[in] configFile - configuration file name | 
|  | * | 
|  | *  @return Json object | 
|  | */ | 
|  | Json readJsonFile(const std::string& configFile); | 
|  |  | 
|  | /** @brief function to write json config file | 
|  | * | 
|  | *  @param[in] configFile - configuration file name | 
|  | *  @param[in] jsonData - json object | 
|  | * | 
|  | *  @return 0 for success, -errno for failure. | 
|  | */ | 
|  | int writeJsonFile(const std::string& configFile, const Json& jsonData); | 
|  |  | 
|  | /** @brief function to convert system access mode to Channel access mode | 
|  | * type | 
|  | * | 
|  | *  @param[in] mode - access mode in string | 
|  | * | 
|  | *  @return Channel access mode. | 
|  | */ | 
|  | EChannelAccessMode convertToAccessModeIndex(const std::string& mode); | 
|  |  | 
|  | /** @brief function to convert access mode value to string | 
|  | * | 
|  | *  @param[in] value - acess mode value | 
|  | * | 
|  | *  @return access mode in string | 
|  | */ | 
|  | std::string convertToAccessModeString(const uint8_t value); | 
|  |  | 
|  | /** @brief function to convert privilege value to string | 
|  | * | 
|  | *  @param[in] value - privilege value | 
|  | * | 
|  | *  @return privilege in string | 
|  | */ | 
|  | std::string convertToPrivLimitString(const uint8_t value); | 
|  |  | 
|  | /** @brief function to convert session support string to value type | 
|  | * | 
|  | *  @param[in] value - session support type in string | 
|  | * | 
|  | *  @return support session type | 
|  | */ | 
|  | EChannelSessSupported convertToSessionSupportIndex( | 
|  | const std::string& value); | 
|  |  | 
|  | /** @brief function to convert medium type string to value type | 
|  | * | 
|  | *  @param[in] value - medium type in string | 
|  | * | 
|  | *  @return channel medium type | 
|  | */ | 
|  | EChannelMediumType convertToMediumTypeIndex(const std::string& value); | 
|  |  | 
|  | /** @brief function to convert protocol type string to value type | 
|  | * | 
|  | *  @param[in] value - protocol type in string | 
|  | * | 
|  | *  @return channel protocol  type | 
|  | */ | 
|  | EChannelProtocolType convertToProtocolTypeIndex(const std::string& value); | 
|  |  | 
|  | /** @brief function to convert channel name to the IPMI channel number. | 
|  | * | 
|  | *  @param[in] chName - the channel name defined in the JSON input file | 
|  | *  (i.e. LAN1) | 
|  | * | 
|  | *  @return IPMI channel number | 
|  | */ | 
|  | int convertToChannelNumberFromChannelName(const std::string& chName); | 
|  |  | 
|  | /** @brief function to handle Channel access property update through the | 
|  | * D-Bus handler. | 
|  | * | 
|  | *  @param[in] path - D-Bus path to the network element (i.e. eth0) | 
|  | *  @param[in] chProperties - D-Bus channel properties | 
|  | */ | 
|  | void processChAccessPropChange(const std::string& path, | 
|  | const DbusChObjProperties& chProperties); | 
|  |  | 
|  | /** @brief function to retrieve last modification time for the named file | 
|  | * | 
|  | *  @param[in] fileName - the name of the file for which to acquire | 
|  | *  timestamp data | 
|  | * | 
|  | *  @return time the file was last modified | 
|  | */ | 
|  | std::time_t getUpdatedFileTime(const std::string& fileName); | 
|  |  | 
|  | /** @brief function to convert the DBus path to a network channel name | 
|  | * | 
|  | *  @param[in] path - The DBus path to the device | 
|  | * | 
|  | *  @return network channel name (i.e. eth0) | 
|  | */ | 
|  | std::string getChannelNameFromPath(const std::string& path); | 
|  | }; | 
|  |  | 
|  | } // namespace ipmi |