blob: 8594d65181fbf4bfd2225736b73fdf98baa6f91d [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
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070019#include "user_layer.hpp"
AppaRao Puli071f3f22018-05-24 16:45:30 +053020
Johnathan Mantey0a2abc82021-02-18 12:39:12 -080021#include <ifaddrs.h>
AppaRao Puli071f3f22018-05-24 16:45:30 +053022#include <sys/stat.h>
Johnathan Mantey0a2abc82021-02-18 12:39:12 -080023#include <sys/types.h>
AppaRao Puli071f3f22018-05-24 16:45:30 +053024#include <unistd.h>
25
26#include <boost/interprocess/sync/scoped_lock.hpp>
George Liu42f64ef2024-02-05 15:03:18 +080027#include <ipmid/utils.hpp>
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -070028#include <phosphor-logging/lg2.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050029#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
AppaRao Puli071f3f22018-05-24 16:45:30 +053041static constexpr const char* channelAccessDefaultFilename =
42 "/usr/share/ipmi-providers/channel_access.json";
43static constexpr const char* channelConfigDefaultFilename =
44 "/usr/share/ipmi-providers/channel_config.json";
45static constexpr const char* channelNvDataFilename =
46 "/var/lib/ipmi/channel_access_nv.json";
47static constexpr const char* channelVolatileDataFilename =
48 "/run/ipmi/channel_access_volatile.json";
49
AppaRao Puli9613ed72018-09-01 23:46:44 +053050// TODO: Get the service name dynamically..
51static constexpr const char* networkIntfServiceName =
52 "xyz.openbmc_project.Network";
53static constexpr const char* networkIntfObjectBasePath =
54 "/xyz/openbmc_project/network";
55static constexpr const char* networkChConfigIntfName =
56 "xyz.openbmc_project.Channel.ChannelAccess";
57static constexpr const char* privilegePropertyString = "MaxPrivilege";
58static constexpr const char* dBusPropertiesInterface =
59 "org.freedesktop.DBus.Properties";
60static constexpr const char* propertiesChangedSignal = "PropertiesChanged";
Willy Tuac05aa12021-11-16 21:15:58 -080061static constexpr const char* interfaceAddedSignal = "InterfacesAdded";
62static constexpr const char* interfaceRemovedSignal = "InterfacesRemoved";
AppaRao Puli9613ed72018-09-01 23:46:44 +053063
AppaRao Puli071f3f22018-05-24 16:45:30 +053064// STRING DEFINES: Should sync with key's in JSON
65static constexpr const char* nameString = "name";
66static constexpr const char* isValidString = "is_valid";
67static constexpr const char* activeSessionsString = "active_sessions";
Vernon Mauery58317122018-11-28 11:02:43 -080068static constexpr const char* maxTransferSizeString = "max_transfer_size";
AppaRao Puli071f3f22018-05-24 16:45:30 +053069static constexpr const char* channelInfoString = "channel_info";
70static constexpr const char* mediumTypeString = "medium_type";
71static constexpr const char* protocolTypeString = "protocol_type";
72static constexpr const char* sessionSupportedString = "session_supported";
73static constexpr const char* isIpmiString = "is_ipmi";
Johnathan Manteyfd61fc32021-04-08 11:05:38 -070074static constexpr const char* isManagementNIC = "is_management_nic";
AppaRao Puli071f3f22018-05-24 16:45:30 +053075static constexpr const char* accessModeString = "access_mode";
76static constexpr const char* userAuthDisabledString = "user_auth_disabled";
77static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
78static constexpr const char* alertingDisabledString = "alerting_disabled";
79static constexpr const char* privLimitString = "priv_limit";
AppaRao Puli071f3f22018-05-24 16:45:30 +053080
81// Default values
82static constexpr const char* defaultChannelName = "RESERVED";
83static constexpr const uint8_t defaultMediumType =
84 static_cast<uint8_t>(EChannelMediumType::reserved);
85static constexpr const uint8_t defaultProtocolType =
86 static_cast<uint8_t>(EChannelProtocolType::reserved);
87static constexpr const uint8_t defaultSessionSupported =
88 static_cast<uint8_t>(EChannelSessSupported::none);
89static constexpr const uint8_t defaultAuthType =
90 static_cast<uint8_t>(EAuthType::none);
91static constexpr const bool defaultIsIpmiState = false;
Vernon Mauery58317122018-11-28 11:02:43 -080092static constexpr size_t smallChannelSize = 64;
AppaRao Puli071f3f22018-05-24 16:45:30 +053093
Lei YU4b0ddb62019-01-25 16:43:50 +080094std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
95 __attribute__((init_priority(101)));
AppaRao Puli9613ed72018-09-01 23:46:44 +053096
Willy Tuac05aa12021-11-16 21:15:58 -080097std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
98 __attribute__((init_priority(101)));
99
100std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
101 __attribute__((init_priority(101)));
102
AppaRao Puli071f3f22018-05-24 16:45:30 +0530103// String mappings use in JSON config file
104static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
105 {"reserved", EChannelMediumType::reserved},
106 {"ipmb", EChannelMediumType::ipmb},
107 {"icmb-v1.0", EChannelMediumType::icmbV10},
108 {"icmb-v0.9", EChannelMediumType::icmbV09},
109 {"lan-802.3", EChannelMediumType::lan8032},
110 {"serial", EChannelMediumType::serial},
111 {"other-lan", EChannelMediumType::otherLan},
112 {"pci-smbus", EChannelMediumType::pciSmbus},
113 {"smbus-v1.0", EChannelMediumType::smbusV11},
114 {"smbus-v2.0", EChannelMediumType::smbusV20},
115 {"usb-1x", EChannelMediumType::usbV1x},
116 {"usb-2x", EChannelMediumType::usbV2x},
117 {"system-interface", EChannelMediumType::systemInterface},
118 {"oem", EChannelMediumType::oem},
119 {"unknown", EChannelMediumType::unknown}};
120
ssekarf4b2b092018-07-25 18:49:08 +0530121static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
Richard Marian Thomaiyar43cb1282018-12-08 17:22:53 +0530122 {interfaceKCS, "SMS"},
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530123 {interfaceLAN1, "eth0"},
ssekarf4b2b092018-07-25 18:49:08 +0530124 {interfaceUnknown, "unknown"}};
125
AppaRao Puli071f3f22018-05-24 16:45:30 +0530126static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
127 {"na", EChannelProtocolType::na},
128 {"ipmb-1.0", EChannelProtocolType::ipmbV10},
129 {"icmb-2.0", EChannelProtocolType::icmbV11},
130 {"reserved", EChannelProtocolType::reserved},
131 {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
132 {"kcs", EChannelProtocolType::kcs},
133 {"smic", EChannelProtocolType::smic},
134 {"bt-10", EChannelProtocolType::bt10},
135 {"bt-15", EChannelProtocolType::bt15},
136 {"tmode", EChannelProtocolType::tMode},
137 {"oem", EChannelProtocolType::oem}};
138
139static std::array<std::string, 4> accessModeList = {
140 "disabled", "pre-boot", "always_available", "shared"};
141
142static std::array<std::string, 4> sessionSupportList = {
143 "session-less", "single-session", "multi-session", "session-based"};
144
Sumanth Bhate4e633e2019-05-14 12:13:57 +0000145const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530146 "priv-reserved", "priv-callback", "priv-user",
147 "priv-operator", "priv-admin", "priv-oem"};
148
Richard Marian Thomaiyar55768e32019-03-02 22:54:37 +0530149std::string ChannelConfig::getChannelName(const uint8_t chNum)
Johnathan Mantey74a21022018-12-13 13:17:56 -0800150{
151 if (!isValidChannel(chNum))
152 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700153 lg2::error("Invalid channel number: {CHANNEL_ID}", "CHANNEL_ID", chNum);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800154 throw std::invalid_argument("Invalid channel number");
155 }
156
157 return channelData[chNum].chName;
158}
159
160int ChannelConfig::convertToChannelNumberFromChannelName(
161 const std::string& chName)
162{
163 for (const auto& it : channelData)
164 {
165 if (it.chName == chName)
166 {
167 return it.chID;
168 }
169 }
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700170 lg2::error("Invalid channel name: {CHANNEL}", "CHANNEL", chName);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800171 throw std::invalid_argument("Invalid channel name");
172
173 return -1;
174}
175
176std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530177{
Peter Foley1214d6c2023-11-01 11:12:42 -0400178 const size_t length = strlen(networkIntfObjectBasePath);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530179 if (((length + 1) >= path.size()) ||
180 path.compare(0, length, networkIntfObjectBasePath))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530181 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700182 lg2::error("Invalid object path: {PATH}", "PATH", path);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530183 throw std::invalid_argument("Invalid object path");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530184 }
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530185 std::string chName(path, length + 1);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800186 return chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530187}
188
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800189void ChannelConfig::processChAccessPropChange(
190 const std::string& path, const DbusChObjProperties& chProperties)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530191{
192 // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
Johnathan Mantey74a21022018-12-13 13:17:56 -0800193 std::string chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530194 try
195 {
Johnathan Mantey74a21022018-12-13 13:17:56 -0800196 chName = getChannelNameFromPath(path);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530197 }
198 catch (const std::invalid_argument& e)
199 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700200 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530201 return;
202 }
203
204 // Get the MaxPrivilege property value from the signal
205 std::string intfPrivStr;
206 std::string propName;
207 for (const auto& prop : chProperties)
208 {
209 if (prop.first == privilegePropertyString)
210 {
211 propName = privilegePropertyString;
Vernon Maueryf442e112019-04-09 11:44:36 -0700212 intfPrivStr = std::get<std::string>(prop.second);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530213 break;
214 }
215 }
216
217 if (propName != privilegePropertyString)
218 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700219 lg2::error("Unknown signal caught.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530220 return;
221 }
222
223 if (intfPrivStr.empty())
224 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700225 lg2::error("Invalid privilege string for intf {INTF}", "INTF", chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530226 return;
227 }
228
229 uint8_t intfPriv = 0;
Johnathan Mantey74a21022018-12-13 13:17:56 -0800230 int chNum;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530231 try
232 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800233 intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800234 chNum = convertToChannelNumberFromChannelName(chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530235 }
236 catch (const std::invalid_argument& e)
237 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700238 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530239 return;
240 }
241
242 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800243 channelLock{*channelMutex};
AppaRao Puli9613ed72018-09-01 23:46:44 +0530244 // skip updating the values, if this property change originated from IPMI.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800245 if (signalFlag & (1 << chNum))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530246 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800247 signalFlag &= ~(1 << chNum);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700248 lg2::debug("Request originated from IPMI so ignoring signal");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530249 return;
250 }
251
252 // Update both volatile & Non-volatile, if there is mismatch.
253 // as property change other than IPMI, has to update both volatile &
254 // non-volatile data.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800255 checkAndReloadVolatileData();
256 checkAndReloadNVData();
257 if (channelData[chNum].chAccess.chNonVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530258 {
259 // Update NV data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800260 channelData[chNum].chAccess.chNonVolatileData.privLimit = intfPriv;
261 if (writeChannelPersistData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530262 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700263 lg2::error("Failed to update the persist data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530264 return;
265 }
266
267 // Update Volatile data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800268 if (channelData[chNum].chAccess.chVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530269 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800270 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
271 if (writeChannelVolatileData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530272 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700273 lg2::error("Failed to update the volatile data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530274 return;
275 }
276 }
277 }
278
279 return;
280}
281
AppaRao Puli071f3f22018-05-24 16:45:30 +0530282ChannelConfig& getChannelConfigObject()
283{
284 static ChannelConfig channelConfig;
285 return channelConfig;
286}
287
AppaRao Puli9613ed72018-09-01 23:46:44 +0530288ChannelConfig::~ChannelConfig()
289{
290 if (signalHndlrObjectState)
291 {
292 chPropertiesSignal.reset();
Willy Tuac05aa12021-11-16 21:15:58 -0800293 chInterfaceAddedSignal.reset();
294 chInterfaceRemovedSignal.reset();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530295 sigHndlrLock.unlock();
296 }
297}
298
AppaRao Puli071f3f22018-05-24 16:45:30 +0530299ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
300{
301 std::ofstream mutexCleanUpFile;
302 mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
303 std::ofstream::out | std::ofstream::app);
304 if (!mutexCleanUpFile.good())
305 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700306 lg2::debug("Unable to open mutex cleanup file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530307 return;
308 }
309 mutexCleanUpFile.close();
310 mutexCleanupLock =
311 boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
312 if (mutexCleanupLock.try_lock())
313 {
314 boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
315 channelMutex =
316 std::make_unique<boost::interprocess::named_recursive_mutex>(
317 boost::interprocess::open_or_create, ipmiChannelMutex);
318 mutexCleanupLock.lock_sharable();
319 }
320 else
321 {
322 mutexCleanupLock.lock_sharable();
323 channelMutex =
324 std::make_unique<boost::interprocess::named_recursive_mutex>(
325 boost::interprocess::open_or_create, ipmiChannelMutex);
326 }
327
328 initChannelPersistData();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530329
330 sigHndlrLock = boost::interprocess::file_lock(channelNvDataFilename);
George Liu1a2e1502022-07-08 12:20:19 +0800331 // Register it for single object and single process either netipmid /
AppaRao Puli9613ed72018-09-01 23:46:44 +0530332 // host-ipmid
333 if (chPropertiesSignal == nullptr && sigHndlrLock.try_lock())
334 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700335 lg2::debug("Registering channel signal handler.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530336 chPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
337 bus,
338 sdbusplus::bus::match::rules::path_namespace(
339 networkIntfObjectBasePath) +
340 sdbusplus::bus::match::rules::type::signal() +
341 sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
342 sdbusplus::bus::match::rules::interface(
343 dBusPropertiesInterface) +
344 sdbusplus::bus::match::rules::argN(0, networkChConfigIntfName),
Patrick Williams5d82f472022-07-22 19:26:53 -0500345 [&](sdbusplus::message_t& msg) {
Patrick Williams1318a5e2024-08-16 15:19:54 -0400346 DbusChObjProperties props;
347 std::string iface;
348 std::string path = msg.get_path();
349 msg.read(iface, props);
350 processChAccessPropChange(path, props);
351 });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530352 signalHndlrObjectState = true;
Willy Tuac05aa12021-11-16 21:15:58 -0800353
354 chInterfaceAddedSignal = std::make_unique<sdbusplus::bus::match_t>(
355 bus,
356 sdbusplus::bus::match::rules::type::signal() +
357 sdbusplus::bus::match::rules::member(interfaceAddedSignal) +
358 sdbusplus::bus::match::rules::argNpath(
359 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500360 [&](sdbusplus::message_t&) { initChannelPersistData(); });
Willy Tuac05aa12021-11-16 21:15:58 -0800361
362 chInterfaceRemovedSignal = std::make_unique<sdbusplus::bus::match_t>(
363 bus,
364 sdbusplus::bus::match::rules::type::signal() +
365 sdbusplus::bus::match::rules::member(interfaceRemovedSignal) +
366 sdbusplus::bus::match::rules::argNpath(
367 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500368 [&](sdbusplus::message_t&) { initChannelPersistData(); });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530369 }
370}
371
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530372bool ChannelConfig::isValidChannel(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530373{
Meera-Kattac1789482021-05-18 09:53:26 +0000374 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530375 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700376 lg2::debug("Invalid channel ID - Out of range");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530377 return false;
378 }
379
380 if (channelData[chNum].isChValid == false)
381 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700382 lg2::debug("Channel is not valid");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530383 }
384
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800385 return channelData[chNum].isChValid;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530386}
387
Patrick Williams69b4c282025-03-03 11:19:13 -0500388EChannelSessSupported ChannelConfig::getChannelSessionSupport(
389 const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530390{
391 EChannelSessSupported chSessSupport =
392 (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
393 return chSessSupport;
394}
395
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530396bool ChannelConfig::isValidAuthType(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530397 const EAuthType& authType)
398{
399 if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
400 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700401 lg2::debug("Invalid authentication type");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530402 return false;
403 }
404
405 uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
406 if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
407 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700408 lg2::debug("Authentication type is not supported.");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530409 return false;
410 }
411
412 return true;
413}
414
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530415int ChannelConfig::getChannelActiveSessions(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530416{
417 // TODO: TEMPORARY FIX
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800418 // Channels active session count is managed separately
AppaRao Puli071f3f22018-05-24 16:45:30 +0530419 // by monitoring channel session which includes LAN and
420 // RAKP layer changes. This will be updated, once the
421 // authentication part is implemented.
422 return channelData[chNum].activeSessCount;
423}
424
Vernon Mauery58317122018-11-28 11:02:43 -0800425size_t ChannelConfig::getChannelMaxTransferSize(uint8_t chNum)
426{
427 return channelData[chNum].maxTransferSize;
428}
429
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000430Cc ChannelConfig::getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530431{
432 if (!isValidChannel(chNum))
433 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700434 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000435 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530436 }
437
438 std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
439 sizeof(channelData[chNum].chInfo),
440 reinterpret_cast<uint8_t*>(&chInfo));
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000441 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530442}
443
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000444Cc ChannelConfig::getChannelAccessData(const uint8_t chNum,
445 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530446{
447 if (!isValidChannel(chNum))
448 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700449 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000450 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530451 }
452
453 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
454 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700455 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000456 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530457 }
458
459 if (checkAndReloadVolatileData() != 0)
460 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000461 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530462 }
463
464 std::copy_n(
465 reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
466 sizeof(channelData[chNum].chAccess.chVolatileData),
467 reinterpret_cast<uint8_t*>(&chAccessData));
468
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000469 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530470}
471
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000472Cc ChannelConfig::setChannelAccessData(const uint8_t chNum,
473 const ChannelAccess& chAccessData,
474 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530475{
476 if (!isValidChannel(chNum))
477 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700478 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000479 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530480 }
481
482 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
483 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700484 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000485 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530486 }
487
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000488 if ((setFlag & setAccessMode) &&
489 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530490 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700491 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000492 return ccAccessModeNotSupportedForChannel;
493 }
494 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
495 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700496 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000497 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530498 }
499
500 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
501 channelLock{*channelMutex};
502
503 if (checkAndReloadVolatileData() != 0)
504 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000505 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530506 }
507
508 if (setFlag & setAccessMode)
509 {
510 channelData[chNum].chAccess.chVolatileData.accessMode =
511 chAccessData.accessMode;
512 }
513 if (setFlag & setUserAuthEnabled)
514 {
515 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
516 chAccessData.userAuthDisabled;
517 }
518 if (setFlag & setMsgAuthEnabled)
519 {
520 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
521 chAccessData.perMsgAuthDisabled;
522 }
523 if (setFlag & setAlertingEnabled)
524 {
525 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
526 chAccessData.alertingDisabled;
527 }
528 if (setFlag & setPrivLimit)
529 {
530 channelData[chNum].chAccess.chVolatileData.privLimit =
531 chAccessData.privLimit;
532 }
533
534 // Write Volatile data to file
535 if (writeChannelVolatileData() != 0)
536 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700537 lg2::debug("Failed to update the channel volatile data");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000538 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530539 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000540 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530541}
542
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000543Cc ChannelConfig::getChannelAccessPersistData(const uint8_t chNum,
544 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530545{
546 if (!isValidChannel(chNum))
547 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700548 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000549 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530550 }
551
552 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
553 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700554 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000555 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530556 }
557
558 if (checkAndReloadNVData() != 0)
559 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000560 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530561 }
562
563 std::copy_n(reinterpret_cast<uint8_t*>(
564 &channelData[chNum].chAccess.chNonVolatileData),
565 sizeof(channelData[chNum].chAccess.chNonVolatileData),
566 reinterpret_cast<uint8_t*>(&chAccessData));
567
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000568 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530569}
570
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000571Cc ChannelConfig::setChannelAccessPersistData(const uint8_t chNum,
572 const ChannelAccess& chAccessData,
573 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530574{
575 if (!isValidChannel(chNum))
576 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700577 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000578 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530579 }
580
581 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
582 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700583 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000584 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530585 }
586
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000587 if ((setFlag & setAccessMode) &&
588 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530589 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700590 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000591 return ccAccessModeNotSupportedForChannel;
592 }
593 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
594 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700595 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000596 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530597 }
598
599 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
600 channelLock{*channelMutex};
601
602 if (checkAndReloadNVData() != 0)
603 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000604 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530605 }
606
607 if (setFlag & setAccessMode)
608 {
609 channelData[chNum].chAccess.chNonVolatileData.accessMode =
610 chAccessData.accessMode;
611 }
612 if (setFlag & setUserAuthEnabled)
613 {
614 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
615 chAccessData.userAuthDisabled;
616 }
617 if (setFlag & setMsgAuthEnabled)
618 {
619 channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
620 chAccessData.perMsgAuthDisabled;
621 }
622 if (setFlag & setAlertingEnabled)
623 {
624 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
625 chAccessData.alertingDisabled;
626 }
627 if (setFlag & setPrivLimit)
628 {
AppaRao Puli9613ed72018-09-01 23:46:44 +0530629 // Send Update to network channel config interfaces over dbus
AppaRao Puli9613ed72018-09-01 23:46:44 +0530630 std::string privStr = convertToPrivLimitString(chAccessData.privLimit);
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530631 std::string networkIntfObj = std::string(networkIntfObjectBasePath) +
632 "/" + channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530633 try
634 {
Johnathan Manteyf92261d2018-12-10 15:49:34 -0800635 if (0 != setDbusProperty(networkIntfServiceName, networkIntfObj,
636 networkChConfigIntfName,
AppaRao Puli9613ed72018-09-01 23:46:44 +0530637 privilegePropertyString, privStr))
638 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700639 lg2::debug("Network interface '{INTERFACE}' does not exist",
640 "INTERFACE", channelData[chNum].chName);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000641 return ccUnspecifiedError;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530642 }
643 }
Patrick Williams5d82f472022-07-22 19:26:53 -0500644 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530645 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700646 lg2::error("Exception: Network interface does not exist");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000647 return ccInvalidFieldRequest;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530648 }
649 signalFlag |= (1 << chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530650 channelData[chNum].chAccess.chNonVolatileData.privLimit =
651 chAccessData.privLimit;
652 }
653
654 // Write persistent data to file
655 if (writeChannelPersistData() != 0)
656 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700657 lg2::debug("Failed to update the presist data file");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000658 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530659 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000660 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530661}
662
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000663Cc ChannelConfig::getChannelAuthTypeSupported(const uint8_t chNum,
664 uint8_t& authTypeSupported)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530665{
666 if (!isValidChannel(chNum))
667 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700668 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000669 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530670 }
671
672 authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000673 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530674}
675
Patrick Williams1318a5e2024-08-16 15:19:54 -0400676Cc ChannelConfig::getChannelEnabledAuthType(
677 const uint8_t chNum, const uint8_t priv, EAuthType& authType)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530678{
679 if (!isValidChannel(chNum))
680 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700681 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000682 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530683 }
684
685 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
686 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700687 lg2::debug("Sessionless channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000688 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530689 }
690
691 if (!isValidPrivLimit(priv))
692 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700693 lg2::debug("Invalid privilege specified.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000694 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530695 }
696
697 // TODO: Hardcoded for now. Need to implement.
698 authType = EAuthType::none;
699
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000700 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530701}
702
703std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
704{
705 struct stat fileStat;
706 if (stat(fileName.c_str(), &fileStat) != 0)
707 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700708 lg2::debug("Error in getting last updated time stamp");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530709 return -EIO;
710 }
711 return fileStat.st_mtime;
712}
713
Patrick Williams69b4c282025-03-03 11:19:13 -0500714EChannelAccessMode ChannelConfig::convertToAccessModeIndex(
715 const std::string& mode)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530716{
717 auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
718 if (iter == accessModeList.end())
719 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700720 lg2::error("Invalid access mode: {MODE_STR}", "MODE_STR", mode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530721 throw std::invalid_argument("Invalid access mode.");
722 }
723
724 return static_cast<EChannelAccessMode>(
725 std::distance(accessModeList.begin(), iter));
726}
727
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530728std::string ChannelConfig::convertToAccessModeString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530729{
730 if (accessModeList.size() <= value)
731 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700732 lg2::error("Invalid access mode: {MODE_IDX}", "MODE_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530733 throw std::invalid_argument("Invalid access mode.");
734 }
735
736 return accessModeList.at(value);
737}
738
Patrick Williams69b4c282025-03-03 11:19:13 -0500739CommandPrivilege ChannelConfig::convertToPrivLimitIndex(
740 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530741{
742 auto iter = std::find(privList.begin(), privList.end(), value);
743 if (iter == privList.end())
744 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700745 lg2::error("Invalid privilege: {PRIV_STR}", "PRIV_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530746 throw std::invalid_argument("Invalid privilege.");
747 }
748
749 return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
750}
751
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530752std::string ChannelConfig::convertToPrivLimitString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530753{
754 if (privList.size() <= value)
755 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700756 lg2::error("Invalid privilege: {PRIV_IDX.", "PRIV_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530757 throw std::invalid_argument("Invalid privilege.");
758 }
759
760 return privList.at(value);
761}
762
Patrick Williams69b4c282025-03-03 11:19:13 -0500763EChannelSessSupported ChannelConfig::convertToSessionSupportIndex(
764 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530765{
Patrick Williams1318a5e2024-08-16 15:19:54 -0400766 auto iter =
767 std::find(sessionSupportList.begin(), sessionSupportList.end(), value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530768 if (iter == sessionSupportList.end())
769 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700770 lg2::error("Invalid session supported: {SESS_STR}", "SESS_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530771 throw std::invalid_argument("Invalid session supported.");
772 }
773
774 return static_cast<EChannelSessSupported>(
775 std::distance(sessionSupportList.begin(), iter));
776}
777
Patrick Williams69b4c282025-03-03 11:19:13 -0500778EChannelMediumType ChannelConfig::convertToMediumTypeIndex(
779 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530780{
781 std::unordered_map<std::string, EChannelMediumType>::iterator it =
782 mediumTypeMap.find(value);
783 if (it == mediumTypeMap.end())
784 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700785 lg2::error("Invalid medium type: {MEDIUM_STR}", "MEDIUM_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530786 throw std::invalid_argument("Invalid medium type.");
787 }
788
789 return static_cast<EChannelMediumType>(it->second);
790}
791
Patrick Williams69b4c282025-03-03 11:19:13 -0500792EChannelProtocolType ChannelConfig::convertToProtocolTypeIndex(
793 const std::string& value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530794{
795 std::unordered_map<std::string, EChannelProtocolType>::iterator it =
796 protocolTypeMap.find(value);
797 if (it == protocolTypeMap.end())
798 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700799 lg2::error("Invalid protocol type: {PROTO_STR}", "PROTO_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530800 throw std::invalid_argument("Invalid protocol type.");
801 }
802
803 return static_cast<EChannelProtocolType>(it->second);
804}
805
806Json ChannelConfig::readJsonFile(const std::string& configFile)
807{
808 std::ifstream jsonFile(configFile);
809 if (!jsonFile.good())
810 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700811 lg2::info("JSON file '{FILE_NAME}' not found", "FILE_NAME", configFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530812 return nullptr;
813 }
814
815 Json data = nullptr;
816 try
817 {
818 data = Json::parse(jsonFile, nullptr, false);
819 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500820 catch (const Json::parse_error& e)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530821 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700822 lg2::debug("Corrupted channel config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +0530823 throw std::runtime_error("Corrupted channel config file");
824 }
825
826 return data;
827}
828
829int ChannelConfig::writeJsonFile(const std::string& configFile,
830 const Json& jsonData)
831{
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530832 const std::string tmpFile = configFile + "_tmp";
833 int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
834 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
835 if (fd < 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530836 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700837 lg2::error("Error in creating json file '{FILE_NAME}'", "FILE_NAME",
838 tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530839 return -EIO;
840 }
841 const auto& writeData = jsonData.dump();
842 if (write(fd, writeData.c_str(), writeData.size()) !=
843 static_cast<ssize_t>(writeData.size()))
844 {
845 close(fd);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700846 lg2::error("Error in writing configuration file '{FILE_NAME}'",
847 "FILE_NAME", tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530848 return -EIO;
849 }
850 close(fd);
851
852 if (std::rename(tmpFile.c_str(), configFile.c_str()) != 0)
853 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700854 lg2::error("Error in renaming temporary data file '{FILE_NAME}'",
855 "FILE_NAME", tmpFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530856 return -EIO;
857 }
858
AppaRao Puli071f3f22018-05-24 16:45:30 +0530859 return 0;
860}
861
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530862void ChannelConfig::setDefaultChannelConfig(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530863 const std::string& chName)
864{
865 channelData[chNum].chName = chName;
866 channelData[chNum].chID = chNum;
867 channelData[chNum].isChValid = false;
868 channelData[chNum].activeSessCount = 0;
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700869 channelData[chNum].isManagementNIC = false;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530870
871 channelData[chNum].chInfo.mediumType = defaultMediumType;
872 channelData[chNum].chInfo.protocolType = defaultProtocolType;
873 channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
874 channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
875 channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
876}
877
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700878uint8_t ChannelConfig::getManagementNICID()
879{
880 static bool idFound = false;
881 static uint8_t id = 0;
882
883 if (idFound)
884 {
885 return id;
886 }
887
888 for (uint8_t chIdx = 0; chIdx < maxIpmiChannels; chIdx++)
889 {
890 if (channelData[chIdx].isManagementNIC)
891 {
892 id = chIdx;
893 idFound = true;
894 break;
895 }
896 }
897
898 if (!idFound)
899 {
900 id = static_cast<uint8_t>(EChannelID::chanLan1);
901 idFound = true;
902 }
903 return id;
904}
905
AppaRao Puli071f3f22018-05-24 16:45:30 +0530906int ChannelConfig::loadChannelConfig()
907{
908 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
909 channelLock{*channelMutex};
910
911 Json data = readJsonFile(channelConfigDefaultFilename);
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800912 if (data.empty())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530913 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700914 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530915 return -EIO;
916 }
917
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800918 channelData.fill(ChannelProperties{});
919
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800920 // Collect the list of NIC interfaces connected to the BMC. Use this
921 // information to only add IPMI channels that have active NIC interfaces.
Snehalatha Venkatesh55f5d532021-07-13 11:06:36 +0000922 struct ifaddrs *ifaddr = nullptr, *ifa = nullptr;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800923 if (int err = getifaddrs(&ifaddr); err < 0)
924 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700925 lg2::debug("Unable to acquire network interfaces");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800926 return -EIO;
927 }
928
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800929 for (int chNum = 0; chNum < maxIpmiChannels; chNum++)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530930 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800931 try
AppaRao Puli071f3f22018-05-24 16:45:30 +0530932 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530933 std::string chKey = std::to_string(chNum);
934 Json jsonChData = data[chKey].get<Json>();
935 if (jsonChData.is_null())
936 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530937 // If user didn't want to configure specific channel (say
938 // reserved channel), then load that index with default values.
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800939 setDefaultChannelConfig(chNum, defaultChannelName);
940 continue;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530941 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800942 Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
943 if (jsonChInfo.is_null())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530944 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700945 lg2::error("Invalid/corrupted channel config file");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800946 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800947 return -EBADMSG;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530948 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800949
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800950 bool channelFound = true;
951 // Confirm the LAN channel is present
952 if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
953 {
954 channelFound = false;
Jayanth Othayotha6fb32d2024-12-15 10:55:22 -0600955 for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800956 {
957 if (jsonChData[nameString].get<std::string>() ==
958 ifa->ifa_name)
959 {
960 channelFound = true;
961 break;
962 }
963 }
964 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800965 ChannelProperties& chData = channelData[chNum];
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800966 chData.chID = chNum;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800967 chData.chName = jsonChData[nameString].get<std::string>();
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500968 chData.isChValid = channelFound &&
969 jsonChData[isValidString].get<bool>();
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800970 chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400971 chData.maxTransferSize =
972 jsonChData.value(maxTransferSizeString, smallChannelSize);
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700973 if (jsonChData.count(isManagementNIC) != 0)
974 {
975 chData.isManagementNIC =
976 jsonChData[isManagementNIC].get<bool>();
977 }
978
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800979 std::string medTypeStr =
980 jsonChInfo[mediumTypeString].get<std::string>();
981 chData.chInfo.mediumType =
982 static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
983 std::string protoTypeStr =
984 jsonChInfo[protocolTypeString].get<std::string>();
985 chData.chInfo.protocolType =
986 static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
987 std::string sessStr =
988 jsonChInfo[sessionSupportedString].get<std::string>();
989 chData.chInfo.sessionSupported =
990 static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
991 chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
992 chData.chInfo.authTypeSupported = defaultAuthType;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530993 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800994 catch (const Json::exception& e)
995 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700996 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800997 freeifaddrs(ifaddr);
998
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800999 return -EBADMSG;
1000 }
1001 catch (const std::invalid_argument& e)
1002 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001003 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001004 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001005 return -EBADMSG;
1006 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301007 }
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001008 freeifaddrs(ifaddr);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301009
1010 return 0;
1011}
1012
1013int ChannelConfig::readChannelVolatileData()
1014{
1015 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1016 channelLock{*channelMutex};
1017
1018 Json data = readJsonFile(channelVolatileDataFilename);
1019 if (data == nullptr)
1020 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001021 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301022 return -EIO;
1023 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301024 try
1025 {
1026 // Fill in global structure
1027 for (auto it = data.begin(); it != data.end(); ++it)
1028 {
1029 std::string chKey = it.key();
1030 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001031 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301032 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001033 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301034 throw std::out_of_range("Out of range - channel number");
1035 }
1036 Json jsonChData = it.value();
1037 if (!jsonChData.is_null())
1038 {
1039 std::string accModeStr =
1040 jsonChData[accessModeString].get<std::string>();
1041 channelData[chNum].chAccess.chVolatileData.accessMode =
1042 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1043 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
1044 jsonChData[userAuthDisabledString].get<bool>();
1045 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
1046 jsonChData[perMsgAuthDisabledString].get<bool>();
1047 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
1048 jsonChData[alertingDisabledString].get<bool>();
1049 std::string privStr =
1050 jsonChData[privLimitString].get<std::string>();
1051 channelData[chNum].chAccess.chVolatileData.privLimit =
1052 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1053 }
1054 else
1055 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001056 lg2::error(
1057 "Invalid/corrupted volatile channel access file '{FILE}'",
1058 "FILE", channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301059 throw std::runtime_error(
1060 "Corrupted volatile channel access file");
1061 }
1062 }
1063 }
1064 catch (const Json::exception& e)
1065 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001066 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301067 throw std::runtime_error("Corrupted volatile channel access file");
1068 }
1069 catch (const std::invalid_argument& e)
1070 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001071 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301072 throw std::runtime_error("Corrupted volatile channel access file");
1073 }
1074
1075 // Update the timestamp
1076 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1077 return 0;
1078}
1079
1080int ChannelConfig::readChannelPersistData()
1081{
1082 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1083 channelLock{*channelMutex};
1084
1085 Json data = readJsonFile(channelNvDataFilename);
1086 if (data == nullptr)
1087 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001088 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301089 return -EIO;
1090 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301091 try
1092 {
1093 // Fill in global structure
1094 for (auto it = data.begin(); it != data.end(); ++it)
1095 {
1096 std::string chKey = it.key();
1097 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001098 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301099 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001100 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301101 throw std::out_of_range("Out of range - channel number");
1102 }
1103 Json jsonChData = it.value();
1104 if (!jsonChData.is_null())
1105 {
1106 std::string accModeStr =
1107 jsonChData[accessModeString].get<std::string>();
1108 channelData[chNum].chAccess.chNonVolatileData.accessMode =
1109 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1110 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
1111 jsonChData[userAuthDisabledString].get<bool>();
1112 channelData[chNum]
1113 .chAccess.chNonVolatileData.perMsgAuthDisabled =
1114 jsonChData[perMsgAuthDisabledString].get<bool>();
1115 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
1116 jsonChData[alertingDisabledString].get<bool>();
1117 std::string privStr =
1118 jsonChData[privLimitString].get<std::string>();
1119 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1120 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1121 }
1122 else
1123 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001124 lg2::error("Invalid/corrupted nv channel access file {FILE}",
1125 "FILE", channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301126 throw std::runtime_error("Corrupted nv channel access file");
1127 }
1128 }
1129 }
1130 catch (const Json::exception& e)
1131 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001132 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301133 throw std::runtime_error("Corrupted nv channel access file");
1134 }
1135 catch (const std::invalid_argument& e)
1136 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001137 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301138 throw std::runtime_error("Corrupted nv channel access file");
1139 }
1140
1141 // Update the timestamp
1142 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1143 return 0;
1144}
1145
1146int ChannelConfig::writeChannelVolatileData()
1147{
1148 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1149 channelLock{*channelMutex};
1150 Json outData;
1151
1152 try
1153 {
1154 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1155 {
1156 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1157 {
1158 Json jsonObj;
1159 std::string chKey = std::to_string(chNum);
1160 std::string accModeStr = convertToAccessModeString(
1161 channelData[chNum].chAccess.chVolatileData.accessMode);
1162 jsonObj[accessModeString] = accModeStr;
1163 jsonObj[userAuthDisabledString] =
1164 channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
1165 jsonObj[perMsgAuthDisabledString] =
1166 channelData[chNum]
1167 .chAccess.chVolatileData.perMsgAuthDisabled;
1168 jsonObj[alertingDisabledString] =
1169 channelData[chNum].chAccess.chVolatileData.alertingDisabled;
1170 std::string privStr = convertToPrivLimitString(
1171 channelData[chNum].chAccess.chVolatileData.privLimit);
1172 jsonObj[privLimitString] = privStr;
1173
1174 outData[chKey] = jsonObj;
1175 }
1176 }
1177 }
1178 catch (const std::invalid_argument& e)
1179 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001180 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301181 return -EINVAL;
1182 }
1183
1184 if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
1185 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001186 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301187 return -EIO;
1188 }
1189
1190 // Update the timestamp
1191 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1192 return 0;
1193}
1194
1195int ChannelConfig::writeChannelPersistData()
1196{
1197 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1198 channelLock{*channelMutex};
1199 Json outData;
1200
1201 try
1202 {
1203 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1204 {
1205 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1206 {
1207 Json jsonObj;
1208 std::string chKey = std::to_string(chNum);
1209 std::string accModeStr = convertToAccessModeString(
1210 channelData[chNum].chAccess.chNonVolatileData.accessMode);
1211 jsonObj[accessModeString] = accModeStr;
1212 jsonObj[userAuthDisabledString] =
1213 channelData[chNum]
1214 .chAccess.chNonVolatileData.userAuthDisabled;
1215 jsonObj[perMsgAuthDisabledString] =
1216 channelData[chNum]
1217 .chAccess.chNonVolatileData.perMsgAuthDisabled;
1218 jsonObj[alertingDisabledString] =
1219 channelData[chNum]
1220 .chAccess.chNonVolatileData.alertingDisabled;
1221 std::string privStr = convertToPrivLimitString(
1222 channelData[chNum].chAccess.chNonVolatileData.privLimit);
1223 jsonObj[privLimitString] = privStr;
1224
1225 outData[chKey] = jsonObj;
1226 }
1227 }
1228 }
1229 catch (const std::invalid_argument& e)
1230 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001231 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301232 return -EINVAL;
1233 }
1234
1235 if (writeJsonFile(channelNvDataFilename, outData) != 0)
1236 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001237 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301238 return -EIO;
1239 }
1240
1241 // Update the timestamp
1242 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1243 return 0;
1244}
1245
1246int ChannelConfig::checkAndReloadNVData()
1247{
1248 std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
1249 int ret = 0;
1250 if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
1251 {
1252 try
1253 {
1254 ret = readChannelPersistData();
1255 }
1256 catch (const std::exception& e)
1257 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001258 lg2::error("Exception caught in readChannelPersistData: {MSG}",
1259 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301260 ret = -EIO;
1261 }
1262 }
1263 return ret;
1264}
1265
1266int ChannelConfig::checkAndReloadVolatileData()
1267{
1268 std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
1269 int ret = 0;
1270 if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
1271 {
1272 try
1273 {
1274 ret = readChannelVolatileData();
1275 }
1276 catch (const std::exception& e)
1277 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001278 lg2::error("Exception caught in readChannelVolatileData: {MSG}",
1279 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301280 ret = -EIO;
1281 }
1282 }
1283 return ret;
1284}
1285
Patrick Williams1318a5e2024-08-16 15:19:54 -04001286int ChannelConfig::setDbusProperty(
1287 const std::string& service, const std::string& objPath,
1288 const std::string& interface, const std::string& property,
1289 const DbusVariant& value)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301290{
1291 try
1292 {
Patrick Williams1318a5e2024-08-16 15:19:54 -04001293 auto method =
1294 bus.new_method_call(service.c_str(), objPath.c_str(),
1295 "org.freedesktop.DBus.Properties", "Set");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301296
1297 method.append(interface, property, value);
1298
1299 auto reply = bus.call(method);
1300 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001301 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301302 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001303 lg2::debug(
1304 "set-property {SERVICE}:{OBJPATH}/{INTERFACE}.{PROP} failed: {MSG}",
1305 "SERVICE", service, "OBJPATH", objPath, "INTERFACE", interface,
George Liu5a398942025-01-24 09:16:43 +08001306 "PROP", property, "MSG", e);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301307 return -EIO;
1308 }
1309
1310 return 0;
1311}
1312
AppaRao Puli9613ed72018-09-01 23:46:44 +05301313int ChannelConfig::syncNetworkChannelConfig()
1314{
1315 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1316 channelLock{*channelMutex};
1317 bool isUpdated = false;
1318 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1319 {
1320 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1321 {
1322 std::string intfPrivStr;
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001323 uint8_t intfPriv = 0;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301324 try
1325 {
AppaRao Puli9613ed72018-09-01 23:46:44 +05301326 std::string networkIntfObj =
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301327 std::string(networkIntfObjectBasePath) + "/" +
1328 channelData[chNum].chName;
George Liu42f64ef2024-02-05 15:03:18 +08001329 auto propValue = ipmi::getDbusProperty(
1330 bus, networkIntfServiceName, networkIntfObj,
1331 networkChConfigIntfName, privilegePropertyString);
1332
1333 intfPrivStr = std::get<std::string>(propValue);
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001334 intfPriv =
1335 static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301336 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001337 catch (const std::bad_variant_access& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301338 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001339 lg2::debug("Network interface '{INTERFACE}' does not exist",
1340 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301341 continue;
1342 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001343 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301344 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001345 lg2::debug("Network interface '{INTERFACE}' does not exist",
1346 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301347 continue;
1348 }
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001349 catch (const std::invalid_argument& e)
1350 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001351 lg2::debug("exception: Invalid privilege");
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001352 continue;
1353 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301354
AppaRao Puli9613ed72018-09-01 23:46:44 +05301355 if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
1356 intfPriv)
1357 {
1358 isUpdated = true;
1359 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1360 intfPriv;
1361 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
1362 }
1363 }
1364 }
1365
1366 if (isUpdated)
1367 {
1368 // Write persistent data to file
1369 if (writeChannelPersistData() != 0)
1370 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001371 lg2::debug("Failed to update the persistent data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301372 return -EIO;
1373 }
1374 // Write Volatile data to file
1375 if (writeChannelVolatileData() != 0)
1376 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001377 lg2::debug("Failed to update the channel volatile data");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301378 return -EIO;
1379 }
1380 }
1381
1382 return 0;
1383}
1384
AppaRao Puli071f3f22018-05-24 16:45:30 +05301385void ChannelConfig::initChannelPersistData()
1386{
Richard Marian Thomaiyare91474c2019-09-01 23:02:47 +05301387 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1388 channelLock{*channelMutex};
1389
AppaRao Puli071f3f22018-05-24 16:45:30 +05301390 /* Always read the channel config */
1391 if (loadChannelConfig() != 0)
1392 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001393 lg2::error("Failed to read channel config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301394 throw std::ios_base::failure("Failed to load channel configuration");
1395 }
1396
1397 /* Populate the channel persist data */
1398 if (readChannelPersistData() != 0)
1399 {
1400 // Copy default NV data to RW location
Patrick Williams3d8d7932022-06-16 12:01:28 -05001401 std::filesystem::copy_file(channelAccessDefaultFilename,
1402 channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301403
1404 // Load the channel access NV data
1405 if (readChannelPersistData() != 0)
1406 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001407 lg2::error("Failed to read channel access NV data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301408 throw std::ios_base::failure(
1409 "Failed to read channel access NV configuration");
1410 }
1411 }
1412
1413 // First check the volatile data file
1414 // If not present, load the default values
1415 if (readChannelVolatileData() != 0)
1416 {
1417 // Copy default volatile data to temporary location
1418 // NV file(channelNvDataFilename) must have created by now.
Patrick Williams3d8d7932022-06-16 12:01:28 -05001419 std::filesystem::copy_file(channelNvDataFilename,
1420 channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301421
1422 // Load the channel access volatile data
1423 if (readChannelVolatileData() != 0)
1424 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001425 lg2::error("Failed to read channel access volatile data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301426 throw std::ios_base::failure(
1427 "Failed to read channel access volatile configuration");
1428 }
1429 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301430
1431 // Synchronize the channel config(priv) with network channel
1432 // configuration(priv) over dbus
1433 if (syncNetworkChannelConfig() != 0)
1434 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001435 lg2::error(
AppaRao Puli9613ed72018-09-01 23:46:44 +05301436 "Failed to synchronize data with network channel config over dbus");
1437 throw std::ios_base::failure(
1438 "Failed to synchronize data with network channel config over dbus");
1439 }
1440
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001441 lg2::debug("Successfully completed channel data initialization.");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301442 return;
1443}
1444
1445} // namespace ipmi