blob: 9ddd5adba29e0c011d34ffe3214347063faeeaa9 [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>
28#include <cerrno>
AppaRao Puli9613ed72018-09-01 23:46:44 +053029#include <exception>
Patrick Williams3d8d7932022-06-16 12:01:28 -050030#include <filesystem>
AppaRao Puli071f3f22018-05-24 16:45:30 +053031#include <fstream>
32#include <phosphor-logging/log.hpp>
AppaRao Puli9613ed72018-09-01 23:46:44 +053033#include <sdbusplus/bus/match.hpp>
34#include <sdbusplus/server/object.hpp>
AppaRao Puli071f3f22018-05-24 16:45:30 +053035#include <unordered_map>
36
37namespace ipmi
38{
39
40using namespace phosphor::logging;
41
42static constexpr const char* channelAccessDefaultFilename =
43 "/usr/share/ipmi-providers/channel_access.json";
44static constexpr const char* channelConfigDefaultFilename =
45 "/usr/share/ipmi-providers/channel_config.json";
46static constexpr const char* channelNvDataFilename =
47 "/var/lib/ipmi/channel_access_nv.json";
48static constexpr const char* channelVolatileDataFilename =
49 "/run/ipmi/channel_access_volatile.json";
50
AppaRao Puli9613ed72018-09-01 23:46:44 +053051// TODO: Get the service name dynamically..
52static constexpr const char* networkIntfServiceName =
53 "xyz.openbmc_project.Network";
54static constexpr const char* networkIntfObjectBasePath =
55 "/xyz/openbmc_project/network";
56static constexpr const char* networkChConfigIntfName =
57 "xyz.openbmc_project.Channel.ChannelAccess";
58static constexpr const char* privilegePropertyString = "MaxPrivilege";
59static constexpr const char* dBusPropertiesInterface =
60 "org.freedesktop.DBus.Properties";
61static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
Willy Tuac05aa12021-11-16 21:15:58 -080062static constexpr const char* interfaceAddedSignal = "InterfacesAdded";
63static constexpr const char* interfaceRemovedSignal = "InterfacesRemoved";
AppaRao Puli9613ed72018-09-01 23:46:44 +053064
AppaRao Puli071f3f22018-05-24 16:45:30 +053065// STRING DEFINES: Should sync with key's in JSON
66static constexpr const char* nameString = "name";
67static constexpr const char* isValidString = "is_valid";
68static constexpr const char* activeSessionsString = "active_sessions";
Vernon Mauery58317122018-11-28 11:02:43 -080069static constexpr const char* maxTransferSizeString = "max_transfer_size";
AppaRao Puli071f3f22018-05-24 16:45:30 +053070static constexpr const char* channelInfoString = "channel_info";
71static constexpr const char* mediumTypeString = "medium_type";
72static constexpr const char* protocolTypeString = "protocol_type";
73static constexpr const char* sessionSupportedString = "session_supported";
74static constexpr const char* isIpmiString = "is_ipmi";
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070075static constexpr const char* isManagementNIC = "is_management_nic";
AppaRao Puli071f3f22018-05-24 16:45:30 +053076static constexpr const char* authTypeSupportedString = "auth_type_supported";
77static constexpr const char* accessModeString = "access_mode";
78static constexpr const char* userAuthDisabledString = "user_auth_disabled";
79static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
80static constexpr const char* alertingDisabledString = "alerting_disabled";
81static constexpr const char* privLimitString = "priv_limit";
82static constexpr const char* authTypeEnabledString = "auth_type_enabled";
83
84// Default values
85static constexpr const char* defaultChannelName = "RESERVED";
86static constexpr const uint8_t defaultMediumType =
87 static_cast<uint8_t>(EChannelMediumType::reserved);
88static constexpr const uint8_t defaultProtocolType =
89 static_cast<uint8_t>(EChannelProtocolType::reserved);
90static constexpr const uint8_t defaultSessionSupported =
91 static_cast<uint8_t>(EChannelSessSupported::none);
92static constexpr const uint8_t defaultAuthType =
93 static_cast<uint8_t>(EAuthType::none);
94static constexpr const bool defaultIsIpmiState = false;
Vernon Mauery58317122018-11-28 11:02:43 -080095static constexpr size_t smallChannelSize = 64;
AppaRao Puli071f3f22018-05-24 16:45:30 +053096
Lei YU4b0ddb62019-01-25 16:43:50 +080097std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
98 __attribute__((init_priority(101)));
AppaRao Puli9613ed72018-09-01 23:46:44 +053099
Willy Tuac05aa12021-11-16 21:15:58 -0800100std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
101 __attribute__((init_priority(101)));
102
103std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
104 __attribute__((init_priority(101)));
105
AppaRao Puli071f3f22018-05-24 16:45:30 +0530106// String mappings use in JSON config file
107static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
108 {"reserved", EChannelMediumType::reserved},
109 {"ipmb", EChannelMediumType::ipmb},
110 {"icmb-v1.0", EChannelMediumType::icmbV10},
111 {"icmb-v0.9", EChannelMediumType::icmbV09},
112 {"lan-802.3", EChannelMediumType::lan8032},
113 {"serial", EChannelMediumType::serial},
114 {"other-lan", EChannelMediumType::otherLan},
115 {"pci-smbus", EChannelMediumType::pciSmbus},
116 {"smbus-v1.0", EChannelMediumType::smbusV11},
117 {"smbus-v2.0", EChannelMediumType::smbusV20},
118 {"usb-1x", EChannelMediumType::usbV1x},
119 {"usb-2x", EChannelMediumType::usbV2x},
120 {"system-interface", EChannelMediumType::systemInterface},
121 {"oem", EChannelMediumType::oem},
122 {"unknown", EChannelMediumType::unknown}};
123
ssekarf4b2b092018-07-25 18:49:08 +0530124static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
Richard Marian Thomaiyar43cb1282018-12-08 17:22:53 +0530125 {interfaceKCS, "SMS"},
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530126 {interfaceLAN1, "eth0"},
ssekarf4b2b092018-07-25 18:49:08 +0530127 {interfaceUnknown, "unknown"}};
128
AppaRao Puli071f3f22018-05-24 16:45:30 +0530129static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
130 {"na", EChannelProtocolType::na},
131 {"ipmb-1.0", EChannelProtocolType::ipmbV10},
132 {"icmb-2.0", EChannelProtocolType::icmbV11},
133 {"reserved", EChannelProtocolType::reserved},
134 {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
135 {"kcs", EChannelProtocolType::kcs},
136 {"smic", EChannelProtocolType::smic},
137 {"bt-10", EChannelProtocolType::bt10},
138 {"bt-15", EChannelProtocolType::bt15},
139 {"tmode", EChannelProtocolType::tMode},
140 {"oem", EChannelProtocolType::oem}};
141
142static std::array<std::string, 4> accessModeList = {
143 "disabled", "pre-boot", "always_available", "shared"};
144
145static std::array<std::string, 4> sessionSupportList = {
146 "session-less", "single-session", "multi-session", "session-based"};
147
Sumanth Bhate4e633e2019-05-14 12:13:57 +0000148const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530149 "priv-reserved", "priv-callback", "priv-user",
150 "priv-operator", "priv-admin", "priv-oem"};
151
Richard Marian Thomaiyar55768e32019-03-02 22:54:37 +0530152std::string ChannelConfig::getChannelName(const uint8_t chNum)
Johnathan Mantey74a21022018-12-13 13:17:56 -0800153{
154 if (!isValidChannel(chNum))
155 {
156 log<level::ERR>("Invalid channel number.",
Richard Marian Thomaiyar619ed5f2020-01-17 12:17:47 +0530157 entry("CHANNEL_ID=%d", chNum));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800158 throw std::invalid_argument("Invalid channel number");
159 }
160
161 return channelData[chNum].chName;
162}
163
164int ChannelConfig::convertToChannelNumberFromChannelName(
165 const std::string& chName)
166{
167 for (const auto& it : channelData)
168 {
169 if (it.chName == chName)
170 {
171 return it.chID;
172 }
173 }
174 log<level::ERR>("Invalid channel name.",
Richard Marian Thomaiyar619ed5f2020-01-17 12:17:47 +0530175 entry("CHANNEL=%s", chName.c_str()));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800176 throw std::invalid_argument("Invalid channel name");
177
178 return -1;
179}
180
181std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530182{
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530183
184 constexpr size_t length = strlen(networkIntfObjectBasePath);
185 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) {
AppaRao Puli9613ed72018-09-01 23:46:44 +0530353 DbusChObjProperties props;
354 std::string iface;
355 std::string path = msg.get_path();
356 msg.read(iface, props);
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800357 processChAccessPropChange(path, props);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530358 });
359 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{
777 auto iter =
778 std::find(sessionSupportList.begin(), sessionSupportList.end(), value);
779 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 {
953 log<level::WARNING>(
954 "Channel not configured so loading default.",
Ayushi Smriti05ad3412019-10-16 16:10:18 +0530955 entry("CHANNEL_NUM=%d", chNum));
AppaRao Puli071f3f22018-05-24 16:45:30 +0530956 // If user didn't want to configure specific channel (say
957 // reserved channel), then load that index with default values.
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800958 setDefaultChannelConfig(chNum, defaultChannelName);
959 continue;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530960 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800961 Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
962 if (jsonChInfo.is_null())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530963 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800964 log<level::ERR>("Invalid/corrupted channel config file");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800965 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800966 return -EBADMSG;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530967 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800968
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800969 bool channelFound = true;
970 // Confirm the LAN channel is present
971 if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
972 {
973 channelFound = false;
974 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
975 {
976 if (jsonChData[nameString].get<std::string>() ==
977 ifa->ifa_name)
978 {
979 channelFound = true;
980 break;
981 }
982 }
983 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800984 ChannelProperties& chData = channelData[chNum];
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800985 chData.chID = chNum;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800986 chData.chName = jsonChData[nameString].get<std::string>();
987 chData.isChValid =
988 channelFound && jsonChData[isValidString].get<bool>();
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800989 chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
990 chData.maxTransferSize =
991 jsonChData.value(maxTransferSizeString, smallChannelSize);
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700992 if (jsonChData.count(isManagementNIC) != 0)
993 {
994 chData.isManagementNIC =
995 jsonChData[isManagementNIC].get<bool>();
996 }
997
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800998 std::string medTypeStr =
999 jsonChInfo[mediumTypeString].get<std::string>();
1000 chData.chInfo.mediumType =
1001 static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
1002 std::string protoTypeStr =
1003 jsonChInfo[protocolTypeString].get<std::string>();
1004 chData.chInfo.protocolType =
1005 static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
1006 std::string sessStr =
1007 jsonChInfo[sessionSupportedString].get<std::string>();
1008 chData.chInfo.sessionSupported =
1009 static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
1010 chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
1011 chData.chInfo.authTypeSupported = defaultAuthType;
AppaRao Puli071f3f22018-05-24 16:45:30 +05301012 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001013 catch (const Json::exception& e)
1014 {
1015 log<level::DEBUG>("Json Exception caught.",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301016 entry("MSG=%s", e.what()));
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001017 freeifaddrs(ifaddr);
1018
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001019 return -EBADMSG;
1020 }
1021 catch (const std::invalid_argument& e)
1022 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301023 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001024 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001025 return -EBADMSG;
1026 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301027 }
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001028 freeifaddrs(ifaddr);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301029
1030 return 0;
1031}
1032
1033int ChannelConfig::readChannelVolatileData()
1034{
1035 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1036 channelLock{*channelMutex};
1037
1038 Json data = readJsonFile(channelVolatileDataFilename);
1039 if (data == nullptr)
1040 {
1041 log<level::DEBUG>("Error in opening IPMI Channel data file");
1042 return -EIO;
1043 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301044 try
1045 {
1046 // Fill in global structure
1047 for (auto it = data.begin(); it != data.end(); ++it)
1048 {
1049 std::string chKey = it.key();
1050 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001051 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301052 {
1053 log<level::DEBUG>(
1054 "Invalid channel access entry in config file");
1055 throw std::out_of_range("Out of range - channel number");
1056 }
1057 Json jsonChData = it.value();
1058 if (!jsonChData.is_null())
1059 {
1060 std::string accModeStr =
1061 jsonChData[accessModeString].get<std::string>();
1062 channelData[chNum].chAccess.chVolatileData.accessMode =
1063 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1064 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
1065 jsonChData[userAuthDisabledString].get<bool>();
1066 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
1067 jsonChData[perMsgAuthDisabledString].get<bool>();
1068 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
1069 jsonChData[alertingDisabledString].get<bool>();
1070 std::string privStr =
1071 jsonChData[privLimitString].get<std::string>();
1072 channelData[chNum].chAccess.chVolatileData.privLimit =
1073 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1074 }
1075 else
1076 {
1077 log<level::ERR>(
1078 "Invalid/corrupted volatile channel access file",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301079 entry("FILE=%s", channelVolatileDataFilename));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301080 throw std::runtime_error(
1081 "Corrupted volatile channel access file");
1082 }
1083 }
1084 }
1085 catch (const Json::exception& e)
1086 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301087 log<level::DEBUG>("Json Exception caught.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301088 throw std::runtime_error("Corrupted volatile channel access file");
1089 }
1090 catch (const std::invalid_argument& e)
1091 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301092 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301093 throw std::runtime_error("Corrupted volatile channel access file");
1094 }
1095
1096 // Update the timestamp
1097 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1098 return 0;
1099}
1100
1101int ChannelConfig::readChannelPersistData()
1102{
1103 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1104 channelLock{*channelMutex};
1105
1106 Json data = readJsonFile(channelNvDataFilename);
1107 if (data == nullptr)
1108 {
1109 log<level::DEBUG>("Error in opening IPMI Channel data file");
1110 return -EIO;
1111 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301112 try
1113 {
1114 // Fill in global structure
1115 for (auto it = data.begin(); it != data.end(); ++it)
1116 {
1117 std::string chKey = it.key();
1118 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001119 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301120 {
1121 log<level::DEBUG>(
1122 "Invalid channel access entry in config file");
1123 throw std::out_of_range("Out of range - channel number");
1124 }
1125 Json jsonChData = it.value();
1126 if (!jsonChData.is_null())
1127 {
1128 std::string accModeStr =
1129 jsonChData[accessModeString].get<std::string>();
1130 channelData[chNum].chAccess.chNonVolatileData.accessMode =
1131 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1132 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
1133 jsonChData[userAuthDisabledString].get<bool>();
1134 channelData[chNum]
1135 .chAccess.chNonVolatileData.perMsgAuthDisabled =
1136 jsonChData[perMsgAuthDisabledString].get<bool>();
1137 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
1138 jsonChData[alertingDisabledString].get<bool>();
1139 std::string privStr =
1140 jsonChData[privLimitString].get<std::string>();
1141 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1142 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1143 }
1144 else
1145 {
1146 log<level::ERR>("Invalid/corrupted nv channel access file",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301147 entry("FILE=%s", channelNvDataFilename));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301148 throw std::runtime_error("Corrupted nv channel access file");
1149 }
1150 }
1151 }
1152 catch (const Json::exception& e)
1153 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301154 log<level::DEBUG>("Json Exception caught.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301155 throw std::runtime_error("Corrupted nv channel access file");
1156 }
1157 catch (const std::invalid_argument& e)
1158 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301159 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301160 throw std::runtime_error("Corrupted nv channel access file");
1161 }
1162
1163 // Update the timestamp
1164 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1165 return 0;
1166}
1167
1168int ChannelConfig::writeChannelVolatileData()
1169{
1170 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1171 channelLock{*channelMutex};
1172 Json outData;
1173
1174 try
1175 {
1176 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1177 {
1178 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1179 {
1180 Json jsonObj;
1181 std::string chKey = std::to_string(chNum);
1182 std::string accModeStr = convertToAccessModeString(
1183 channelData[chNum].chAccess.chVolatileData.accessMode);
1184 jsonObj[accessModeString] = accModeStr;
1185 jsonObj[userAuthDisabledString] =
1186 channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
1187 jsonObj[perMsgAuthDisabledString] =
1188 channelData[chNum]
1189 .chAccess.chVolatileData.perMsgAuthDisabled;
1190 jsonObj[alertingDisabledString] =
1191 channelData[chNum].chAccess.chVolatileData.alertingDisabled;
1192 std::string privStr = convertToPrivLimitString(
1193 channelData[chNum].chAccess.chVolatileData.privLimit);
1194 jsonObj[privLimitString] = privStr;
1195
1196 outData[chKey] = jsonObj;
1197 }
1198 }
1199 }
1200 catch (const std::invalid_argument& e)
1201 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301202 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301203 return -EINVAL;
1204 }
1205
1206 if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
1207 {
1208 log<level::DEBUG>("Error in write JSON data to file");
1209 return -EIO;
1210 }
1211
1212 // Update the timestamp
1213 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1214 return 0;
1215}
1216
1217int ChannelConfig::writeChannelPersistData()
1218{
1219 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1220 channelLock{*channelMutex};
1221 Json outData;
1222
1223 try
1224 {
1225 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1226 {
1227 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1228 {
1229 Json jsonObj;
1230 std::string chKey = std::to_string(chNum);
1231 std::string accModeStr = convertToAccessModeString(
1232 channelData[chNum].chAccess.chNonVolatileData.accessMode);
1233 jsonObj[accessModeString] = accModeStr;
1234 jsonObj[userAuthDisabledString] =
1235 channelData[chNum]
1236 .chAccess.chNonVolatileData.userAuthDisabled;
1237 jsonObj[perMsgAuthDisabledString] =
1238 channelData[chNum]
1239 .chAccess.chNonVolatileData.perMsgAuthDisabled;
1240 jsonObj[alertingDisabledString] =
1241 channelData[chNum]
1242 .chAccess.chNonVolatileData.alertingDisabled;
1243 std::string privStr = convertToPrivLimitString(
1244 channelData[chNum].chAccess.chNonVolatileData.privLimit);
1245 jsonObj[privLimitString] = privStr;
1246
1247 outData[chKey] = jsonObj;
1248 }
1249 }
1250 }
1251 catch (const std::invalid_argument& e)
1252 {
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301253 log<level::ERR>("Corrupted config.", entry("MSG=%s", e.what()));
AppaRao Puli071f3f22018-05-24 16:45:30 +05301254 return -EINVAL;
1255 }
1256
1257 if (writeJsonFile(channelNvDataFilename, outData) != 0)
1258 {
1259 log<level::DEBUG>("Error in write JSON data to file");
1260 return -EIO;
1261 }
1262
1263 // Update the timestamp
1264 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1265 return 0;
1266}
1267
1268int ChannelConfig::checkAndReloadNVData()
1269{
1270 std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
1271 int ret = 0;
1272 if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
1273 {
1274 try
1275 {
1276 ret = readChannelPersistData();
1277 }
1278 catch (const std::exception& e)
1279 {
1280 log<level::ERR>("Exception caught in readChannelPersistData.",
1281 entry("MSG=%s", e.what()));
1282 ret = -EIO;
1283 }
1284 }
1285 return ret;
1286}
1287
1288int ChannelConfig::checkAndReloadVolatileData()
1289{
1290 std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
1291 int ret = 0;
1292 if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
1293 {
1294 try
1295 {
1296 ret = readChannelVolatileData();
1297 }
1298 catch (const std::exception& e)
1299 {
1300 log<level::ERR>("Exception caught in readChannelVolatileData.",
1301 entry("MSG=%s", e.what()));
1302 ret = -EIO;
1303 }
1304 }
1305 return ret;
1306}
1307
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001308int ChannelConfig::setDbusProperty(const std::string& service,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301309 const std::string& objPath,
1310 const std::string& interface,
1311 const std::string& property,
1312 const DbusVariant& value)
1313{
1314 try
1315 {
1316 auto method =
1317 bus.new_method_call(service.c_str(), objPath.c_str(),
1318 "org.freedesktop.DBus.Properties", "Set");
1319
1320 method.append(interface, property, value);
1321
1322 auto reply = bus.call(method);
1323 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001324 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301325 {
1326 log<level::DEBUG>("set-property failed",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301327 entry("SERVICE=%s", service.c_str()),
1328 entry("OBJPATH=%s", objPath.c_str()),
1329 entry("INTERFACE=%s", interface.c_str()),
1330 entry("PROP=%s", property.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301331 return -EIO;
1332 }
1333
1334 return 0;
1335}
1336
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001337int ChannelConfig::getDbusProperty(const std::string& service,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301338 const std::string& objPath,
1339 const std::string& interface,
1340 const std::string& property,
1341 DbusVariant& value)
1342{
1343 try
1344 {
1345 auto method =
1346 bus.new_method_call(service.c_str(), objPath.c_str(),
1347 "org.freedesktop.DBus.Properties", "Get");
1348
1349 method.append(interface, property);
1350
1351 auto reply = bus.call(method);
1352 reply.read(value);
1353 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001354 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301355 {
1356 log<level::DEBUG>("get-property failed",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301357 entry("SERVICE=%s", service.c_str()),
1358 entry("OBJPATH=%s", objPath.c_str()),
1359 entry("INTERFACE=%s", interface.c_str()),
1360 entry("PROP=%s", property.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301361 return -EIO;
1362 }
1363 return 0;
1364}
1365
1366int ChannelConfig::syncNetworkChannelConfig()
1367{
1368 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1369 channelLock{*channelMutex};
1370 bool isUpdated = false;
1371 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1372 {
1373 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1374 {
1375 std::string intfPrivStr;
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001376 uint8_t intfPriv = 0;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301377 try
1378 {
AppaRao Puli9613ed72018-09-01 23:46:44 +05301379 std::string networkIntfObj =
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301380 std::string(networkIntfObjectBasePath) + "/" +
1381 channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301382 DbusVariant variant;
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001383 if (0 != getDbusProperty(networkIntfServiceName, networkIntfObj,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301384 networkChConfigIntfName,
1385 privilegePropertyString, variant))
1386 {
1387 log<level::DEBUG>("Network interface does not exist",
Ayushi Smriti05ad3412019-10-16 16:10:18 +05301388 entry("INTERFACE=%s",
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301389 channelData[chNum].chName.c_str()));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301390 continue;
1391 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001392 intfPrivStr = std::get<std::string>(variant);
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001393 intfPriv =
1394 static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301395 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001396 catch (const std::bad_variant_access& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301397 {
1398 log<level::DEBUG>(
1399 "exception: Network interface does not exist");
1400 continue;
1401 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001402 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301403 {
1404 log<level::DEBUG>(
1405 "exception: Network interface does not exist");
1406 continue;
1407 }
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001408 catch (const std::invalid_argument& e)
1409 {
1410 log<level::DEBUG>("exception: Invalid privilege");
1411 continue;
1412 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301413
AppaRao Puli9613ed72018-09-01 23:46:44 +05301414 if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
1415 intfPriv)
1416 {
1417 isUpdated = true;
1418 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1419 intfPriv;
1420 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
1421 }
1422 }
1423 }
1424
1425 if (isUpdated)
1426 {
1427 // Write persistent data to file
1428 if (writeChannelPersistData() != 0)
1429 {
1430 log<level::DEBUG>("Failed to update the persistent data file");
1431 return -EIO;
1432 }
1433 // Write Volatile data to file
1434 if (writeChannelVolatileData() != 0)
1435 {
1436 log<level::DEBUG>("Failed to update the channel volatile data");
1437 return -EIO;
1438 }
1439 }
1440
1441 return 0;
1442}
1443
AppaRao Puli071f3f22018-05-24 16:45:30 +05301444void ChannelConfig::initChannelPersistData()
1445{
Richard Marian Thomaiyare91474c2019-09-01 23:02:47 +05301446 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1447 channelLock{*channelMutex};
1448
AppaRao Puli071f3f22018-05-24 16:45:30 +05301449 /* Always read the channel config */
1450 if (loadChannelConfig() != 0)
1451 {
1452 log<level::ERR>("Failed to read channel config file");
1453 throw std::ios_base::failure("Failed to load channel configuration");
1454 }
1455
1456 /* Populate the channel persist data */
1457 if (readChannelPersistData() != 0)
1458 {
1459 // Copy default NV data to RW location
Patrick Williams3d8d7932022-06-16 12:01:28 -05001460 std::filesystem::copy_file(channelAccessDefaultFilename,
1461 channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301462
1463 // Load the channel access NV data
1464 if (readChannelPersistData() != 0)
1465 {
1466 log<level::ERR>("Failed to read channel access NV data");
1467 throw std::ios_base::failure(
1468 "Failed to read channel access NV configuration");
1469 }
1470 }
1471
1472 // First check the volatile data file
1473 // If not present, load the default values
1474 if (readChannelVolatileData() != 0)
1475 {
1476 // Copy default volatile data to temporary location
1477 // NV file(channelNvDataFilename) must have created by now.
Patrick Williams3d8d7932022-06-16 12:01:28 -05001478 std::filesystem::copy_file(channelNvDataFilename,
1479 channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301480
1481 // Load the channel access volatile data
1482 if (readChannelVolatileData() != 0)
1483 {
1484 log<level::ERR>("Failed to read channel access volatile data");
1485 throw std::ios_base::failure(
1486 "Failed to read channel access volatile configuration");
1487 }
1488 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301489
1490 // Synchronize the channel config(priv) with network channel
1491 // configuration(priv) over dbus
1492 if (syncNetworkChannelConfig() != 0)
1493 {
1494 log<level::ERR>(
1495 "Failed to synchronize data with network channel config over dbus");
1496 throw std::ios_base::failure(
1497 "Failed to synchronize data with network channel config over dbus");
1498 }
1499
1500 log<level::DEBUG>("Successfully completed channel data initialization.");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301501 return;
1502}
1503
1504} // namespace ipmi