blob: 50505aa87a5ca0816bb391cb2575855b50445555 [file] [log] [blame]
AppaRao Puli071f3f22018-05-24 16:45:30 +05301/*
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#include "channel_mgmt.hpp"
18
19#include "apphandler.hpp"
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070020#include "user_layer.hpp"
AppaRao Puli071f3f22018-05-24 16:45:30 +053021
Johnathan Mantey0a2abc82021-02-18 12:39:12 -080022#include <ifaddrs.h>
AppaRao Puli071f3f22018-05-24 16:45:30 +053023#include <sys/stat.h>
Johnathan Mantey0a2abc82021-02-18 12:39:12 -080024#include <sys/types.h>
AppaRao Puli071f3f22018-05-24 16:45:30 +053025#include <unistd.h>
26
27#include <boost/interprocess/sync/scoped_lock.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050028#include <phosphor-logging/log.hpp>
29#include <sdbusplus/bus/match.hpp>
30#include <sdbusplus/server/object.hpp>
31
AppaRao Puli071f3f22018-05-24 16:45:30 +053032#include <cerrno>
AppaRao Puli9613ed72018-09-01 23:46:44 +053033#include <exception>
Patrick Williams3d8d7932022-06-16 12:01:28 -050034#include <filesystem>
AppaRao Puli071f3f22018-05-24 16:45:30 +053035#include <fstream>
AppaRao Puli071f3f22018-05-24 16:45:30 +053036#include <unordered_map>
37
38namespace ipmi
39{
40
41using namespace phosphor::logging;
42
43static constexpr const char* channelAccessDefaultFilename =
44 "/usr/share/ipmi-providers/channel_access.json";
45static constexpr const char* channelConfigDefaultFilename =
46 "/usr/share/ipmi-providers/channel_config.json";
47static constexpr const char* channelNvDataFilename =
48 "/var/lib/ipmi/channel_access_nv.json";
49static constexpr const char* channelVolatileDataFilename =
50 "/run/ipmi/channel_access_volatile.json";
51
AppaRao Puli9613ed72018-09-01 23:46:44 +053052// TODO: Get the service name dynamically..
53static constexpr const char* networkIntfServiceName =
54 "xyz.openbmc_project.Network";
55static constexpr const char* networkIntfObjectBasePath =
56 "/xyz/openbmc_project/network";
57static constexpr const char* networkChConfigIntfName =
58 "xyz.openbmc_project.Channel.ChannelAccess";
59static constexpr const char* privilegePropertyString = "MaxPrivilege";
60static constexpr const char* dBusPropertiesInterface =
61 "org.freedesktop.DBus.Properties";
62static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
Willy Tuac05aa12021-11-16 21:15:58 -080063static constexpr const char* interfaceAddedSignal = "InterfacesAdded";
64static constexpr const char* interfaceRemovedSignal = "InterfacesRemoved";
AppaRao Puli9613ed72018-09-01 23:46:44 +053065
AppaRao Puli071f3f22018-05-24 16:45:30 +053066// STRING DEFINES: Should sync with key's in JSON
67static constexpr const char* nameString = "name";
68static constexpr const char* isValidString = "is_valid";
69static constexpr const char* activeSessionsString = "active_sessions";
Vernon Mauery58317122018-11-28 11:02:43 -080070static constexpr const char* maxTransferSizeString = "max_transfer_size";
AppaRao Puli071f3f22018-05-24 16:45:30 +053071static constexpr const char* channelInfoString = "channel_info";
72static constexpr const char* mediumTypeString = "medium_type";
73static constexpr const char* protocolTypeString = "protocol_type";
74static constexpr const char* sessionSupportedString = "session_supported";
75static constexpr const char* isIpmiString = "is_ipmi";
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070076static constexpr const char* isManagementNIC = "is_management_nic";
AppaRao Puli071f3f22018-05-24 16:45:30 +053077static constexpr const char* authTypeSupportedString = "auth_type_supported";
78static constexpr const char* accessModeString = "access_mode";
79static constexpr const char* userAuthDisabledString = "user_auth_disabled";
80static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
81static constexpr const char* alertingDisabledString = "alerting_disabled";
82static constexpr const char* privLimitString = "priv_limit";
83static constexpr const char* authTypeEnabledString = "auth_type_enabled";
84
85// Default values
86static constexpr const char* defaultChannelName = "RESERVED";
87static constexpr const uint8_t defaultMediumType =
88 static_cast<uint8_t>(EChannelMediumType::reserved);
89static constexpr const uint8_t defaultProtocolType =
90 static_cast<uint8_t>(EChannelProtocolType::reserved);
91static constexpr const uint8_t defaultSessionSupported =
92 static_cast<uint8_t>(EChannelSessSupported::none);
93static constexpr const uint8_t defaultAuthType =
94 static_cast<uint8_t>(EAuthType::none);
95static constexpr const bool defaultIsIpmiState = false;
Vernon Mauery58317122018-11-28 11:02:43 -080096static constexpr size_t smallChannelSize = 64;
AppaRao Puli071f3f22018-05-24 16:45:30 +053097
Lei YU4b0ddb62019-01-25 16:43:50 +080098std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
99 __attribute__((init_priority(101)));
AppaRao Puli9613ed72018-09-01 23:46:44 +0530100
Willy Tuac05aa12021-11-16 21:15:58 -0800101std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
102 __attribute__((init_priority(101)));
103
104std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
105 __attribute__((init_priority(101)));
106
AppaRao Puli071f3f22018-05-24 16:45:30 +0530107// String mappings use in JSON config file
108static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
109 {"reserved", EChannelMediumType::reserved},
110 {"ipmb", EChannelMediumType::ipmb},
111 {"icmb-v1.0", EChannelMediumType::icmbV10},
112 {"icmb-v0.9", EChannelMediumType::icmbV09},
113 {"lan-802.3", EChannelMediumType::lan8032},
114 {"serial", EChannelMediumType::serial},
115 {"other-lan", EChannelMediumType::otherLan},
116 {"pci-smbus", EChannelMediumType::pciSmbus},
117 {"smbus-v1.0", EChannelMediumType::smbusV11},
118 {"smbus-v2.0", EChannelMediumType::smbusV20},
119 {"usb-1x", EChannelMediumType::usbV1x},
120 {"usb-2x", EChannelMediumType::usbV2x},
121 {"system-interface", EChannelMediumType::systemInterface},
122 {"oem", EChannelMediumType::oem},
123 {"unknown", EChannelMediumType::unknown}};
124
ssekarf4b2b092018-07-25 18:49:08 +0530125static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
Richard Marian Thomaiyar43cb1282018-12-08 17:22:53 +0530126 {interfaceKCS, "SMS"},
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530127 {interfaceLAN1, "eth0"},
ssekarf4b2b092018-07-25 18:49:08 +0530128 {interfaceUnknown, "unknown"}};
129
AppaRao Puli071f3f22018-05-24 16:45:30 +0530130static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
131 {"na", EChannelProtocolType::na},
132 {"ipmb-1.0", EChannelProtocolType::ipmbV10},
133 {"icmb-2.0", EChannelProtocolType::icmbV11},
134 {"reserved", EChannelProtocolType::reserved},
135 {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
136 {"kcs", EChannelProtocolType::kcs},
137 {"smic", EChannelProtocolType::smic},
138 {"bt-10", EChannelProtocolType::bt10},
139 {"bt-15", EChannelProtocolType::bt15},
140 {"tmode", EChannelProtocolType::tMode},
141 {"oem", EChannelProtocolType::oem}};
142
143static std::array<std::string, 4> accessModeList = {
144 "disabled", "pre-boot", "always_available", "shared"};
145
146static std::array<std::string, 4> sessionSupportList = {
147 "session-less", "single-session", "multi-session", "session-based"};
148
Sumanth Bhate4e633e2019-05-14 12:13:57 +0000149const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530150 "priv-reserved", "priv-callback", "priv-user",
151 "priv-operator", "priv-admin", "priv-oem"};
152
Richard Marian Thomaiyar55768e32019-03-02 22:54:37 +0530153std::string ChannelConfig::getChannelName(const uint8_t chNum)
Johnathan Mantey74a21022018-12-13 13:17:56 -0800154{
155 if (!isValidChannel(chNum))
156 {
157 log<level::ERR>("Invalid channel number.",
Richard Marian Thomaiyar619ed5f2020-01-17 12:17:47 +0530158 entry("CHANNEL_ID=%d", chNum));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800159 throw std::invalid_argument("Invalid channel number");
160 }
161
162 return channelData[chNum].chName;
163}
164
165int ChannelConfig::convertToChannelNumberFromChannelName(
166 const std::string& chName)
167{
168 for (const auto& it : channelData)
169 {
170 if (it.chName == chName)
171 {
172 return it.chID;
173 }
174 }
175 log<level::ERR>("Invalid channel name.",
Richard Marian Thomaiyar619ed5f2020-01-17 12:17:47 +0530176 entry("CHANNEL=%s", chName.c_str()));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800177 throw std::invalid_argument("Invalid channel name");
178
179 return -1;
180}
181
182std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530183{
Peter Foley1214d6c2023-11-01 11:12:42 -0400184 const size_t length = strlen(networkIntfObjectBasePath);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530185 if (((length + 1) >= path.size()) ||
186 path.compare(0, length, networkIntfObjectBasePath))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530187 {
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530188 log<level::ERR>("Invalid object path.", entry("PATH=%s", path.c_str()));
189 throw std::invalid_argument("Invalid object path");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530190 }
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530191 std::string chName(path, length + 1);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800192 return chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530193}
194
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800195void ChannelConfig::processChAccessPropChange(
196 const std::string& path, const DbusChObjProperties& chProperties)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530197{
198 // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
Johnathan Mantey74a21022018-12-13 13:17:56 -0800199 std::string chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530200 try
201 {
Johnathan Mantey74a21022018-12-13 13:17:56 -0800202 chName = getChannelNameFromPath(path);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530203 }
204 catch (const std::invalid_argument& e)
205 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +0530206 log<level::ERR>("Exception: ", entry("MSG=%s", e.what()));
AppaRao Puli9613ed72018-09-01 23:46:44 +0530207 return;
208 }
209
210 // Get the MaxPrivilege property value from the signal
211 std::string intfPrivStr;
212 std::string propName;
213 for (const auto& prop : chProperties)
214 {
215 if (prop.first == privilegePropertyString)
216 {
217 propName = privilegePropertyString;
Vernon Maueryf442e112019-04-09 11:44:36 -0700218 intfPrivStr = std::get<std::string>(prop.second);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530219 break;
220 }
221 }
222
223 if (propName != privilegePropertyString)
224 {
225 log<level::ERR>("Unknown signal caught.");
226 return;
227 }
228
229 if (intfPrivStr.empty())
230 {
231 log<level::ERR>("Invalid privilege string.",
Ayushi Smriti05ad3412019-10-16 16:10:18 +0530232 entry("INTF=%s", chName.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +0530233 return;
234 }
235
236 uint8_t intfPriv = 0;
Johnathan Mantey74a21022018-12-13 13:17:56 -0800237 int chNum;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530238 try
239 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800240 intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800241 chNum = convertToChannelNumberFromChannelName(chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530242 }
243 catch (const std::invalid_argument& e)
244 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +0530245 log<level::ERR>("Exception: ", entry("MSG=%s", e.what()));
AppaRao Puli9613ed72018-09-01 23:46:44 +0530246 return;
247 }
248
249 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800250 channelLock{*channelMutex};
AppaRao Puli9613ed72018-09-01 23:46:44 +0530251 // skip updating the values, if this property change originated from IPMI.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800252 if (signalFlag & (1 << chNum))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530253 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800254 signalFlag &= ~(1 << chNum);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530255 log<level::DEBUG>("Request originated from IPMI so ignoring signal");
256 return;
257 }
258
259 // Update both volatile & Non-volatile, if there is mismatch.
260 // as property change other than IPMI, has to update both volatile &
261 // non-volatile data.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800262 checkAndReloadVolatileData();
263 checkAndReloadNVData();
264 if (channelData[chNum].chAccess.chNonVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530265 {
266 // Update NV data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800267 channelData[chNum].chAccess.chNonVolatileData.privLimit = intfPriv;
268 if (writeChannelPersistData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530269 {
270 log<level::ERR>("Failed to update the persist data file");
271 return;
272 }
273
274 // Update Volatile data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800275 if (channelData[chNum].chAccess.chVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530276 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800277 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
278 if (writeChannelVolatileData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530279 {
280 log<level::ERR>("Failed to update the volatile data file");
281 return;
282 }
283 }
284 }
285
286 return;
287}
288
AppaRao Puli071f3f22018-05-24 16:45:30 +0530289ChannelConfig& getChannelConfigObject()
290{
291 static ChannelConfig channelConfig;
292 return channelConfig;
293}
294
AppaRao Puli9613ed72018-09-01 23:46:44 +0530295ChannelConfig::~ChannelConfig()
296{
297 if (signalHndlrObjectState)
298 {
299 chPropertiesSignal.reset();
Willy Tuac05aa12021-11-16 21:15:58 -0800300 chInterfaceAddedSignal.reset();
301 chInterfaceRemovedSignal.reset();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530302 sigHndlrLock.unlock();
303 }
304}
305
AppaRao Puli071f3f22018-05-24 16:45:30 +0530306ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
307{
308 std::ofstream mutexCleanUpFile;
309 mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
310 std::ofstream::out | std::ofstream::app);
311 if (!mutexCleanUpFile.good())
312 {
313 log<level::DEBUG>("Unable to open mutex cleanup file");
314 return;
315 }
316 mutexCleanUpFile.close();
317 mutexCleanupLock =
318 boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
319 if (mutexCleanupLock.try_lock())
320 {
321 boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
322 channelMutex =
323 std::make_unique<boost::interprocess::named_recursive_mutex>(
324 boost::interprocess::open_or_create, ipmiChannelMutex);
325 mutexCleanupLock.lock_sharable();
326 }
327 else
328 {
329 mutexCleanupLock.lock_sharable();
330 channelMutex =
331 std::make_unique<boost::interprocess::named_recursive_mutex>(
332 boost::interprocess::open_or_create, ipmiChannelMutex);
333 }
334
335 initChannelPersistData();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530336
337 sigHndlrLock = boost::interprocess::file_lock(channelNvDataFilename);
George Liu1a2e1502022-07-08 12:20:19 +0800338 // Register it for single object and single process either netipmid /
AppaRao Puli9613ed72018-09-01 23:46:44 +0530339 // host-ipmid
340 if (chPropertiesSignal == nullptr && sigHndlrLock.try_lock())
341 {
342 log<level::DEBUG>("Registering channel signal handler.");
343 chPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
344 bus,
345 sdbusplus::bus::match::rules::path_namespace(
346 networkIntfObjectBasePath) +
347 sdbusplus::bus::match::rules::type::signal() +
348 sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
349 sdbusplus::bus::match::rules::interface(
350 dBusPropertiesInterface) +
351 sdbusplus::bus::match::rules::argN(0, networkChConfigIntfName),
Patrick Williams5d82f472022-07-22 19:26:53 -0500352 [&](sdbusplus::message_t& msg) {
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500353 DbusChObjProperties props;
354 std::string iface;
355 std::string path = msg.get_path();
356 msg.read(iface, props);
357 processChAccessPropChange(path, props);
Patrick Williams369824e2023-10-20 11:18:23 -0500358 });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530359 signalHndlrObjectState = true;
Willy Tuac05aa12021-11-16 21:15:58 -0800360
361 chInterfaceAddedSignal = std::make_unique<sdbusplus::bus::match_t>(
362 bus,
363 sdbusplus::bus::match::rules::type::signal() +
364 sdbusplus::bus::match::rules::member(interfaceAddedSignal) +
365 sdbusplus::bus::match::rules::argNpath(
366 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500367 [&](sdbusplus::message_t&) { initChannelPersistData(); });
Willy Tuac05aa12021-11-16 21:15:58 -0800368
369 chInterfaceRemovedSignal = std::make_unique<sdbusplus::bus::match_t>(
370 bus,
371 sdbusplus::bus::match::rules::type::signal() +
372 sdbusplus::bus::match::rules::member(interfaceRemovedSignal) +
373 sdbusplus::bus::match::rules::argNpath(
374 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500375 [&](sdbusplus::message_t&) { initChannelPersistData(); });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530376 }
377}
378
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530379bool ChannelConfig::isValidChannel(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530380{
Meera-Kattac1789482021-05-18 09:53:26 +0000381 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530382 {
383 log<level::DEBUG>("Invalid channel ID - Out of range");
384 return false;
385 }
386
387 if (channelData[chNum].isChValid == false)
388 {
389 log<level::DEBUG>("Channel is not valid");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530390 }
391
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800392 return channelData[chNum].isChValid;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530393}
394
395EChannelSessSupported
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530396 ChannelConfig::getChannelSessionSupport(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530397{
398 EChannelSessSupported chSessSupport =
399 (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
400 return chSessSupport;
401}
402
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530403bool ChannelConfig::isValidAuthType(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530404 const EAuthType& authType)
405{
406 if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
407 {
408 log<level::DEBUG>("Invalid authentication type");
409 return false;
410 }
411
412 uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
413 if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
414 {
415 log<level::DEBUG>("Authentication type is not supported.");
416 return false;
417 }
418
419 return true;
420}
421
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530422int ChannelConfig::getChannelActiveSessions(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530423{
424 // TODO: TEMPORARY FIX
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800425 // Channels active session count is managed separately
AppaRao Puli071f3f22018-05-24 16:45:30 +0530426 // by monitoring channel session which includes LAN and
427 // RAKP layer changes. This will be updated, once the
428 // authentication part is implemented.
429 return channelData[chNum].activeSessCount;
430}
431
Vernon Mauery58317122018-11-28 11:02:43 -0800432size_t ChannelConfig::getChannelMaxTransferSize(uint8_t chNum)
433{
434 return channelData[chNum].maxTransferSize;
435}
436
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000437Cc ChannelConfig::getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530438{
439 if (!isValidChannel(chNum))
440 {
441 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000442 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530443 }
444
445 std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
446 sizeof(channelData[chNum].chInfo),
447 reinterpret_cast<uint8_t*>(&chInfo));
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000448 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530449}
450
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000451Cc ChannelConfig::getChannelAccessData(const uint8_t chNum,
452 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530453{
454 if (!isValidChannel(chNum))
455 {
456 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000457 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530458 }
459
460 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
461 {
462 log<level::DEBUG>("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000463 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530464 }
465
466 if (checkAndReloadVolatileData() != 0)
467 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000468 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530469 }
470
471 std::copy_n(
472 reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
473 sizeof(channelData[chNum].chAccess.chVolatileData),
474 reinterpret_cast<uint8_t*>(&chAccessData));
475
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000476 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530477}
478
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000479Cc ChannelConfig::setChannelAccessData(const uint8_t chNum,
480 const ChannelAccess& chAccessData,
481 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530482{
483 if (!isValidChannel(chNum))
484 {
485 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000486 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530487 }
488
489 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
490 {
491 log<level::DEBUG>("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000492 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530493 }
494
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000495 if ((setFlag & setAccessMode) &&
496 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530497 {
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000498 log<level::DEBUG>("Invalid access mode specified");
499 return ccAccessModeNotSupportedForChannel;
500 }
501 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
502 {
503 log<level::DEBUG>("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000504 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530505 }
506
507 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
508 channelLock{*channelMutex};
509
510 if (checkAndReloadVolatileData() != 0)
511 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000512 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530513 }
514
515 if (setFlag & setAccessMode)
516 {
517 channelData[chNum].chAccess.chVolatileData.accessMode =
518 chAccessData.accessMode;
519 }
520 if (setFlag & setUserAuthEnabled)
521 {
522 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
523 chAccessData.userAuthDisabled;
524 }
525 if (setFlag & setMsgAuthEnabled)
526 {
527 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
528 chAccessData.perMsgAuthDisabled;
529 }
530 if (setFlag & setAlertingEnabled)
531 {
532 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
533 chAccessData.alertingDisabled;
534 }
535 if (setFlag & setPrivLimit)
536 {
537 channelData[chNum].chAccess.chVolatileData.privLimit =
538 chAccessData.privLimit;
539 }
540
541 // Write Volatile data to file
542 if (writeChannelVolatileData() != 0)
543 {
544 log<level::DEBUG>("Failed to update the channel volatile data");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000545 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530546 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000547 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530548}
549
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000550Cc ChannelConfig::getChannelAccessPersistData(const uint8_t chNum,
551 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530552{
553 if (!isValidChannel(chNum))
554 {
555 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000556 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530557 }
558
559 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
560 {
561 log<level::DEBUG>("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000562 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530563 }
564
565 if (checkAndReloadNVData() != 0)
566 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000567 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530568 }
569
570 std::copy_n(reinterpret_cast<uint8_t*>(
571 &channelData[chNum].chAccess.chNonVolatileData),
572 sizeof(channelData[chNum].chAccess.chNonVolatileData),
573 reinterpret_cast<uint8_t*>(&chAccessData));
574
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000575 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530576}
577
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000578Cc ChannelConfig::setChannelAccessPersistData(const uint8_t chNum,
579 const ChannelAccess& chAccessData,
580 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530581{
582 if (!isValidChannel(chNum))
583 {
584 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000585 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530586 }
587
588 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
589 {
590 log<level::DEBUG>("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000591 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530592 }
593
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000594 if ((setFlag & setAccessMode) &&
595 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530596 {
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000597 log<level::DEBUG>("Invalid access mode specified");
598 return ccAccessModeNotSupportedForChannel;
599 }
600 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
601 {
602 log<level::DEBUG>("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000603 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530604 }
605
606 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
607 channelLock{*channelMutex};
608
609 if (checkAndReloadNVData() != 0)
610 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000611 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530612 }
613
614 if (setFlag & setAccessMode)
615 {
616 channelData[chNum].chAccess.chNonVolatileData.accessMode =
617 chAccessData.accessMode;
618 }
619 if (setFlag & setUserAuthEnabled)
620 {
621 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
622 chAccessData.userAuthDisabled;
623 }
624 if (setFlag & setMsgAuthEnabled)
625 {
626 channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
627 chAccessData.perMsgAuthDisabled;
628 }
629 if (setFlag & setAlertingEnabled)
630 {
631 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
632 chAccessData.alertingDisabled;
633 }
634 if (setFlag & setPrivLimit)
635 {
AppaRao Puli9613ed72018-09-01 23:46:44 +0530636 // Send Update to network channel config interfaces over dbus
AppaRao Puli9613ed72018-09-01 23:46:44 +0530637 std::string privStr = convertToPrivLimitString(chAccessData.privLimit);
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530638 std::string networkIntfObj = std::string(networkIntfObjectBasePath) +
639 "/" + channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530640 try
641 {
Johnathan Manteyf92261d2018-12-10 15:49:34 -0800642 if (0 != setDbusProperty(networkIntfServiceName, networkIntfObj,
643 networkChConfigIntfName,
AppaRao Puli9613ed72018-09-01 23:46:44 +0530644 privilegePropertyString, privStr))
645 {
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530646 log<level::DEBUG>(
647 "Network interface does not exist",
Ayushi Smriti05ad3412019-10-16 16:10:18 +0530648 entry("INTERFACE=%s", channelData[chNum].chName.c_str()));
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000649 return ccUnspecifiedError;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530650 }
651 }
Patrick Williams5d82f472022-07-22 19:26:53 -0500652 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530653 {
654 log<level::ERR>("Exception: Network interface does not exist");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000655 return ccInvalidFieldRequest;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530656 }
657 signalFlag |= (1 << chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530658 channelData[chNum].chAccess.chNonVolatileData.privLimit =
659 chAccessData.privLimit;
660 }
661
662 // Write persistent data to file
663 if (writeChannelPersistData() != 0)
664 {
665 log<level::DEBUG>("Failed to update the presist data file");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000666 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530667 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000668 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530669}
670
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000671Cc ChannelConfig::getChannelAuthTypeSupported(const uint8_t chNum,
672 uint8_t& authTypeSupported)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530673{
674 if (!isValidChannel(chNum))
675 {
676 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000677 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530678 }
679
680 authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000681 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530682}
683
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000684Cc ChannelConfig::getChannelEnabledAuthType(const uint8_t chNum,
685 const uint8_t priv,
686 EAuthType& authType)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530687{
688 if (!isValidChannel(chNum))
689 {
690 log<level::DEBUG>("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000691 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530692 }
693
694 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
695 {
696 log<level::DEBUG>("Sessionless channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000697 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530698 }
699
700 if (!isValidPrivLimit(priv))
701 {
702 log<level::DEBUG>("Invalid privilege specified.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000703 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530704 }
705
706 // TODO: Hardcoded for now. Need to implement.
707 authType = EAuthType::none;
708
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000709 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530710}
711
712std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
713{
714 struct stat fileStat;
715 if (stat(fileName.c_str(), &fileStat) != 0)
716 {
717 log<level::DEBUG>("Error in getting last updated time stamp");
718 return -EIO;
719 }
720 return fileStat.st_mtime;
721}
722
723EChannelAccessMode
724 ChannelConfig::convertToAccessModeIndex(const std::string& mode)
725{
726 auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
727 if (iter == accessModeList.end())
728 {
729 log<level::ERR>("Invalid access mode.",
730 entry("MODE_STR=%s", mode.c_str()));
731 throw std::invalid_argument("Invalid access mode.");
732 }
733
734 return static_cast<EChannelAccessMode>(
735 std::distance(accessModeList.begin(), iter));
736}
737
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530738std::string ChannelConfig::convertToAccessModeString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530739{
740 if (accessModeList.size() <= value)
741 {
742 log<level::ERR>("Invalid access mode.", entry("MODE_IDX=%d", value));
743 throw std::invalid_argument("Invalid access mode.");
744 }
745
746 return accessModeList.at(value);
747}
748
749CommandPrivilege
750 ChannelConfig::convertToPrivLimitIndex(const std::string& value)
751{
752 auto iter = std::find(privList.begin(), privList.end(), value);
753 if (iter == privList.end())
754 {
755 log<level::ERR>("Invalid privilege.",
756 entry("PRIV_STR=%s", value.c_str()));
757 throw std::invalid_argument("Invalid privilege.");
758 }
759
760 return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
761}
762
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530763std::string ChannelConfig::convertToPrivLimitString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530764{
765 if (privList.size() <= value)
766 {
767 log<level::ERR>("Invalid privilege.", entry("PRIV_IDX=%d", value));
768 throw std::invalid_argument("Invalid privilege.");
769 }
770
771 return privList.at(value);
772}
773
774EChannelSessSupported
775 ChannelConfig::convertToSessionSupportIndex(const std::string& value)
776{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500777 auto iter = std::find(sessionSupportList.begin(), sessionSupportList.end(),
778 value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530779 if (iter == sessionSupportList.end())
780 {
781 log<level::ERR>("Invalid session supported.",
782 entry("SESS_STR=%s", value.c_str()));
783 throw std::invalid_argument("Invalid session supported.");
784 }
785
786 return static_cast<EChannelSessSupported>(
787 std::distance(sessionSupportList.begin(), iter));
788}
789
790EChannelMediumType
791 ChannelConfig::convertToMediumTypeIndex(const std::string& value)
792{
793 std::unordered_map<std::string, EChannelMediumType>::iterator it =
794 mediumTypeMap.find(value);
795 if (it == mediumTypeMap.end())
796 {
797 log<level::ERR>("Invalid medium type.",
798 entry("MEDIUM_STR=%s", value.c_str()));
799 throw std::invalid_argument("Invalid medium type.");
800 }
801
802 return static_cast<EChannelMediumType>(it->second);
803}
804
805EChannelProtocolType
806 ChannelConfig::convertToProtocolTypeIndex(const std::string& value)
807{
808 std::unordered_map<std::string, EChannelProtocolType>::iterator it =
809 protocolTypeMap.find(value);
810 if (it == protocolTypeMap.end())
811 {
812 log<level::ERR>("Invalid protocol type.",
813 entry("PROTO_STR=%s", value.c_str()));
814 throw std::invalid_argument("Invalid protocol type.");
815 }
816
817 return static_cast<EChannelProtocolType>(it->second);
818}
819
820Json ChannelConfig::readJsonFile(const std::string& configFile)
821{
822 std::ifstream jsonFile(configFile);
823 if (!jsonFile.good())
824 {
Richard Marian Thomaiyarc4196802019-06-03 19:27:48 +0530825 log<level::INFO>("JSON file not found",
826 entry("FILE_NAME=%s", configFile.c_str()));
AppaRao Puli071f3f22018-05-24 16:45:30 +0530827 return nullptr;
828 }
829
830 Json data = nullptr;
831 try
832 {
833 data = Json::parse(jsonFile, nullptr, false);
834 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500835 catch (const Json::parse_error& e)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530836 {
837 log<level::DEBUG>("Corrupted channel config.",
Ayushi Smriti05ad3412019-10-16 16:10:18 +0530838 entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +0530839 throw std::runtime_error("Corrupted channel config file");
840 }
841
842 return data;
843}
844
845int ChannelConfig::writeJsonFile(const std::string& configFile,
846 const Json& jsonData)
847{
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530848 const std::string tmpFile = configFile + "_tmp";
849 int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
850 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
851 if (fd < 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530852 {
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530853 log<level::ERR>("Error in creating json file",
854 entry("FILE_NAME = %s", tmpFile.c_str()));
855 return -EIO;
856 }
857 const auto& writeData = jsonData.dump();
858 if (write(fd, writeData.c_str(), writeData.size()) !=
859 static_cast<ssize_t>(writeData.size()))
860 {
861 close(fd);
862 log<level::ERR>("Error in writing configuration file",
863 entry("FILE_NAME = %s", tmpFile.c_str()));
864 return -EIO;
865 }
866 close(fd);
867
868 if (std::rename(tmpFile.c_str(), configFile.c_str()) != 0)
869 {
870 log<level::ERR>("Error in renaming temporary data file",
871 entry("FILE_NAME = %s", tmpFile.c_str()));
AppaRao Puli071f3f22018-05-24 16:45:30 +0530872 return -EIO;
873 }
874
AppaRao Puli071f3f22018-05-24 16:45:30 +0530875 return 0;
876}
877
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530878void ChannelConfig::setDefaultChannelConfig(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530879 const std::string& chName)
880{
881 channelData[chNum].chName = chName;
882 channelData[chNum].chID = chNum;
883 channelData[chNum].isChValid = false;
884 channelData[chNum].activeSessCount = 0;
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700885 channelData[chNum].isManagementNIC = false;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530886
887 channelData[chNum].chInfo.mediumType = defaultMediumType;
888 channelData[chNum].chInfo.protocolType = defaultProtocolType;
889 channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
890 channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
891 channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
892}
893
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700894uint8_t ChannelConfig::getManagementNICID()
895{
896 static bool idFound = false;
897 static uint8_t id = 0;
898
899 if (idFound)
900 {
901 return id;
902 }
903
904 for (uint8_t chIdx = 0; chIdx < maxIpmiChannels; chIdx++)
905 {
906 if (channelData[chIdx].isManagementNIC)
907 {
908 id = chIdx;
909 idFound = true;
910 break;
911 }
912 }
913
914 if (!idFound)
915 {
916 id = static_cast<uint8_t>(EChannelID::chanLan1);
917 idFound = true;
918 }
919 return id;
920}
921
AppaRao Puli071f3f22018-05-24 16:45:30 +0530922int ChannelConfig::loadChannelConfig()
923{
924 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
925 channelLock{*channelMutex};
926
927 Json data = readJsonFile(channelConfigDefaultFilename);
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800928 if (data.empty())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530929 {
930 log<level::DEBUG>("Error in opening IPMI Channel data file");
931 return -EIO;
932 }
933
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800934 channelData.fill(ChannelProperties{});
935
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800936 // Collect the list of NIC interfaces connected to the BMC. Use this
937 // information to only add IPMI channels that have active NIC interfaces.
Snehalatha Venkatesh55f5d532021-07-13 11:06:36 +0000938 struct ifaddrs *ifaddr = nullptr, *ifa = nullptr;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800939 if (int err = getifaddrs(&ifaddr); err < 0)
940 {
941 log<level::DEBUG>("Unable to acquire network interfaces");
942 return -EIO;
943 }
944
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800945 for (int chNum = 0; chNum < maxIpmiChannels; chNum++)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530946 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800947 try
AppaRao Puli071f3f22018-05-24 16:45:30 +0530948 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530949 std::string chKey = std::to_string(chNum);
950 Json jsonChData = data[chKey].get<Json>();
951 if (jsonChData.is_null())
952 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530953 // If user didn't want to configure specific channel (say
954 // reserved channel), then load that index with default values.
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800955 setDefaultChannelConfig(chNum, defaultChannelName);
956 continue;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530957 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800958 Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
959 if (jsonChInfo.is_null())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530960 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800961 log<level::ERR>("Invalid/corrupted channel config file");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800962 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800963 return -EBADMSG;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530964 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800965
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800966 bool channelFound = true;
967 // Confirm the LAN channel is present
968 if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
969 {
970 channelFound = false;
971 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
972 {
973 if (jsonChData[nameString].get<std::string>() ==
974 ifa->ifa_name)
975 {
976 channelFound = true;
977 break;
978 }
979 }
980 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800981 ChannelProperties& chData = channelData[chNum];
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800982 chData.chID = chNum;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800983 chData.chName = jsonChData[nameString].get<std::string>();
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500984 chData.isChValid = channelFound &&
985 jsonChData[isValidString].get<bool>();
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800986 chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500987 chData.maxTransferSize = jsonChData.value(maxTransferSizeString,
988 smallChannelSize);
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700989 if (jsonChData.count(isManagementNIC) != 0)
990 {
991 chData.isManagementNIC =
992 jsonChData[isManagementNIC].get<bool>();
993 }
994
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800995 std::string medTypeStr =
996 jsonChInfo[mediumTypeString].get<std::string>();
997 chData.chInfo.mediumType =
998 static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
999 std::string protoTypeStr =
1000 jsonChInfo[protocolTypeString].get<std::string>();
1001 chData.chInfo.protocolType =
1002 static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
1003 std::string sessStr =
1004 jsonChInfo[sessionSupportedString].get<std::string>();
1005 chData.chInfo.sessionSupported =
1006 static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
1007 chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
1008 chData.chInfo.authTypeSupported = defaultAuthType;
AppaRao Puli071f3f22018-05-24 16:45:30 +05301009 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001010 catch (const Json::exception& e)
1011 {
1012 log<level::DEBUG>("Json Exception caught.",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301013 entry("MSG=%s", e.what()));
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001014 freeifaddrs(ifaddr);
1015
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001016 return -EBADMSG;
1017 }
1018 catch (const std::invalid_argument& e)
1019 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301020 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001021 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001022 return -EBADMSG;
1023 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301024 }
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001025 freeifaddrs(ifaddr);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301026
1027 return 0;
1028}
1029
1030int ChannelConfig::readChannelVolatileData()
1031{
1032 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1033 channelLock{*channelMutex};
1034
1035 Json data = readJsonFile(channelVolatileDataFilename);
1036 if (data == nullptr)
1037 {
1038 log<level::DEBUG>("Error in opening IPMI Channel data file");
1039 return -EIO;
1040 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301041 try
1042 {
1043 // Fill in global structure
1044 for (auto it = data.begin(); it != data.end(); ++it)
1045 {
1046 std::string chKey = it.key();
1047 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001048 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301049 {
1050 log<level::DEBUG>(
1051 "Invalid channel access entry in config file");
1052 throw std::out_of_range("Out of range - channel number");
1053 }
1054 Json jsonChData = it.value();
1055 if (!jsonChData.is_null())
1056 {
1057 std::string accModeStr =
1058 jsonChData[accessModeString].get<std::string>();
1059 channelData[chNum].chAccess.chVolatileData.accessMode =
1060 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1061 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
1062 jsonChData[userAuthDisabledString].get<bool>();
1063 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
1064 jsonChData[perMsgAuthDisabledString].get<bool>();
1065 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
1066 jsonChData[alertingDisabledString].get<bool>();
1067 std::string privStr =
1068 jsonChData[privLimitString].get<std::string>();
1069 channelData[chNum].chAccess.chVolatileData.privLimit =
1070 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1071 }
1072 else
1073 {
1074 log<level::ERR>(
1075 "Invalid/corrupted volatile channel access file",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301076 entry("FILE=%s", channelVolatileDataFilename));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301077 throw std::runtime_error(
1078 "Corrupted volatile channel access file");
1079 }
1080 }
1081 }
1082 catch (const Json::exception& e)
1083 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301084 log<level::DEBUG>("Json Exception caught.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301085 throw std::runtime_error("Corrupted volatile channel access file");
1086 }
1087 catch (const std::invalid_argument& e)
1088 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301089 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301090 throw std::runtime_error("Corrupted volatile channel access file");
1091 }
1092
1093 // Update the timestamp
1094 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1095 return 0;
1096}
1097
1098int ChannelConfig::readChannelPersistData()
1099{
1100 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1101 channelLock{*channelMutex};
1102
1103 Json data = readJsonFile(channelNvDataFilename);
1104 if (data == nullptr)
1105 {
1106 log<level::DEBUG>("Error in opening IPMI Channel data file");
1107 return -EIO;
1108 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301109 try
1110 {
1111 // Fill in global structure
1112 for (auto it = data.begin(); it != data.end(); ++it)
1113 {
1114 std::string chKey = it.key();
1115 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001116 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301117 {
1118 log<level::DEBUG>(
1119 "Invalid channel access entry in config file");
1120 throw std::out_of_range("Out of range - channel number");
1121 }
1122 Json jsonChData = it.value();
1123 if (!jsonChData.is_null())
1124 {
1125 std::string accModeStr =
1126 jsonChData[accessModeString].get<std::string>();
1127 channelData[chNum].chAccess.chNonVolatileData.accessMode =
1128 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1129 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
1130 jsonChData[userAuthDisabledString].get<bool>();
1131 channelData[chNum]
1132 .chAccess.chNonVolatileData.perMsgAuthDisabled =
1133 jsonChData[perMsgAuthDisabledString].get<bool>();
1134 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
1135 jsonChData[alertingDisabledString].get<bool>();
1136 std::string privStr =
1137 jsonChData[privLimitString].get<std::string>();
1138 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1139 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1140 }
1141 else
1142 {
1143 log<level::ERR>("Invalid/corrupted nv channel access file",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301144 entry("FILE=%s", channelNvDataFilename));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301145 throw std::runtime_error("Corrupted nv channel access file");
1146 }
1147 }
1148 }
1149 catch (const Json::exception& e)
1150 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301151 log<level::DEBUG>("Json Exception caught.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301152 throw std::runtime_error("Corrupted nv channel access file");
1153 }
1154 catch (const std::invalid_argument& e)
1155 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301156 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301157 throw std::runtime_error("Corrupted nv channel access file");
1158 }
1159
1160 // Update the timestamp
1161 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1162 return 0;
1163}
1164
1165int ChannelConfig::writeChannelVolatileData()
1166{
1167 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1168 channelLock{*channelMutex};
1169 Json outData;
1170
1171 try
1172 {
1173 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1174 {
1175 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1176 {
1177 Json jsonObj;
1178 std::string chKey = std::to_string(chNum);
1179 std::string accModeStr = convertToAccessModeString(
1180 channelData[chNum].chAccess.chVolatileData.accessMode);
1181 jsonObj[accessModeString] = accModeStr;
1182 jsonObj[userAuthDisabledString] =
1183 channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
1184 jsonObj[perMsgAuthDisabledString] =
1185 channelData[chNum]
1186 .chAccess.chVolatileData.perMsgAuthDisabled;
1187 jsonObj[alertingDisabledString] =
1188 channelData[chNum].chAccess.chVolatileData.alertingDisabled;
1189 std::string privStr = convertToPrivLimitString(
1190 channelData[chNum].chAccess.chVolatileData.privLimit);
1191 jsonObj[privLimitString] = privStr;
1192
1193 outData[chKey] = jsonObj;
1194 }
1195 }
1196 }
1197 catch (const std::invalid_argument& e)
1198 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301199 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301200 return -EINVAL;
1201 }
1202
1203 if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
1204 {
1205 log<level::DEBUG>("Error in write JSON data to file");
1206 return -EIO;
1207 }
1208
1209 // Update the timestamp
1210 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1211 return 0;
1212}
1213
1214int ChannelConfig::writeChannelPersistData()
1215{
1216 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1217 channelLock{*channelMutex};
1218 Json outData;
1219
1220 try
1221 {
1222 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1223 {
1224 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1225 {
1226 Json jsonObj;
1227 std::string chKey = std::to_string(chNum);
1228 std::string accModeStr = convertToAccessModeString(
1229 channelData[chNum].chAccess.chNonVolatileData.accessMode);
1230 jsonObj[accessModeString] = accModeStr;
1231 jsonObj[userAuthDisabledString] =
1232 channelData[chNum]
1233 .chAccess.chNonVolatileData.userAuthDisabled;
1234 jsonObj[perMsgAuthDisabledString] =
1235 channelData[chNum]
1236 .chAccess.chNonVolatileData.perMsgAuthDisabled;
1237 jsonObj[alertingDisabledString] =
1238 channelData[chNum]
1239 .chAccess.chNonVolatileData.alertingDisabled;
1240 std::string privStr = convertToPrivLimitString(
1241 channelData[chNum].chAccess.chNonVolatileData.privLimit);
1242 jsonObj[privLimitString] = privStr;
1243
1244 outData[chKey] = jsonObj;
1245 }
1246 }
1247 }
1248 catch (const std::invalid_argument& e)
1249 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301250 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301251 return -EINVAL;
1252 }
1253
1254 if (writeJsonFile(channelNvDataFilename, outData) != 0)
1255 {
1256 log<level::DEBUG>("Error in write JSON data to file");
1257 return -EIO;
1258 }
1259
1260 // Update the timestamp
1261 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1262 return 0;
1263}
1264
1265int ChannelConfig::checkAndReloadNVData()
1266{
1267 std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
1268 int ret = 0;
1269 if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
1270 {
1271 try
1272 {
1273 ret = readChannelPersistData();
1274 }
1275 catch (const std::exception& e)
1276 {
1277 log<level::ERR>("Exception caught in readChannelPersistData.",
1278 entry("MSG=%s", e.what()));
1279 ret = -EIO;
1280 }
1281 }
1282 return ret;
1283}
1284
1285int ChannelConfig::checkAndReloadVolatileData()
1286{
1287 std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
1288 int ret = 0;
1289 if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
1290 {
1291 try
1292 {
1293 ret = readChannelVolatileData();
1294 }
1295 catch (const std::exception& e)
1296 {
1297 log<level::ERR>("Exception caught in readChannelVolatileData.",
1298 entry("MSG=%s", e.what()));
1299 ret = -EIO;
1300 }
1301 }
1302 return ret;
1303}
1304
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001305int ChannelConfig::setDbusProperty(const std::string& service,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301306 const std::string& objPath,
1307 const std::string& interface,
1308 const std::string& property,
1309 const DbusVariant& value)
1310{
1311 try
1312 {
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -05001313 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
1314 "org.freedesktop.DBus.Properties",
1315 "Set");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301316
1317 method.append(interface, property, value);
1318
1319 auto reply = bus.call(method);
1320 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001321 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301322 {
1323 log<level::DEBUG>("set-property failed",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301324 entry("SERVICE=%s", service.c_str()),
1325 entry("OBJPATH=%s", objPath.c_str()),
1326 entry("INTERFACE=%s", interface.c_str()),
1327 entry("PROP=%s", property.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301328 return -EIO;
1329 }
1330
1331 return 0;
1332}
1333
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001334int ChannelConfig::getDbusProperty(const std::string& service,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301335 const std::string& objPath,
1336 const std::string& interface,
1337 const std::string& property,
1338 DbusVariant& value)
1339{
1340 try
1341 {
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -05001342 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
1343 "org.freedesktop.DBus.Properties",
1344 "Get");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301345
1346 method.append(interface, property);
1347
1348 auto reply = bus.call(method);
1349 reply.read(value);
1350 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001351 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301352 {
1353 log<level::DEBUG>("get-property failed",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301354 entry("SERVICE=%s", service.c_str()),
1355 entry("OBJPATH=%s", objPath.c_str()),
1356 entry("INTERFACE=%s", interface.c_str()),
1357 entry("PROP=%s", property.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301358 return -EIO;
1359 }
1360 return 0;
1361}
1362
1363int ChannelConfig::syncNetworkChannelConfig()
1364{
1365 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1366 channelLock{*channelMutex};
1367 bool isUpdated = false;
1368 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1369 {
1370 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1371 {
1372 std::string intfPrivStr;
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001373 uint8_t intfPriv = 0;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301374 try
1375 {
AppaRao Puli9613ed72018-09-01 23:46:44 +05301376 std::string networkIntfObj =
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301377 std::string(networkIntfObjectBasePath) + "/" +
1378 channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301379 DbusVariant variant;
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001380 if (0 != getDbusProperty(networkIntfServiceName, networkIntfObj,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301381 networkChConfigIntfName,
1382 privilegePropertyString, variant))
1383 {
1384 log<level::DEBUG>("Network interface does not exist",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301385 entry("INTERFACE=%s",
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301386 channelData[chNum].chName.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301387 continue;
1388 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001389 intfPrivStr = std::get<std::string>(variant);
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001390 intfPriv =
1391 static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301392 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001393 catch (const std::bad_variant_access& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301394 {
1395 log<level::DEBUG>(
1396 "exception: Network interface does not exist");
1397 continue;
1398 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001399 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301400 {
1401 log<level::DEBUG>(
1402 "exception: Network interface does not exist");
1403 continue;
1404 }
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001405 catch (const std::invalid_argument& e)
1406 {
1407 log<level::DEBUG>("exception: Invalid privilege");
1408 continue;
1409 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301410
AppaRao Puli9613ed72018-09-01 23:46:44 +05301411 if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
1412 intfPriv)
1413 {
1414 isUpdated = true;
1415 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1416 intfPriv;
1417 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
1418 }
1419 }
1420 }
1421
1422 if (isUpdated)
1423 {
1424 // Write persistent data to file
1425 if (writeChannelPersistData() != 0)
1426 {
1427 log<level::DEBUG>("Failed to update the persistent data file");
1428 return -EIO;
1429 }
1430 // Write Volatile data to file
1431 if (writeChannelVolatileData() != 0)
1432 {
1433 log<level::DEBUG>("Failed to update the channel volatile data");
1434 return -EIO;
1435 }
1436 }
1437
1438 return 0;
1439}
1440
AppaRao Puli071f3f22018-05-24 16:45:30 +05301441void ChannelConfig::initChannelPersistData()
1442{
Richard Marian Thomaiyare91474c2019-09-01 23:02:47 +05301443 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1444 channelLock{*channelMutex};
1445
AppaRao Puli071f3f22018-05-24 16:45:30 +05301446 /* Always read the channel config */
1447 if (loadChannelConfig() != 0)
1448 {
1449 log<level::ERR>("Failed to read channel config file");
1450 throw std::ios_base::failure("Failed to load channel configuration");
1451 }
1452
1453 /* Populate the channel persist data */
1454 if (readChannelPersistData() != 0)
1455 {
1456 // Copy default NV data to RW location
Patrick Williams3d8d7932022-06-16 12:01:28 -05001457 std::filesystem::copy_file(channelAccessDefaultFilename,
1458 channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301459
1460 // Load the channel access NV data
1461 if (readChannelPersistData() != 0)
1462 {
1463 log<level::ERR>("Failed to read channel access NV data");
1464 throw std::ios_base::failure(
1465 "Failed to read channel access NV configuration");
1466 }
1467 }
1468
1469 // First check the volatile data file
1470 // If not present, load the default values
1471 if (readChannelVolatileData() != 0)
1472 {
1473 // Copy default volatile data to temporary location
1474 // NV file(channelNvDataFilename) must have created by now.
Patrick Williams3d8d7932022-06-16 12:01:28 -05001475 std::filesystem::copy_file(channelNvDataFilename,
1476 channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301477
1478 // Load the channel access volatile data
1479 if (readChannelVolatileData() != 0)
1480 {
1481 log<level::ERR>("Failed to read channel access volatile data");
1482 throw std::ios_base::failure(
1483 "Failed to read channel access volatile configuration");
1484 }
1485 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301486
1487 // Synchronize the channel config(priv) with network channel
1488 // configuration(priv) over dbus
1489 if (syncNetworkChannelConfig() != 0)
1490 {
1491 log<level::ERR>(
1492 "Failed to synchronize data with network channel config over dbus");
1493 throw std::ios_base::failure(
1494 "Failed to synchronize data with network channel config over dbus");
1495 }
1496
1497 log<level::DEBUG>("Successfully completed channel data initialization.");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301498 return;
1499}
1500
1501} // namespace ipmi