1 /* 2 // Copyright (c) 2018 Intel Corporation 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 */ 16 17 #pragma once 18 #include "channel_layer.hpp" 19 #include "ipmid/api-types.hpp" 20 21 #include <boost/interprocess/sync/file_lock.hpp> 22 #include <boost/interprocess/sync/named_recursive_mutex.hpp> 23 #include <nlohmann/json.hpp> 24 #include <sdbusplus/bus.hpp> 25 26 #include <cstdint> 27 #include <ctime> 28 #include <variant> 29 30 namespace ipmi 31 { 32 33 using Json = nlohmann::json; 34 35 using DbusVariant = std::variant<std::vector<std::string>, std::string, bool>; 36 37 using DbusChObjProperties = std::vector<std::pair<std::string, DbusVariant>>; 38 39 static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex"; 40 static constexpr const char* ipmiChMutexCleanupLockFile = 41 "/var/lib/ipmi/ipmi_channel_mutex_cleanup"; 42 43 /** @struct ChannelAccessData 44 * 45 * Structure to store both non-volatile and volatile channel access information 46 * as used by IPMI specification (refer spec sec 22.22 to 22.24) 47 */ 48 struct ChannelAccessData 49 { 50 ChannelAccess chNonVolatileData; 51 ChannelAccess chVolatileData; 52 }; 53 54 /** @struct ChannelProperties 55 * 56 * Structure for channel information - base structure to get all information 57 * about the channel.(refer spec sec 22.22 to 22.24) 58 */ 59 struct ChannelProperties 60 { 61 std::string chName; 62 uint8_t chID; 63 bool isChValid; 64 uint8_t activeSessCount; 65 ChannelInfo chInfo; 66 ChannelAccessData chAccess; 67 size_t maxTransferSize; 68 bool isManagementNIC; 69 }; 70 71 class ChannelConfig; 72 73 ChannelConfig& getChannelConfigObject(); 74 75 class ChannelConfig 76 { 77 public: 78 ChannelConfig(const ChannelConfig&) = delete; 79 ChannelConfig& operator=(const ChannelConfig&) = delete; 80 ChannelConfig(ChannelConfig&&) = delete; 81 ChannelConfig& operator=(ChannelConfig&&) = delete; 82 83 ~ChannelConfig(); 84 ChannelConfig(); 85 86 /** @brief determines valid channel 87 * 88 * @param[in] chNum - channel number 89 * 90 * @return true if valid, false otherwise 91 */ 92 bool isValidChannel(const uint8_t chNum); 93 94 /** @brief determines valid authentication type 95 * 96 * @param[in] chNum - channel number 97 * @param[in] authType - authentication type 98 * 99 * @return true if valid, false otherwise 100 */ 101 bool isValidAuthType(const uint8_t chNum, const EAuthType& authType); 102 103 /** @brief function to get channel name from channel number 104 * 105 * @param[in] chNum - channel number index 106 * 107 * @return network channel interface name 108 */ 109 std::string getChannelName(const uint8_t chNum); 110 111 /** @brief function to get channel number from channel name 112 * 113 * @param[in] chName - channel name 114 * 115 * @return network channel interface number 116 */ 117 118 uint8_t getChannelByName(const std::string& chName) 119 { 120 return convertToChannelNumberFromChannelName(chName); 121 } 122 123 /** @brief determines supported session type of a channel 124 * 125 * @param[in] chNum - channel number 126 * 127 * @return EChannelSessSupported - supported session type 128 */ 129 EChannelSessSupported getChannelSessionSupport(const uint8_t chNum); 130 131 /** @brief determines number of active sessions on a channel 132 * 133 * @param[in] chNum - channel number 134 * 135 * @return numer of active sessions 136 */ 137 int getChannelActiveSessions(const uint8_t chNum); 138 139 /** @brief determines maximum transfer size for a channel 140 * 141 * @param[in] chNum - channel number 142 * 143 * @return maximum bytes that can be transferred on this channel 144 */ 145 size_t getChannelMaxTransferSize(uint8_t chNum); 146 147 /** @brief provides channel info details 148 * 149 * @param[in] chNum - channel number 150 * @param[out] chInfo - channel info details 151 * 152 * @return ccSuccess for success, others for failure. 153 */ 154 Cc getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo); 155 156 /** @brief provides channel access data 157 * 158 * @param[in] chNum - channel number 159 * @param[out] chAccessData - channel access data 160 * 161 * @return ccSuccess for success, others for failure. 162 */ 163 Cc getChannelAccessData(const uint8_t chNum, ChannelAccess& chAccessData); 164 165 /** @brief to set channel access data 166 * 167 * @param[in] chNum - channel number 168 * @param[in] chAccessData - channel access data 169 * @param[in] setFlag - flag to indicate updatable fields 170 * 171 * @return ccSuccess for success, others for failure. 172 */ 173 Cc setChannelAccessData(const uint8_t chNum, 174 const ChannelAccess& chAccessData, 175 const uint8_t setFlag); 176 177 /** @brief to get channel access data persistent data 178 * 179 * @param[in] chNum - channel number 180 * @param[out] chAccessData - channel access data 181 * 182 * @return ccSuccess for success, others for failure. 183 */ 184 Cc getChannelAccessPersistData(const uint8_t chNum, 185 ChannelAccess& chAccessData); 186 187 /** @brief to set channel access data persistent data 188 * 189 * @param[in] chNum - channel number 190 * @param[in] chAccessData - channel access data 191 * @param[in] setFlag - flag to indicate updatable fields 192 * 193 * @return ccSuccess for success, others for failure. 194 */ 195 Cc setChannelAccessPersistData(const uint8_t chNum, 196 const ChannelAccess& chAccessData, 197 const uint8_t setFlag); 198 199 /** @brief provides supported authentication type for the channel 200 * 201 * @param[in] chNum - channel number 202 * @param[out] authTypeSupported - supported authentication type 203 * 204 * @return ccSuccess for success, others for failure. 205 */ 206 Cc getChannelAuthTypeSupported(const uint8_t chNum, 207 uint8_t& authTypeSupported); 208 209 /** @brief provides enabled authentication type for the channel 210 * 211 * @param[in] chNum - channel number 212 * @param[in] priv - privilege 213 * @param[out] authType - enabled authentication type 214 * 215 * @return ccSuccess for success, others for failure. 216 */ 217 Cc getChannelEnabledAuthType(const uint8_t chNum, const uint8_t priv, 218 EAuthType& authType); 219 220 /** @brief conver to channel privilege from system privilege 221 * 222 * @param[in] value - privilege value 223 * 224 * @return Channel privilege 225 */ 226 CommandPrivilege convertToPrivLimitIndex(const std::string& value); 227 228 /** @brief function to write persistent channel configuration to config file 229 * 230 * @return 0 for success, -errno for failure. 231 */ 232 int writeChannelPersistData(); 233 234 /** @brief function to write volatile channel configuration to config file 235 * 236 * @return 0 for success, -errno for failure. 237 */ 238 int writeChannelVolatileData(); 239 240 /** @brief Returns the IPMI channel ID authorized to push IPMI privilege 241 * changes to phosphor-user-manager. Any channel access changes made on 242 * any other channel are ignored. 243 * 244 * @return IPMI channel ID as defined in channel_config.json 245 */ 246 uint8_t getManagementNICID(); 247 248 private: 249 uint32_t signalFlag = 0; 250 std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{ 251 nullptr}; 252 std::array<ChannelProperties, maxIpmiChannels> channelData; 253 std::time_t nvFileLastUpdatedTime; 254 std::time_t voltFileLastUpdatedTime; 255 boost::interprocess::file_lock mutexCleanupLock; 256 sdbusplus::bus_t bus; 257 bool signalHndlrObjectState = false; 258 boost::interprocess::file_lock sigHndlrLock; 259 260 /** @brief function to initialize persistent channel configuration 261 * 262 */ 263 void initChannelPersistData(); 264 265 /** @brief function to set default channel configuration based on channel 266 * number 267 * 268 * @param[in] chNum - channel number 269 * @param[in] chName - channel name 270 */ 271 void setDefaultChannelConfig(const uint8_t chNum, 272 const std::string& chName); 273 274 /** @brief function to load all channel configuration 275 * 276 * @return 0 for success, -errno for failure. 277 */ 278 int loadChannelConfig(); 279 280 /** @brief function to read persistent channel data 281 * 282 * @return 0 for success, -errno for failure. 283 */ 284 int readChannelPersistData(); 285 286 /** @brief function to read volatile channel data 287 * 288 * @return 0 for success, -errno for failure. 289 */ 290 int readChannelVolatileData(); 291 292 /** @brief function to check and reload persistent channel data 293 * 294 * @return 0 for success, -errno for failure. 295 */ 296 int checkAndReloadNVData(); 297 298 /** @brief function to check and reload volatile channel data 299 * 300 * @return 0 for success, -errno for failure. 301 */ 302 int checkAndReloadVolatileData(); 303 304 /** @brief function to sync channel privilege with system network channel 305 * privilege 306 * 307 * @return 0 for success, -errno for failure. 308 */ 309 int syncNetworkChannelConfig(); 310 311 /** @brief function to set D-Bus property value 312 * 313 * @param[in] service - service name 314 * @param[in] objPath - object path 315 * @param[in] interface - interface 316 * @param[in] property - property name 317 * @param[in] value - property value 318 * 319 * @return 0 for success, -errno for failure. 320 */ 321 int setDbusProperty(const std::string& service, const std::string& objPath, 322 const std::string& interface, 323 const std::string& property, const DbusVariant& value); 324 325 /** @brief function to get D-Bus property value 326 * 327 * @param[in] service - service name 328 * @param[in] objPath - object path 329 * @param[in] interface - interface 330 * @param[in] property - property name 331 * @param[out] value - property value 332 * 333 * @return 0 for success, -errno for failure. 334 */ 335 int getDbusProperty(const std::string& service, const std::string& objPath, 336 const std::string& interface, 337 const std::string& property, DbusVariant& value); 338 339 /** @brief function to read json config file 340 * 341 * @param[in] configFile - configuration file name 342 * 343 * @return Json object 344 */ 345 Json readJsonFile(const std::string& configFile); 346 347 /** @brief function to write json config file 348 * 349 * @param[in] configFile - configuration file name 350 * @param[in] jsonData - json object 351 * 352 * @return 0 for success, -errno for failure. 353 */ 354 int writeJsonFile(const std::string& configFile, const Json& jsonData); 355 356 /** @brief function to convert system access mode to Channel access mode 357 * type 358 * 359 * @param[in] mode - access mode in string 360 * 361 * @return Channel access mode. 362 */ 363 EChannelAccessMode convertToAccessModeIndex(const std::string& mode); 364 365 /** @brief function to convert access mode value to string 366 * 367 * @param[in] value - acess mode value 368 * 369 * @return access mode in string 370 */ 371 std::string convertToAccessModeString(const uint8_t value); 372 373 /** @brief function to convert privilege value to string 374 * 375 * @param[in] value - privilege value 376 * 377 * @return privilege in string 378 */ 379 std::string convertToPrivLimitString(const uint8_t value); 380 381 /** @brief function to convert session support string to value type 382 * 383 * @param[in] value - session support type in string 384 * 385 * @return support session type 386 */ 387 EChannelSessSupported 388 convertToSessionSupportIndex(const std::string& value); 389 390 /** @brief function to convert medium type string to value type 391 * 392 * @param[in] value - medium type in string 393 * 394 * @return channel medium type 395 */ 396 EChannelMediumType convertToMediumTypeIndex(const std::string& value); 397 398 /** @brief function to convert protocol type string to value type 399 * 400 * @param[in] value - protocol type in string 401 * 402 * @return channel protocol type 403 */ 404 EChannelProtocolType convertToProtocolTypeIndex(const std::string& value); 405 406 /** @brief function to convert channel name to the IPMI channel number. 407 * 408 * @param[in] chName - the channel name defined in the JSON input file 409 * (i.e. LAN1) 410 * 411 * @return IPMI channel number 412 */ 413 int convertToChannelNumberFromChannelName(const std::string& chName); 414 415 /** @brief function to handle Channel access property update through the 416 * D-Bus handler. 417 * 418 * @param[in] path - D-Bus path to the network element (i.e. eth0) 419 * @param[in] chProperties - D-Bus channel properties 420 */ 421 void processChAccessPropChange(const std::string& path, 422 const DbusChObjProperties& chProperties); 423 424 /** @brief function to retrieve last modification time for the named file 425 * 426 * @param[in] fileName - the name of the file for which to acquire 427 * timestamp data 428 * 429 * @return time the file was last modified 430 */ 431 std::time_t getUpdatedFileTime(const std::string& fileName); 432 433 /** @brief function to convert the DBus path to a network channel name 434 * 435 * @param[in] path - The DBus path to the device 436 * 437 * @return network channel name (i.e. eth0) 438 */ 439 std::string getChannelNameFromPath(const std::string& path); 440 }; 441 442 } // namespace ipmi 443