blob: ed123ad7039848f54f44f4fb9800f268edda1996 [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>
George Liu42f64ef2024-02-05 15:03:18 +080028#include <ipmid/utils.hpp>
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -070029#include <phosphor-logging/lg2.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050030#include <sdbusplus/bus/match.hpp>
31#include <sdbusplus/server/object.hpp>
32
AppaRao Puli071f3f22018-05-24 16:45:30 +053033#include <cerrno>
AppaRao Puli9613ed72018-09-01 23:46:44 +053034#include <exception>
Patrick Williams3d8d7932022-06-16 12:01:28 -050035#include <filesystem>
AppaRao Puli071f3f22018-05-24 16:45:30 +053036#include <fstream>
AppaRao Puli071f3f22018-05-24 16:45:30 +053037#include <unordered_map>
38
39namespace ipmi
40{
41
AppaRao Puli071f3f22018-05-24 16:45:30 +053042static 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* accessModeString = "access_mode";
77static constexpr const char* userAuthDisabledString = "user_auth_disabled";
78static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
79static constexpr const char* alertingDisabledString = "alerting_disabled";
80static constexpr const char* privLimitString = "priv_limit";
AppaRao Puli071f3f22018-05-24 16:45:30 +053081
82// Default values
83static constexpr const char* defaultChannelName = "RESERVED";
84static constexpr const uint8_t defaultMediumType =
85 static_cast<uint8_t>(EChannelMediumType::reserved);
86static constexpr const uint8_t defaultProtocolType =
87 static_cast<uint8_t>(EChannelProtocolType::reserved);
88static constexpr const uint8_t defaultSessionSupported =
89 static_cast<uint8_t>(EChannelSessSupported::none);
90static constexpr const uint8_t defaultAuthType =
91 static_cast<uint8_t>(EAuthType::none);
92static constexpr const bool defaultIsIpmiState = false;
Vernon Mauery58317122018-11-28 11:02:43 -080093static constexpr size_t smallChannelSize = 64;
AppaRao Puli071f3f22018-05-24 16:45:30 +053094
Lei YU4b0ddb62019-01-25 16:43:50 +080095std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
96 __attribute__((init_priority(101)));
AppaRao Puli9613ed72018-09-01 23:46:44 +053097
Willy Tuac05aa12021-11-16 21:15:58 -080098std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
99 __attribute__((init_priority(101)));
100
101std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
102 __attribute__((init_priority(101)));
103
AppaRao Puli071f3f22018-05-24 16:45:30 +0530104// String mappings use in JSON config file
105static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
106 {"reserved", EChannelMediumType::reserved},
107 {"ipmb", EChannelMediumType::ipmb},
108 {"icmb-v1.0", EChannelMediumType::icmbV10},
109 {"icmb-v0.9", EChannelMediumType::icmbV09},
110 {"lan-802.3", EChannelMediumType::lan8032},
111 {"serial", EChannelMediumType::serial},
112 {"other-lan", EChannelMediumType::otherLan},
113 {"pci-smbus", EChannelMediumType::pciSmbus},
114 {"smbus-v1.0", EChannelMediumType::smbusV11},
115 {"smbus-v2.0", EChannelMediumType::smbusV20},
116 {"usb-1x", EChannelMediumType::usbV1x},
117 {"usb-2x", EChannelMediumType::usbV2x},
118 {"system-interface", EChannelMediumType::systemInterface},
119 {"oem", EChannelMediumType::oem},
120 {"unknown", EChannelMediumType::unknown}};
121
ssekarf4b2b092018-07-25 18:49:08 +0530122static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
Richard Marian Thomaiyar43cb1282018-12-08 17:22:53 +0530123 {interfaceKCS, "SMS"},
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530124 {interfaceLAN1, "eth0"},
ssekarf4b2b092018-07-25 18:49:08 +0530125 {interfaceUnknown, "unknown"}};
126
AppaRao Puli071f3f22018-05-24 16:45:30 +0530127static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
128 {"na", EChannelProtocolType::na},
129 {"ipmb-1.0", EChannelProtocolType::ipmbV10},
130 {"icmb-2.0", EChannelProtocolType::icmbV11},
131 {"reserved", EChannelProtocolType::reserved},
132 {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
133 {"kcs", EChannelProtocolType::kcs},
134 {"smic", EChannelProtocolType::smic},
135 {"bt-10", EChannelProtocolType::bt10},
136 {"bt-15", EChannelProtocolType::bt15},
137 {"tmode", EChannelProtocolType::tMode},
138 {"oem", EChannelProtocolType::oem}};
139
140static std::array<std::string, 4> accessModeList = {
141 "disabled", "pre-boot", "always_available", "shared"};
142
143static std::array<std::string, 4> sessionSupportList = {
144 "session-less", "single-session", "multi-session", "session-based"};
145
Sumanth Bhate4e633e2019-05-14 12:13:57 +0000146const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530147 "priv-reserved", "priv-callback", "priv-user",
148 "priv-operator", "priv-admin", "priv-oem"};
149
Richard Marian Thomaiyar55768e32019-03-02 22:54:37 +0530150std::string ChannelConfig::getChannelName(const uint8_t chNum)
Johnathan Mantey74a21022018-12-13 13:17:56 -0800151{
152 if (!isValidChannel(chNum))
153 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700154 lg2::error("Invalid channel number: {CHANNEL_ID}", "CHANNEL_ID", chNum);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800155 throw std::invalid_argument("Invalid channel number");
156 }
157
158 return channelData[chNum].chName;
159}
160
161int ChannelConfig::convertToChannelNumberFromChannelName(
162 const std::string& chName)
163{
164 for (const auto& it : channelData)
165 {
166 if (it.chName == chName)
167 {
168 return it.chID;
169 }
170 }
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700171 lg2::error("Invalid channel name: {CHANNEL}", "CHANNEL", chName);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800172 throw std::invalid_argument("Invalid channel name");
173
174 return -1;
175}
176
177std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530178{
Peter Foley1214d6c2023-11-01 11:12:42 -0400179 const size_t length = strlen(networkIntfObjectBasePath);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530180 if (((length + 1) >= path.size()) ||
181 path.compare(0, length, networkIntfObjectBasePath))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530182 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700183 lg2::error("Invalid object path: {PATH}", "PATH", path);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530184 throw std::invalid_argument("Invalid object path");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530185 }
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530186 std::string chName(path, length + 1);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800187 return chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530188}
189
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800190void ChannelConfig::processChAccessPropChange(
191 const std::string& path, const DbusChObjProperties& chProperties)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530192{
193 // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
Johnathan Mantey74a21022018-12-13 13:17:56 -0800194 std::string chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530195 try
196 {
Johnathan Mantey74a21022018-12-13 13:17:56 -0800197 chName = getChannelNameFromPath(path);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530198 }
199 catch (const std::invalid_argument& e)
200 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700201 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530202 return;
203 }
204
205 // Get the MaxPrivilege property value from the signal
206 std::string intfPrivStr;
207 std::string propName;
208 for (const auto& prop : chProperties)
209 {
210 if (prop.first == privilegePropertyString)
211 {
212 propName = privilegePropertyString;
Vernon Maueryf442e112019-04-09 11:44:36 -0700213 intfPrivStr = std::get<std::string>(prop.second);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530214 break;
215 }
216 }
217
218 if (propName != privilegePropertyString)
219 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700220 lg2::error("Unknown signal caught.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530221 return;
222 }
223
224 if (intfPrivStr.empty())
225 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700226 lg2::error("Invalid privilege string for intf {INTF}", "INTF", chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530227 return;
228 }
229
230 uint8_t intfPriv = 0;
Johnathan Mantey74a21022018-12-13 13:17:56 -0800231 int chNum;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530232 try
233 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800234 intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800235 chNum = convertToChannelNumberFromChannelName(chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530236 }
237 catch (const std::invalid_argument& e)
238 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700239 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530240 return;
241 }
242
243 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800244 channelLock{*channelMutex};
AppaRao Puli9613ed72018-09-01 23:46:44 +0530245 // skip updating the values, if this property change originated from IPMI.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800246 if (signalFlag & (1 << chNum))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530247 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800248 signalFlag &= ~(1 << chNum);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700249 lg2::debug("Request originated from IPMI so ignoring signal");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530250 return;
251 }
252
253 // Update both volatile & Non-volatile, if there is mismatch.
254 // as property change other than IPMI, has to update both volatile &
255 // non-volatile data.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800256 checkAndReloadVolatileData();
257 checkAndReloadNVData();
258 if (channelData[chNum].chAccess.chNonVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530259 {
260 // Update NV data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800261 channelData[chNum].chAccess.chNonVolatileData.privLimit = intfPriv;
262 if (writeChannelPersistData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530263 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700264 lg2::error("Failed to update the persist data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530265 return;
266 }
267
268 // Update Volatile data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800269 if (channelData[chNum].chAccess.chVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530270 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800271 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
272 if (writeChannelVolatileData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530273 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700274 lg2::error("Failed to update the volatile data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530275 return;
276 }
277 }
278 }
279
280 return;
281}
282
AppaRao Puli071f3f22018-05-24 16:45:30 +0530283ChannelConfig& getChannelConfigObject()
284{
285 static ChannelConfig channelConfig;
286 return channelConfig;
287}
288
AppaRao Puli9613ed72018-09-01 23:46:44 +0530289ChannelConfig::~ChannelConfig()
290{
291 if (signalHndlrObjectState)
292 {
293 chPropertiesSignal.reset();
Willy Tuac05aa12021-11-16 21:15:58 -0800294 chInterfaceAddedSignal.reset();
295 chInterfaceRemovedSignal.reset();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530296 sigHndlrLock.unlock();
297 }
298}
299
AppaRao Puli071f3f22018-05-24 16:45:30 +0530300ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
301{
302 std::ofstream mutexCleanUpFile;
303 mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
304 std::ofstream::out | std::ofstream::app);
305 if (!mutexCleanUpFile.good())
306 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700307 lg2::debug("Unable to open mutex cleanup file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530308 return;
309 }
310 mutexCleanUpFile.close();
311 mutexCleanupLock =
312 boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
313 if (mutexCleanupLock.try_lock())
314 {
315 boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
316 channelMutex =
317 std::make_unique<boost::interprocess::named_recursive_mutex>(
318 boost::interprocess::open_or_create, ipmiChannelMutex);
319 mutexCleanupLock.lock_sharable();
320 }
321 else
322 {
323 mutexCleanupLock.lock_sharable();
324 channelMutex =
325 std::make_unique<boost::interprocess::named_recursive_mutex>(
326 boost::interprocess::open_or_create, ipmiChannelMutex);
327 }
328
329 initChannelPersistData();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530330
331 sigHndlrLock = boost::interprocess::file_lock(channelNvDataFilename);
George Liu1a2e1502022-07-08 12:20:19 +0800332 // Register it for single object and single process either netipmid /
AppaRao Puli9613ed72018-09-01 23:46:44 +0530333 // host-ipmid
334 if (chPropertiesSignal == nullptr && sigHndlrLock.try_lock())
335 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700336 lg2::debug("Registering channel signal handler.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530337 chPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
338 bus,
339 sdbusplus::bus::match::rules::path_namespace(
340 networkIntfObjectBasePath) +
341 sdbusplus::bus::match::rules::type::signal() +
342 sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
343 sdbusplus::bus::match::rules::interface(
344 dBusPropertiesInterface) +
345 sdbusplus::bus::match::rules::argN(0, networkChConfigIntfName),
Patrick Williams5d82f472022-07-22 19:26:53 -0500346 [&](sdbusplus::message_t& msg) {
Patrick Williams1318a5e2024-08-16 15:19:54 -0400347 DbusChObjProperties props;
348 std::string iface;
349 std::string path = msg.get_path();
350 msg.read(iface, props);
351 processChAccessPropChange(path, props);
352 });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530353 signalHndlrObjectState = true;
Willy Tuac05aa12021-11-16 21:15:58 -0800354
355 chInterfaceAddedSignal = std::make_unique<sdbusplus::bus::match_t>(
356 bus,
357 sdbusplus::bus::match::rules::type::signal() +
358 sdbusplus::bus::match::rules::member(interfaceAddedSignal) +
359 sdbusplus::bus::match::rules::argNpath(
360 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500361 [&](sdbusplus::message_t&) { initChannelPersistData(); });
Willy Tuac05aa12021-11-16 21:15:58 -0800362
363 chInterfaceRemovedSignal = std::make_unique<sdbusplus::bus::match_t>(
364 bus,
365 sdbusplus::bus::match::rules::type::signal() +
366 sdbusplus::bus::match::rules::member(interfaceRemovedSignal) +
367 sdbusplus::bus::match::rules::argNpath(
368 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500369 [&](sdbusplus::message_t&) { initChannelPersistData(); });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530370 }
371}
372
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530373bool ChannelConfig::isValidChannel(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530374{
Meera-Kattac1789482021-05-18 09:53:26 +0000375 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530376 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700377 lg2::debug("Invalid channel ID - Out of range");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530378 return false;
379 }
380
381 if (channelData[chNum].isChValid == false)
382 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700383 lg2::debug("Channel is not valid");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530384 }
385
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800386 return channelData[chNum].isChValid;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530387}
388
389EChannelSessSupported
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530390 ChannelConfig::getChannelSessionSupport(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530391{
392 EChannelSessSupported chSessSupport =
393 (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
394 return chSessSupport;
395}
396
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530397bool ChannelConfig::isValidAuthType(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530398 const EAuthType& authType)
399{
400 if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
401 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700402 lg2::debug("Invalid authentication type");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530403 return false;
404 }
405
406 uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
407 if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
408 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700409 lg2::debug("Authentication type is not supported.");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530410 return false;
411 }
412
413 return true;
414}
415
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530416int ChannelConfig::getChannelActiveSessions(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530417{
418 // TODO: TEMPORARY FIX
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800419 // Channels active session count is managed separately
AppaRao Puli071f3f22018-05-24 16:45:30 +0530420 // by monitoring channel session which includes LAN and
421 // RAKP layer changes. This will be updated, once the
422 // authentication part is implemented.
423 return channelData[chNum].activeSessCount;
424}
425
Vernon Mauery58317122018-11-28 11:02:43 -0800426size_t ChannelConfig::getChannelMaxTransferSize(uint8_t chNum)
427{
428 return channelData[chNum].maxTransferSize;
429}
430
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000431Cc ChannelConfig::getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530432{
433 if (!isValidChannel(chNum))
434 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700435 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000436 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530437 }
438
439 std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
440 sizeof(channelData[chNum].chInfo),
441 reinterpret_cast<uint8_t*>(&chInfo));
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000442 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530443}
444
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000445Cc ChannelConfig::getChannelAccessData(const uint8_t chNum,
446 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530447{
448 if (!isValidChannel(chNum))
449 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700450 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000451 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530452 }
453
454 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
455 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700456 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000457 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530458 }
459
460 if (checkAndReloadVolatileData() != 0)
461 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000462 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530463 }
464
465 std::copy_n(
466 reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
467 sizeof(channelData[chNum].chAccess.chVolatileData),
468 reinterpret_cast<uint8_t*>(&chAccessData));
469
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000470 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530471}
472
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000473Cc ChannelConfig::setChannelAccessData(const uint8_t chNum,
474 const ChannelAccess& chAccessData,
475 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530476{
477 if (!isValidChannel(chNum))
478 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700479 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000480 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530481 }
482
483 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
484 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700485 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000486 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530487 }
488
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000489 if ((setFlag & setAccessMode) &&
490 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530491 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700492 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000493 return ccAccessModeNotSupportedForChannel;
494 }
495 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
496 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700497 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000498 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530499 }
500
501 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
502 channelLock{*channelMutex};
503
504 if (checkAndReloadVolatileData() != 0)
505 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000506 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530507 }
508
509 if (setFlag & setAccessMode)
510 {
511 channelData[chNum].chAccess.chVolatileData.accessMode =
512 chAccessData.accessMode;
513 }
514 if (setFlag & setUserAuthEnabled)
515 {
516 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
517 chAccessData.userAuthDisabled;
518 }
519 if (setFlag & setMsgAuthEnabled)
520 {
521 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
522 chAccessData.perMsgAuthDisabled;
523 }
524 if (setFlag & setAlertingEnabled)
525 {
526 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
527 chAccessData.alertingDisabled;
528 }
529 if (setFlag & setPrivLimit)
530 {
531 channelData[chNum].chAccess.chVolatileData.privLimit =
532 chAccessData.privLimit;
533 }
534
535 // Write Volatile data to file
536 if (writeChannelVolatileData() != 0)
537 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700538 lg2::debug("Failed to update the channel volatile data");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000539 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530540 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000541 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530542}
543
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000544Cc ChannelConfig::getChannelAccessPersistData(const uint8_t chNum,
545 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530546{
547 if (!isValidChannel(chNum))
548 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700549 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000550 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530551 }
552
553 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
554 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700555 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000556 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530557 }
558
559 if (checkAndReloadNVData() != 0)
560 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000561 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530562 }
563
564 std::copy_n(reinterpret_cast<uint8_t*>(
565 &channelData[chNum].chAccess.chNonVolatileData),
566 sizeof(channelData[chNum].chAccess.chNonVolatileData),
567 reinterpret_cast<uint8_t*>(&chAccessData));
568
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000569 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530570}
571
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000572Cc ChannelConfig::setChannelAccessPersistData(const uint8_t chNum,
573 const ChannelAccess& chAccessData,
574 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530575{
576 if (!isValidChannel(chNum))
577 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700578 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000579 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530580 }
581
582 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
583 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700584 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000585 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530586 }
587
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000588 if ((setFlag & setAccessMode) &&
589 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530590 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700591 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000592 return ccAccessModeNotSupportedForChannel;
593 }
594 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
595 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700596 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000597 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530598 }
599
600 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
601 channelLock{*channelMutex};
602
603 if (checkAndReloadNVData() != 0)
604 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000605 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530606 }
607
608 if (setFlag & setAccessMode)
609 {
610 channelData[chNum].chAccess.chNonVolatileData.accessMode =
611 chAccessData.accessMode;
612 }
613 if (setFlag & setUserAuthEnabled)
614 {
615 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
616 chAccessData.userAuthDisabled;
617 }
618 if (setFlag & setMsgAuthEnabled)
619 {
620 channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
621 chAccessData.perMsgAuthDisabled;
622 }
623 if (setFlag & setAlertingEnabled)
624 {
625 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
626 chAccessData.alertingDisabled;
627 }
628 if (setFlag & setPrivLimit)
629 {
AppaRao Puli9613ed72018-09-01 23:46:44 +0530630 // Send Update to network channel config interfaces over dbus
AppaRao Puli9613ed72018-09-01 23:46:44 +0530631 std::string privStr = convertToPrivLimitString(chAccessData.privLimit);
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530632 std::string networkIntfObj = std::string(networkIntfObjectBasePath) +
633 "/" + channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530634 try
635 {
Johnathan Manteyf92261d2018-12-10 15:49:34 -0800636 if (0 != setDbusProperty(networkIntfServiceName, networkIntfObj,
637 networkChConfigIntfName,
AppaRao Puli9613ed72018-09-01 23:46:44 +0530638 privilegePropertyString, privStr))
639 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700640 lg2::debug("Network interface '{INTERFACE}' does not exist",
641 "INTERFACE", channelData[chNum].chName);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000642 return ccUnspecifiedError;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530643 }
644 }
Patrick Williams5d82f472022-07-22 19:26:53 -0500645 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530646 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700647 lg2::error("Exception: Network interface does not exist");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000648 return ccInvalidFieldRequest;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530649 }
650 signalFlag |= (1 << chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530651 channelData[chNum].chAccess.chNonVolatileData.privLimit =
652 chAccessData.privLimit;
653 }
654
655 // Write persistent data to file
656 if (writeChannelPersistData() != 0)
657 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700658 lg2::debug("Failed to update the presist data file");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000659 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530660 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000661 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530662}
663
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000664Cc ChannelConfig::getChannelAuthTypeSupported(const uint8_t chNum,
665 uint8_t& authTypeSupported)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530666{
667 if (!isValidChannel(chNum))
668 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700669 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000670 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530671 }
672
673 authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000674 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530675}
676
Patrick Williams1318a5e2024-08-16 15:19:54 -0400677Cc ChannelConfig::getChannelEnabledAuthType(
678 const uint8_t chNum, const uint8_t priv, EAuthType& authType)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530679{
680 if (!isValidChannel(chNum))
681 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700682 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000683 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530684 }
685
686 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
687 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700688 lg2::debug("Sessionless channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000689 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530690 }
691
692 if (!isValidPrivLimit(priv))
693 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700694 lg2::debug("Invalid privilege specified.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000695 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530696 }
697
698 // TODO: Hardcoded for now. Need to implement.
699 authType = EAuthType::none;
700
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000701 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530702}
703
704std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
705{
706 struct stat fileStat;
707 if (stat(fileName.c_str(), &fileStat) != 0)
708 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700709 lg2::debug("Error in getting last updated time stamp");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530710 return -EIO;
711 }
712 return fileStat.st_mtime;
713}
714
715EChannelAccessMode
716 ChannelConfig::convertToAccessModeIndex(const std::string& mode)
717{
718 auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
719 if (iter == accessModeList.end())
720 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700721 lg2::error("Invalid access mode: {MODE_STR}", "MODE_STR", mode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530722 throw std::invalid_argument("Invalid access mode.");
723 }
724
725 return static_cast<EChannelAccessMode>(
726 std::distance(accessModeList.begin(), iter));
727}
728
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530729std::string ChannelConfig::convertToAccessModeString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530730{
731 if (accessModeList.size() <= value)
732 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700733 lg2::error("Invalid access mode: {MODE_IDX}", "MODE_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530734 throw std::invalid_argument("Invalid access mode.");
735 }
736
737 return accessModeList.at(value);
738}
739
740CommandPrivilege
741 ChannelConfig::convertToPrivLimitIndex(const std::string& value)
742{
743 auto iter = std::find(privList.begin(), privList.end(), value);
744 if (iter == privList.end())
745 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700746 lg2::error("Invalid privilege: {PRIV_STR}", "PRIV_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530747 throw std::invalid_argument("Invalid privilege.");
748 }
749
750 return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
751}
752
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530753std::string ChannelConfig::convertToPrivLimitString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530754{
755 if (privList.size() <= value)
756 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700757 lg2::error("Invalid privilege: {PRIV_IDX.", "PRIV_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530758 throw std::invalid_argument("Invalid privilege.");
759 }
760
761 return privList.at(value);
762}
763
764EChannelSessSupported
765 ChannelConfig::convertToSessionSupportIndex(const std::string& value)
766{
Patrick Williams1318a5e2024-08-16 15:19:54 -0400767 auto iter =
768 std::find(sessionSupportList.begin(), sessionSupportList.end(), value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530769 if (iter == sessionSupportList.end())
770 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700771 lg2::error("Invalid session supported: {SESS_STR}", "SESS_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530772 throw std::invalid_argument("Invalid session supported.");
773 }
774
775 return static_cast<EChannelSessSupported>(
776 std::distance(sessionSupportList.begin(), iter));
777}
778
779EChannelMediumType
780 ChannelConfig::convertToMediumTypeIndex(const std::string& value)
781{
782 std::unordered_map<std::string, EChannelMediumType>::iterator it =
783 mediumTypeMap.find(value);
784 if (it == mediumTypeMap.end())
785 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700786 lg2::error("Invalid medium type: {MEDIUM_STR}", "MEDIUM_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530787 throw std::invalid_argument("Invalid medium type.");
788 }
789
790 return static_cast<EChannelMediumType>(it->second);
791}
792
793EChannelProtocolType
794 ChannelConfig::convertToProtocolTypeIndex(const std::string& value)
795{
796 std::unordered_map<std::string, EChannelProtocolType>::iterator it =
797 protocolTypeMap.find(value);
798 if (it == protocolTypeMap.end())
799 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700800 lg2::error("Invalid protocol type: {PROTO_STR}", "PROTO_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530801 throw std::invalid_argument("Invalid protocol type.");
802 }
803
804 return static_cast<EChannelProtocolType>(it->second);
805}
806
807Json ChannelConfig::readJsonFile(const std::string& configFile)
808{
809 std::ifstream jsonFile(configFile);
810 if (!jsonFile.good())
811 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700812 lg2::info("JSON file '{FILE_NAME}' not found", "FILE_NAME", configFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530813 return nullptr;
814 }
815
816 Json data = nullptr;
817 try
818 {
819 data = Json::parse(jsonFile, nullptr, false);
820 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500821 catch (const Json::parse_error& e)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530822 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700823 lg2::debug("Corrupted channel config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +0530824 throw std::runtime_error("Corrupted channel config file");
825 }
826
827 return data;
828}
829
830int ChannelConfig::writeJsonFile(const std::string& configFile,
831 const Json& jsonData)
832{
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530833 const std::string tmpFile = configFile + "_tmp";
834 int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
835 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
836 if (fd < 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530837 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700838 lg2::error("Error in creating json file '{FILE_NAME}'", "FILE_NAME",
839 tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530840 return -EIO;
841 }
842 const auto& writeData = jsonData.dump();
843 if (write(fd, writeData.c_str(), writeData.size()) !=
844 static_cast<ssize_t>(writeData.size()))
845 {
846 close(fd);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700847 lg2::error("Error in writing configuration file '{FILE_NAME}'",
848 "FILE_NAME", tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530849 return -EIO;
850 }
851 close(fd);
852
853 if (std::rename(tmpFile.c_str(), configFile.c_str()) != 0)
854 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700855 lg2::error("Error in renaming temporary data file '{FILE_NAME}'",
856 "FILE_NAME", tmpFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530857 return -EIO;
858 }
859
AppaRao Puli071f3f22018-05-24 16:45:30 +0530860 return 0;
861}
862
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530863void ChannelConfig::setDefaultChannelConfig(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530864 const std::string& chName)
865{
866 channelData[chNum].chName = chName;
867 channelData[chNum].chID = chNum;
868 channelData[chNum].isChValid = false;
869 channelData[chNum].activeSessCount = 0;
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700870 channelData[chNum].isManagementNIC = false;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530871
872 channelData[chNum].chInfo.mediumType = defaultMediumType;
873 channelData[chNum].chInfo.protocolType = defaultProtocolType;
874 channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
875 channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
876 channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
877}
878
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700879uint8_t ChannelConfig::getManagementNICID()
880{
881 static bool idFound = false;
882 static uint8_t id = 0;
883
884 if (idFound)
885 {
886 return id;
887 }
888
889 for (uint8_t chIdx = 0; chIdx < maxIpmiChannels; chIdx++)
890 {
891 if (channelData[chIdx].isManagementNIC)
892 {
893 id = chIdx;
894 idFound = true;
895 break;
896 }
897 }
898
899 if (!idFound)
900 {
901 id = static_cast<uint8_t>(EChannelID::chanLan1);
902 idFound = true;
903 }
904 return id;
905}
906
AppaRao Puli071f3f22018-05-24 16:45:30 +0530907int ChannelConfig::loadChannelConfig()
908{
909 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
910 channelLock{*channelMutex};
911
912 Json data = readJsonFile(channelConfigDefaultFilename);
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800913 if (data.empty())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530914 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700915 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530916 return -EIO;
917 }
918
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800919 channelData.fill(ChannelProperties{});
920
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800921 // Collect the list of NIC interfaces connected to the BMC. Use this
922 // information to only add IPMI channels that have active NIC interfaces.
Snehalatha Venkatesh55f5d532021-07-13 11:06:36 +0000923 struct ifaddrs *ifaddr = nullptr, *ifa = nullptr;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800924 if (int err = getifaddrs(&ifaddr); err < 0)
925 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700926 lg2::debug("Unable to acquire network interfaces");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800927 return -EIO;
928 }
929
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800930 for (int chNum = 0; chNum < maxIpmiChannels; chNum++)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530931 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800932 try
AppaRao Puli071f3f22018-05-24 16:45:30 +0530933 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530934 std::string chKey = std::to_string(chNum);
935 Json jsonChData = data[chKey].get<Json>();
936 if (jsonChData.is_null())
937 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530938 // If user didn't want to configure specific channel (say
939 // reserved channel), then load that index with default values.
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800940 setDefaultChannelConfig(chNum, defaultChannelName);
941 continue;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530942 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800943 Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
944 if (jsonChInfo.is_null())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530945 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700946 lg2::error("Invalid/corrupted channel config file");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800947 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800948 return -EBADMSG;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530949 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800950
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800951 bool channelFound = true;
952 // Confirm the LAN channel is present
953 if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
954 {
955 channelFound = false;
956 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
957 {
958 if (jsonChData[nameString].get<std::string>() ==
959 ifa->ifa_name)
960 {
961 channelFound = true;
962 break;
963 }
964 }
965 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800966 ChannelProperties& chData = channelData[chNum];
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800967 chData.chID = chNum;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800968 chData.chName = jsonChData[nameString].get<std::string>();
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500969 chData.isChValid = channelFound &&
970 jsonChData[isValidString].get<bool>();
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800971 chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400972 chData.maxTransferSize =
973 jsonChData.value(maxTransferSizeString, smallChannelSize);
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700974 if (jsonChData.count(isManagementNIC) != 0)
975 {
976 chData.isManagementNIC =
977 jsonChData[isManagementNIC].get<bool>();
978 }
979
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800980 std::string medTypeStr =
981 jsonChInfo[mediumTypeString].get<std::string>();
982 chData.chInfo.mediumType =
983 static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
984 std::string protoTypeStr =
985 jsonChInfo[protocolTypeString].get<std::string>();
986 chData.chInfo.protocolType =
987 static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
988 std::string sessStr =
989 jsonChInfo[sessionSupportedString].get<std::string>();
990 chData.chInfo.sessionSupported =
991 static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
992 chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
993 chData.chInfo.authTypeSupported = defaultAuthType;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530994 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800995 catch (const Json::exception& e)
996 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700997 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800998 freeifaddrs(ifaddr);
999
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001000 return -EBADMSG;
1001 }
1002 catch (const std::invalid_argument& e)
1003 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001004 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001005 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001006 return -EBADMSG;
1007 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301008 }
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001009 freeifaddrs(ifaddr);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301010
1011 return 0;
1012}
1013
1014int ChannelConfig::readChannelVolatileData()
1015{
1016 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1017 channelLock{*channelMutex};
1018
1019 Json data = readJsonFile(channelVolatileDataFilename);
1020 if (data == nullptr)
1021 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001022 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301023 return -EIO;
1024 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301025 try
1026 {
1027 // Fill in global structure
1028 for (auto it = data.begin(); it != data.end(); ++it)
1029 {
1030 std::string chKey = it.key();
1031 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001032 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301033 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001034 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301035 throw std::out_of_range("Out of range - channel number");
1036 }
1037 Json jsonChData = it.value();
1038 if (!jsonChData.is_null())
1039 {
1040 std::string accModeStr =
1041 jsonChData[accessModeString].get<std::string>();
1042 channelData[chNum].chAccess.chVolatileData.accessMode =
1043 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1044 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
1045 jsonChData[userAuthDisabledString].get<bool>();
1046 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
1047 jsonChData[perMsgAuthDisabledString].get<bool>();
1048 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
1049 jsonChData[alertingDisabledString].get<bool>();
1050 std::string privStr =
1051 jsonChData[privLimitString].get<std::string>();
1052 channelData[chNum].chAccess.chVolatileData.privLimit =
1053 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1054 }
1055 else
1056 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001057 lg2::error(
1058 "Invalid/corrupted volatile channel access file '{FILE}'",
1059 "FILE", channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301060 throw std::runtime_error(
1061 "Corrupted volatile channel access file");
1062 }
1063 }
1064 }
1065 catch (const Json::exception& e)
1066 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001067 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301068 throw std::runtime_error("Corrupted volatile channel access file");
1069 }
1070 catch (const std::invalid_argument& e)
1071 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001072 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301073 throw std::runtime_error("Corrupted volatile channel access file");
1074 }
1075
1076 // Update the timestamp
1077 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1078 return 0;
1079}
1080
1081int ChannelConfig::readChannelPersistData()
1082{
1083 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1084 channelLock{*channelMutex};
1085
1086 Json data = readJsonFile(channelNvDataFilename);
1087 if (data == nullptr)
1088 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001089 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301090 return -EIO;
1091 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301092 try
1093 {
1094 // Fill in global structure
1095 for (auto it = data.begin(); it != data.end(); ++it)
1096 {
1097 std::string chKey = it.key();
1098 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001099 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301100 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001101 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301102 throw std::out_of_range("Out of range - channel number");
1103 }
1104 Json jsonChData = it.value();
1105 if (!jsonChData.is_null())
1106 {
1107 std::string accModeStr =
1108 jsonChData[accessModeString].get<std::string>();
1109 channelData[chNum].chAccess.chNonVolatileData.accessMode =
1110 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1111 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
1112 jsonChData[userAuthDisabledString].get<bool>();
1113 channelData[chNum]
1114 .chAccess.chNonVolatileData.perMsgAuthDisabled =
1115 jsonChData[perMsgAuthDisabledString].get<bool>();
1116 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
1117 jsonChData[alertingDisabledString].get<bool>();
1118 std::string privStr =
1119 jsonChData[privLimitString].get<std::string>();
1120 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1121 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1122 }
1123 else
1124 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001125 lg2::error("Invalid/corrupted nv channel access file {FILE}",
1126 "FILE", channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301127 throw std::runtime_error("Corrupted nv channel access file");
1128 }
1129 }
1130 }
1131 catch (const Json::exception& e)
1132 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001133 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301134 throw std::runtime_error("Corrupted nv channel access file");
1135 }
1136 catch (const std::invalid_argument& e)
1137 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001138 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301139 throw std::runtime_error("Corrupted nv channel access file");
1140 }
1141
1142 // Update the timestamp
1143 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1144 return 0;
1145}
1146
1147int ChannelConfig::writeChannelVolatileData()
1148{
1149 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1150 channelLock{*channelMutex};
1151 Json outData;
1152
1153 try
1154 {
1155 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1156 {
1157 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1158 {
1159 Json jsonObj;
1160 std::string chKey = std::to_string(chNum);
1161 std::string accModeStr = convertToAccessModeString(
1162 channelData[chNum].chAccess.chVolatileData.accessMode);
1163 jsonObj[accessModeString] = accModeStr;
1164 jsonObj[userAuthDisabledString] =
1165 channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
1166 jsonObj[perMsgAuthDisabledString] =
1167 channelData[chNum]
1168 .chAccess.chVolatileData.perMsgAuthDisabled;
1169 jsonObj[alertingDisabledString] =
1170 channelData[chNum].chAccess.chVolatileData.alertingDisabled;
1171 std::string privStr = convertToPrivLimitString(
1172 channelData[chNum].chAccess.chVolatileData.privLimit);
1173 jsonObj[privLimitString] = privStr;
1174
1175 outData[chKey] = jsonObj;
1176 }
1177 }
1178 }
1179 catch (const std::invalid_argument& e)
1180 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001181 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301182 return -EINVAL;
1183 }
1184
1185 if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
1186 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001187 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301188 return -EIO;
1189 }
1190
1191 // Update the timestamp
1192 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1193 return 0;
1194}
1195
1196int ChannelConfig::writeChannelPersistData()
1197{
1198 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1199 channelLock{*channelMutex};
1200 Json outData;
1201
1202 try
1203 {
1204 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1205 {
1206 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1207 {
1208 Json jsonObj;
1209 std::string chKey = std::to_string(chNum);
1210 std::string accModeStr = convertToAccessModeString(
1211 channelData[chNum].chAccess.chNonVolatileData.accessMode);
1212 jsonObj[accessModeString] = accModeStr;
1213 jsonObj[userAuthDisabledString] =
1214 channelData[chNum]
1215 .chAccess.chNonVolatileData.userAuthDisabled;
1216 jsonObj[perMsgAuthDisabledString] =
1217 channelData[chNum]
1218 .chAccess.chNonVolatileData.perMsgAuthDisabled;
1219 jsonObj[alertingDisabledString] =
1220 channelData[chNum]
1221 .chAccess.chNonVolatileData.alertingDisabled;
1222 std::string privStr = convertToPrivLimitString(
1223 channelData[chNum].chAccess.chNonVolatileData.privLimit);
1224 jsonObj[privLimitString] = privStr;
1225
1226 outData[chKey] = jsonObj;
1227 }
1228 }
1229 }
1230 catch (const std::invalid_argument& e)
1231 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001232 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301233 return -EINVAL;
1234 }
1235
1236 if (writeJsonFile(channelNvDataFilename, outData) != 0)
1237 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001238 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301239 return -EIO;
1240 }
1241
1242 // Update the timestamp
1243 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1244 return 0;
1245}
1246
1247int ChannelConfig::checkAndReloadNVData()
1248{
1249 std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
1250 int ret = 0;
1251 if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
1252 {
1253 try
1254 {
1255 ret = readChannelPersistData();
1256 }
1257 catch (const std::exception& e)
1258 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001259 lg2::error("Exception caught in readChannelPersistData: {MSG}",
1260 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301261 ret = -EIO;
1262 }
1263 }
1264 return ret;
1265}
1266
1267int ChannelConfig::checkAndReloadVolatileData()
1268{
1269 std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
1270 int ret = 0;
1271 if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
1272 {
1273 try
1274 {
1275 ret = readChannelVolatileData();
1276 }
1277 catch (const std::exception& e)
1278 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001279 lg2::error("Exception caught in readChannelVolatileData: {MSG}",
1280 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301281 ret = -EIO;
1282 }
1283 }
1284 return ret;
1285}
1286
Patrick Williams1318a5e2024-08-16 15:19:54 -04001287int ChannelConfig::setDbusProperty(
1288 const std::string& service, const std::string& objPath,
1289 const std::string& interface, const std::string& property,
1290 const DbusVariant& value)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301291{
1292 try
1293 {
Patrick Williams1318a5e2024-08-16 15:19:54 -04001294 auto method =
1295 bus.new_method_call(service.c_str(), objPath.c_str(),
1296 "org.freedesktop.DBus.Properties", "Set");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301297
1298 method.append(interface, property, value);
1299
1300 auto reply = bus.call(method);
1301 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001302 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301303 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001304 lg2::debug(
1305 "set-property {SERVICE}:{OBJPATH}/{INTERFACE}.{PROP} failed: {MSG}",
1306 "SERVICE", service, "OBJPATH", objPath, "INTERFACE", interface,
1307 "PROP", property);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301308 return -EIO;
1309 }
1310
1311 return 0;
1312}
1313
AppaRao Puli9613ed72018-09-01 23:46:44 +05301314int ChannelConfig::syncNetworkChannelConfig()
1315{
1316 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1317 channelLock{*channelMutex};
1318 bool isUpdated = false;
1319 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1320 {
1321 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1322 {
1323 std::string intfPrivStr;
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001324 uint8_t intfPriv = 0;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301325 try
1326 {
AppaRao Puli9613ed72018-09-01 23:46:44 +05301327 std::string networkIntfObj =
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301328 std::string(networkIntfObjectBasePath) + "/" +
1329 channelData[chNum].chName;
George Liu42f64ef2024-02-05 15:03:18 +08001330 auto propValue = ipmi::getDbusProperty(
1331 bus, networkIntfServiceName, networkIntfObj,
1332 networkChConfigIntfName, privilegePropertyString);
1333
1334 intfPrivStr = std::get<std::string>(propValue);
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001335 intfPriv =
1336 static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301337 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001338 catch (const std::bad_variant_access& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301339 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001340 lg2::debug("Network interface '{INTERFACE}' does not exist",
1341 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301342 continue;
1343 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001344 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301345 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001346 lg2::debug("Network interface '{INTERFACE}' does not exist",
1347 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301348 continue;
1349 }
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001350 catch (const std::invalid_argument& e)
1351 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001352 lg2::debug("exception: Invalid privilege");
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001353 continue;
1354 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301355
AppaRao Puli9613ed72018-09-01 23:46:44 +05301356 if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
1357 intfPriv)
1358 {
1359 isUpdated = true;
1360 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1361 intfPriv;
1362 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
1363 }
1364 }
1365 }
1366
1367 if (isUpdated)
1368 {
1369 // Write persistent data to file
1370 if (writeChannelPersistData() != 0)
1371 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001372 lg2::debug("Failed to update the persistent data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301373 return -EIO;
1374 }
1375 // Write Volatile data to file
1376 if (writeChannelVolatileData() != 0)
1377 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001378 lg2::debug("Failed to update the channel volatile data");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301379 return -EIO;
1380 }
1381 }
1382
1383 return 0;
1384}
1385
AppaRao Puli071f3f22018-05-24 16:45:30 +05301386void ChannelConfig::initChannelPersistData()
1387{
Richard Marian Thomaiyare91474c2019-09-01 23:02:47 +05301388 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1389 channelLock{*channelMutex};
1390
AppaRao Puli071f3f22018-05-24 16:45:30 +05301391 /* Always read the channel config */
1392 if (loadChannelConfig() != 0)
1393 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001394 lg2::error("Failed to read channel config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301395 throw std::ios_base::failure("Failed to load channel configuration");
1396 }
1397
1398 /* Populate the channel persist data */
1399 if (readChannelPersistData() != 0)
1400 {
1401 // Copy default NV data to RW location
Patrick Williams3d8d7932022-06-16 12:01:28 -05001402 std::filesystem::copy_file(channelAccessDefaultFilename,
1403 channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301404
1405 // Load the channel access NV data
1406 if (readChannelPersistData() != 0)
1407 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001408 lg2::error("Failed to read channel access NV data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301409 throw std::ios_base::failure(
1410 "Failed to read channel access NV configuration");
1411 }
1412 }
1413
1414 // First check the volatile data file
1415 // If not present, load the default values
1416 if (readChannelVolatileData() != 0)
1417 {
1418 // Copy default volatile data to temporary location
1419 // NV file(channelNvDataFilename) must have created by now.
Patrick Williams3d8d7932022-06-16 12:01:28 -05001420 std::filesystem::copy_file(channelNvDataFilename,
1421 channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301422
1423 // Load the channel access volatile data
1424 if (readChannelVolatileData() != 0)
1425 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001426 lg2::error("Failed to read channel access volatile data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301427 throw std::ios_base::failure(
1428 "Failed to read channel access volatile configuration");
1429 }
1430 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301431
1432 // Synchronize the channel config(priv) with network channel
1433 // configuration(priv) over dbus
1434 if (syncNetworkChannelConfig() != 0)
1435 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001436 lg2::error(
AppaRao Puli9613ed72018-09-01 23:46:44 +05301437 "Failed to synchronize data with network channel config over dbus");
1438 throw std::ios_base::failure(
1439 "Failed to synchronize data with network channel config over dbus");
1440 }
1441
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001442 lg2::debug("Successfully completed channel data initialization.");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301443 return;
1444}
1445
1446} // namespace ipmi