blob: 13ea55b5fad4958ba54771c6b2356d27651939fd [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* authTypeSupportedString = "auth_type_supported";
77static constexpr const char* accessModeString = "access_mode";
78static constexpr const char* userAuthDisabledString = "user_auth_disabled";
79static constexpr const char* perMsgAuthDisabledString = "per_msg_auth_disabled";
80static constexpr const char* alertingDisabledString = "alerting_disabled";
81static constexpr const char* privLimitString = "priv_limit";
82static constexpr const char* authTypeEnabledString = "auth_type_enabled";
83
84// Default values
85static constexpr const char* defaultChannelName = "RESERVED";
86static constexpr const uint8_t defaultMediumType =
87 static_cast<uint8_t>(EChannelMediumType::reserved);
88static constexpr const uint8_t defaultProtocolType =
89 static_cast<uint8_t>(EChannelProtocolType::reserved);
90static constexpr const uint8_t defaultSessionSupported =
91 static_cast<uint8_t>(EChannelSessSupported::none);
92static constexpr const uint8_t defaultAuthType =
93 static_cast<uint8_t>(EAuthType::none);
94static constexpr const bool defaultIsIpmiState = false;
Vernon Mauery58317122018-11-28 11:02:43 -080095static constexpr size_t smallChannelSize = 64;
AppaRao Puli071f3f22018-05-24 16:45:30 +053096
Lei YU4b0ddb62019-01-25 16:43:50 +080097std::unique_ptr<sdbusplus::bus::match_t> chPropertiesSignal
98 __attribute__((init_priority(101)));
AppaRao Puli9613ed72018-09-01 23:46:44 +053099
Willy Tuac05aa12021-11-16 21:15:58 -0800100std::unique_ptr<sdbusplus::bus::match_t> chInterfaceAddedSignal
101 __attribute__((init_priority(101)));
102
103std::unique_ptr<sdbusplus::bus::match_t> chInterfaceRemovedSignal
104 __attribute__((init_priority(101)));
105
AppaRao Puli071f3f22018-05-24 16:45:30 +0530106// String mappings use in JSON config file
107static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
108 {"reserved", EChannelMediumType::reserved},
109 {"ipmb", EChannelMediumType::ipmb},
110 {"icmb-v1.0", EChannelMediumType::icmbV10},
111 {"icmb-v0.9", EChannelMediumType::icmbV09},
112 {"lan-802.3", EChannelMediumType::lan8032},
113 {"serial", EChannelMediumType::serial},
114 {"other-lan", EChannelMediumType::otherLan},
115 {"pci-smbus", EChannelMediumType::pciSmbus},
116 {"smbus-v1.0", EChannelMediumType::smbusV11},
117 {"smbus-v2.0", EChannelMediumType::smbusV20},
118 {"usb-1x", EChannelMediumType::usbV1x},
119 {"usb-2x", EChannelMediumType::usbV2x},
120 {"system-interface", EChannelMediumType::systemInterface},
121 {"oem", EChannelMediumType::oem},
122 {"unknown", EChannelMediumType::unknown}};
123
ssekarf4b2b092018-07-25 18:49:08 +0530124static std::unordered_map<EInterfaceIndex, std::string> interfaceMap = {
Richard Marian Thomaiyar43cb1282018-12-08 17:22:53 +0530125 {interfaceKCS, "SMS"},
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530126 {interfaceLAN1, "eth0"},
ssekarf4b2b092018-07-25 18:49:08 +0530127 {interfaceUnknown, "unknown"}};
128
AppaRao Puli071f3f22018-05-24 16:45:30 +0530129static std::unordered_map<std::string, EChannelProtocolType> protocolTypeMap = {
130 {"na", EChannelProtocolType::na},
131 {"ipmb-1.0", EChannelProtocolType::ipmbV10},
132 {"icmb-2.0", EChannelProtocolType::icmbV11},
133 {"reserved", EChannelProtocolType::reserved},
134 {"ipmi-smbus", EChannelProtocolType::ipmiSmbus},
135 {"kcs", EChannelProtocolType::kcs},
136 {"smic", EChannelProtocolType::smic},
137 {"bt-10", EChannelProtocolType::bt10},
138 {"bt-15", EChannelProtocolType::bt15},
139 {"tmode", EChannelProtocolType::tMode},
140 {"oem", EChannelProtocolType::oem}};
141
142static std::array<std::string, 4> accessModeList = {
143 "disabled", "pre-boot", "always_available", "shared"};
144
145static std::array<std::string, 4> sessionSupportList = {
146 "session-less", "single-session", "multi-session", "session-based"};
147
Sumanth Bhate4e633e2019-05-14 12:13:57 +0000148const std::array<std::string, PRIVILEGE_OEM + 1> privList = {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530149 "priv-reserved", "priv-callback", "priv-user",
150 "priv-operator", "priv-admin", "priv-oem"};
151
Richard Marian Thomaiyar55768e32019-03-02 22:54:37 +0530152std::string ChannelConfig::getChannelName(const uint8_t chNum)
Johnathan Mantey74a21022018-12-13 13:17:56 -0800153{
154 if (!isValidChannel(chNum))
155 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700156 lg2::error("Invalid channel number: {CHANNEL_ID}", "CHANNEL_ID", chNum);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800157 throw std::invalid_argument("Invalid channel number");
158 }
159
160 return channelData[chNum].chName;
161}
162
163int ChannelConfig::convertToChannelNumberFromChannelName(
164 const std::string& chName)
165{
166 for (const auto& it : channelData)
167 {
168 if (it.chName == chName)
169 {
170 return it.chID;
171 }
172 }
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700173 lg2::error("Invalid channel name: {CHANNEL}", "CHANNEL", chName);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800174 throw std::invalid_argument("Invalid channel name");
175
176 return -1;
177}
178
179std::string ChannelConfig::getChannelNameFromPath(const std::string& path)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530180{
Peter Foley1214d6c2023-11-01 11:12:42 -0400181 const size_t length = strlen(networkIntfObjectBasePath);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530182 if (((length + 1) >= path.size()) ||
183 path.compare(0, length, networkIntfObjectBasePath))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530184 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700185 lg2::error("Invalid object path: {PATH}", "PATH", path);
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530186 throw std::invalid_argument("Invalid object path");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530187 }
Richard Marian Thomaiyarbbbc3952020-01-17 12:13:28 +0530188 std::string chName(path, length + 1);
Johnathan Mantey74a21022018-12-13 13:17:56 -0800189 return chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530190}
191
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800192void ChannelConfig::processChAccessPropChange(
193 const std::string& path, const DbusChObjProperties& chProperties)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530194{
195 // Get interface name from path. ex: '/xyz/openbmc_project/network/eth0'
Johnathan Mantey74a21022018-12-13 13:17:56 -0800196 std::string chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530197 try
198 {
Johnathan Mantey74a21022018-12-13 13:17:56 -0800199 chName = getChannelNameFromPath(path);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530200 }
201 catch (const std::invalid_argument& e)
202 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700203 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530204 return;
205 }
206
207 // Get the MaxPrivilege property value from the signal
208 std::string intfPrivStr;
209 std::string propName;
210 for (const auto& prop : chProperties)
211 {
212 if (prop.first == privilegePropertyString)
213 {
214 propName = privilegePropertyString;
Vernon Maueryf442e112019-04-09 11:44:36 -0700215 intfPrivStr = std::get<std::string>(prop.second);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530216 break;
217 }
218 }
219
220 if (propName != privilegePropertyString)
221 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700222 lg2::error("Unknown signal caught.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530223 return;
224 }
225
226 if (intfPrivStr.empty())
227 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700228 lg2::error("Invalid privilege string for intf {INTF}", "INTF", chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530229 return;
230 }
231
232 uint8_t intfPriv = 0;
Johnathan Mantey74a21022018-12-13 13:17:56 -0800233 int chNum;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530234 try
235 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800236 intfPriv = static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
Johnathan Mantey74a21022018-12-13 13:17:56 -0800237 chNum = convertToChannelNumberFromChannelName(chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +0530238 }
239 catch (const std::invalid_argument& e)
240 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700241 lg2::error("Exception: {MSG}", "MSG", e.what());
AppaRao Puli9613ed72018-09-01 23:46:44 +0530242 return;
243 }
244
245 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800246 channelLock{*channelMutex};
AppaRao Puli9613ed72018-09-01 23:46:44 +0530247 // skip updating the values, if this property change originated from IPMI.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800248 if (signalFlag & (1 << chNum))
AppaRao Puli9613ed72018-09-01 23:46:44 +0530249 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800250 signalFlag &= ~(1 << chNum);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700251 lg2::debug("Request originated from IPMI so ignoring signal");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530252 return;
253 }
254
255 // Update both volatile & Non-volatile, if there is mismatch.
256 // as property change other than IPMI, has to update both volatile &
257 // non-volatile data.
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800258 checkAndReloadVolatileData();
259 checkAndReloadNVData();
260 if (channelData[chNum].chAccess.chNonVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530261 {
262 // Update NV data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800263 channelData[chNum].chAccess.chNonVolatileData.privLimit = intfPriv;
264 if (writeChannelPersistData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530265 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700266 lg2::error("Failed to update the persist data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530267 return;
268 }
269
270 // Update Volatile data
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800271 if (channelData[chNum].chAccess.chVolatileData.privLimit != intfPriv)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530272 {
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800273 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
274 if (writeChannelVolatileData() != 0)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530275 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700276 lg2::error("Failed to update the volatile data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530277 return;
278 }
279 }
280 }
281
282 return;
283}
284
AppaRao Puli071f3f22018-05-24 16:45:30 +0530285ChannelConfig& getChannelConfigObject()
286{
287 static ChannelConfig channelConfig;
288 return channelConfig;
289}
290
AppaRao Puli9613ed72018-09-01 23:46:44 +0530291ChannelConfig::~ChannelConfig()
292{
293 if (signalHndlrObjectState)
294 {
295 chPropertiesSignal.reset();
Willy Tuac05aa12021-11-16 21:15:58 -0800296 chInterfaceAddedSignal.reset();
297 chInterfaceRemovedSignal.reset();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530298 sigHndlrLock.unlock();
299 }
300}
301
AppaRao Puli071f3f22018-05-24 16:45:30 +0530302ChannelConfig::ChannelConfig() : bus(ipmid_get_sd_bus_connection())
303{
304 std::ofstream mutexCleanUpFile;
305 mutexCleanUpFile.open(ipmiChMutexCleanupLockFile,
306 std::ofstream::out | std::ofstream::app);
307 if (!mutexCleanUpFile.good())
308 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700309 lg2::debug("Unable to open mutex cleanup file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530310 return;
311 }
312 mutexCleanUpFile.close();
313 mutexCleanupLock =
314 boost::interprocess::file_lock(ipmiChMutexCleanupLockFile);
315 if (mutexCleanupLock.try_lock())
316 {
317 boost::interprocess::named_recursive_mutex::remove(ipmiChannelMutex);
318 channelMutex =
319 std::make_unique<boost::interprocess::named_recursive_mutex>(
320 boost::interprocess::open_or_create, ipmiChannelMutex);
321 mutexCleanupLock.lock_sharable();
322 }
323 else
324 {
325 mutexCleanupLock.lock_sharable();
326 channelMutex =
327 std::make_unique<boost::interprocess::named_recursive_mutex>(
328 boost::interprocess::open_or_create, ipmiChannelMutex);
329 }
330
331 initChannelPersistData();
AppaRao Puli9613ed72018-09-01 23:46:44 +0530332
333 sigHndlrLock = boost::interprocess::file_lock(channelNvDataFilename);
George Liu1a2e1502022-07-08 12:20:19 +0800334 // Register it for single object and single process either netipmid /
AppaRao Puli9613ed72018-09-01 23:46:44 +0530335 // host-ipmid
336 if (chPropertiesSignal == nullptr && sigHndlrLock.try_lock())
337 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700338 lg2::debug("Registering channel signal handler.");
AppaRao Puli9613ed72018-09-01 23:46:44 +0530339 chPropertiesSignal = std::make_unique<sdbusplus::bus::match_t>(
340 bus,
341 sdbusplus::bus::match::rules::path_namespace(
342 networkIntfObjectBasePath) +
343 sdbusplus::bus::match::rules::type::signal() +
344 sdbusplus::bus::match::rules::member(propertiesChangedSignal) +
345 sdbusplus::bus::match::rules::interface(
346 dBusPropertiesInterface) +
347 sdbusplus::bus::match::rules::argN(0, networkChConfigIntfName),
Patrick Williams5d82f472022-07-22 19:26:53 -0500348 [&](sdbusplus::message_t& msg) {
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500349 DbusChObjProperties props;
350 std::string iface;
351 std::string path = msg.get_path();
352 msg.read(iface, props);
353 processChAccessPropChange(path, props);
Patrick Williams369824e2023-10-20 11:18:23 -0500354 });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530355 signalHndlrObjectState = true;
Willy Tuac05aa12021-11-16 21:15:58 -0800356
357 chInterfaceAddedSignal = std::make_unique<sdbusplus::bus::match_t>(
358 bus,
359 sdbusplus::bus::match::rules::type::signal() +
360 sdbusplus::bus::match::rules::member(interfaceAddedSignal) +
361 sdbusplus::bus::match::rules::argNpath(
362 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500363 [&](sdbusplus::message_t&) { initChannelPersistData(); });
Willy Tuac05aa12021-11-16 21:15:58 -0800364
365 chInterfaceRemovedSignal = std::make_unique<sdbusplus::bus::match_t>(
366 bus,
367 sdbusplus::bus::match::rules::type::signal() +
368 sdbusplus::bus::match::rules::member(interfaceRemovedSignal) +
369 sdbusplus::bus::match::rules::argNpath(
370 0, std::string(networkIntfObjectBasePath) + "/"),
Patrick Williams5d82f472022-07-22 19:26:53 -0500371 [&](sdbusplus::message_t&) { initChannelPersistData(); });
AppaRao Puli9613ed72018-09-01 23:46:44 +0530372 }
373}
374
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530375bool ChannelConfig::isValidChannel(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530376{
Meera-Kattac1789482021-05-18 09:53:26 +0000377 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530378 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700379 lg2::debug("Invalid channel ID - Out of range");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530380 return false;
381 }
382
383 if (channelData[chNum].isChValid == false)
384 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700385 lg2::debug("Channel is not valid");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530386 }
387
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800388 return channelData[chNum].isChValid;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530389}
390
391EChannelSessSupported
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530392 ChannelConfig::getChannelSessionSupport(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530393{
394 EChannelSessSupported chSessSupport =
395 (EChannelSessSupported)channelData[chNum].chInfo.sessionSupported;
396 return chSessSupport;
397}
398
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530399bool ChannelConfig::isValidAuthType(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530400 const EAuthType& authType)
401{
402 if ((authType < EAuthType::md2) || (authType > EAuthType::oem))
403 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700404 lg2::debug("Invalid authentication type");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530405 return false;
406 }
407
408 uint8_t authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
409 if (!(authTypeSupported & (1 << static_cast<uint8_t>(authType))))
410 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700411 lg2::debug("Authentication type is not supported.");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530412 return false;
413 }
414
415 return true;
416}
417
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530418int ChannelConfig::getChannelActiveSessions(const uint8_t chNum)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530419{
420 // TODO: TEMPORARY FIX
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800421 // Channels active session count is managed separately
AppaRao Puli071f3f22018-05-24 16:45:30 +0530422 // by monitoring channel session which includes LAN and
423 // RAKP layer changes. This will be updated, once the
424 // authentication part is implemented.
425 return channelData[chNum].activeSessCount;
426}
427
Vernon Mauery58317122018-11-28 11:02:43 -0800428size_t ChannelConfig::getChannelMaxTransferSize(uint8_t chNum)
429{
430 return channelData[chNum].maxTransferSize;
431}
432
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000433Cc ChannelConfig::getChannelInfo(const uint8_t chNum, ChannelInfo& chInfo)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530434{
435 if (!isValidChannel(chNum))
436 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700437 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000438 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530439 }
440
441 std::copy_n(reinterpret_cast<uint8_t*>(&channelData[chNum].chInfo),
442 sizeof(channelData[chNum].chInfo),
443 reinterpret_cast<uint8_t*>(&chInfo));
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000444 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530445}
446
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000447Cc ChannelConfig::getChannelAccessData(const uint8_t chNum,
448 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530449{
450 if (!isValidChannel(chNum))
451 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700452 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000453 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530454 }
455
456 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
457 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700458 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000459 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530460 }
461
462 if (checkAndReloadVolatileData() != 0)
463 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000464 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530465 }
466
467 std::copy_n(
468 reinterpret_cast<uint8_t*>(&channelData[chNum].chAccess.chVolatileData),
469 sizeof(channelData[chNum].chAccess.chVolatileData),
470 reinterpret_cast<uint8_t*>(&chAccessData));
471
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000472 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530473}
474
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000475Cc ChannelConfig::setChannelAccessData(const uint8_t chNum,
476 const ChannelAccess& chAccessData,
477 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530478{
479 if (!isValidChannel(chNum))
480 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700481 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000482 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530483 }
484
485 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
486 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700487 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000488 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530489 }
490
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000491 if ((setFlag & setAccessMode) &&
492 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530493 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700494 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000495 return ccAccessModeNotSupportedForChannel;
496 }
497 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
498 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700499 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000500 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530501 }
502
503 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
504 channelLock{*channelMutex};
505
506 if (checkAndReloadVolatileData() != 0)
507 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000508 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530509 }
510
511 if (setFlag & setAccessMode)
512 {
513 channelData[chNum].chAccess.chVolatileData.accessMode =
514 chAccessData.accessMode;
515 }
516 if (setFlag & setUserAuthEnabled)
517 {
518 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
519 chAccessData.userAuthDisabled;
520 }
521 if (setFlag & setMsgAuthEnabled)
522 {
523 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
524 chAccessData.perMsgAuthDisabled;
525 }
526 if (setFlag & setAlertingEnabled)
527 {
528 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
529 chAccessData.alertingDisabled;
530 }
531 if (setFlag & setPrivLimit)
532 {
533 channelData[chNum].chAccess.chVolatileData.privLimit =
534 chAccessData.privLimit;
535 }
536
537 // Write Volatile data to file
538 if (writeChannelVolatileData() != 0)
539 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700540 lg2::debug("Failed to update the channel volatile data");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000541 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530542 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000543 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530544}
545
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000546Cc ChannelConfig::getChannelAccessPersistData(const uint8_t chNum,
547 ChannelAccess& chAccessData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530548{
549 if (!isValidChannel(chNum))
550 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700551 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000552 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530553 }
554
555 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
556 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700557 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000558 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530559 }
560
561 if (checkAndReloadNVData() != 0)
562 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000563 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530564 }
565
566 std::copy_n(reinterpret_cast<uint8_t*>(
567 &channelData[chNum].chAccess.chNonVolatileData),
568 sizeof(channelData[chNum].chAccess.chNonVolatileData),
569 reinterpret_cast<uint8_t*>(&chAccessData));
570
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000571 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530572}
573
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000574Cc ChannelConfig::setChannelAccessPersistData(const uint8_t chNum,
575 const ChannelAccess& chAccessData,
576 const uint8_t setFlag)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530577{
578 if (!isValidChannel(chNum))
579 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700580 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000581 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530582 }
583
584 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
585 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700586 lg2::debug("Session-less channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000587 return ccActionNotSupportedForChannel;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530588 }
589
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000590 if ((setFlag & setAccessMode) &&
591 (!isValidAccessMode(chAccessData.accessMode)))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530592 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700593 lg2::debug("Invalid access mode specified");
jayaprakash Mutyala0e2dbee2019-12-26 13:03:04 +0000594 return ccAccessModeNotSupportedForChannel;
595 }
596 if ((setFlag & setPrivLimit) && (!isValidPrivLimit(chAccessData.privLimit)))
597 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700598 lg2::debug("Invalid privilege limit specified");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000599 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530600 }
601
602 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
603 channelLock{*channelMutex};
604
605 if (checkAndReloadNVData() != 0)
606 {
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000607 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530608 }
609
610 if (setFlag & setAccessMode)
611 {
612 channelData[chNum].chAccess.chNonVolatileData.accessMode =
613 chAccessData.accessMode;
614 }
615 if (setFlag & setUserAuthEnabled)
616 {
617 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
618 chAccessData.userAuthDisabled;
619 }
620 if (setFlag & setMsgAuthEnabled)
621 {
622 channelData[chNum].chAccess.chNonVolatileData.perMsgAuthDisabled =
623 chAccessData.perMsgAuthDisabled;
624 }
625 if (setFlag & setAlertingEnabled)
626 {
627 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
628 chAccessData.alertingDisabled;
629 }
630 if (setFlag & setPrivLimit)
631 {
AppaRao Puli9613ed72018-09-01 23:46:44 +0530632 // Send Update to network channel config interfaces over dbus
AppaRao Puli9613ed72018-09-01 23:46:44 +0530633 std::string privStr = convertToPrivLimitString(chAccessData.privLimit);
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +0530634 std::string networkIntfObj = std::string(networkIntfObjectBasePath) +
635 "/" + channelData[chNum].chName;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530636 try
637 {
Johnathan Manteyf92261d2018-12-10 15:49:34 -0800638 if (0 != setDbusProperty(networkIntfServiceName, networkIntfObj,
639 networkChConfigIntfName,
AppaRao Puli9613ed72018-09-01 23:46:44 +0530640 privilegePropertyString, privStr))
641 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700642 lg2::debug("Network interface '{INTERFACE}' does not exist",
643 "INTERFACE", channelData[chNum].chName);
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000644 return ccUnspecifiedError;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530645 }
646 }
Patrick Williams5d82f472022-07-22 19:26:53 -0500647 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +0530648 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700649 lg2::error("Exception: Network interface does not exist");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000650 return ccInvalidFieldRequest;
AppaRao Puli9613ed72018-09-01 23:46:44 +0530651 }
652 signalFlag |= (1 << chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530653 channelData[chNum].chAccess.chNonVolatileData.privLimit =
654 chAccessData.privLimit;
655 }
656
657 // Write persistent data to file
658 if (writeChannelPersistData() != 0)
659 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700660 lg2::debug("Failed to update the presist data file");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000661 return ccUnspecifiedError;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530662 }
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000663 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530664}
665
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000666Cc ChannelConfig::getChannelAuthTypeSupported(const uint8_t chNum,
667 uint8_t& authTypeSupported)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530668{
669 if (!isValidChannel(chNum))
670 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700671 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000672 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530673 }
674
675 authTypeSupported = channelData[chNum].chInfo.authTypeSupported;
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000676 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530677}
678
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000679Cc ChannelConfig::getChannelEnabledAuthType(const uint8_t chNum,
680 const uint8_t priv,
681 EAuthType& authType)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530682{
683 if (!isValidChannel(chNum))
684 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700685 lg2::debug("Invalid channel");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000686 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530687 }
688
689 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
690 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700691 lg2::debug("Sessionless channel doesn't have access data.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000692 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530693 }
694
695 if (!isValidPrivLimit(priv))
696 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700697 lg2::debug("Invalid privilege specified.");
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000698 return ccInvalidFieldRequest;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530699 }
700
701 // TODO: Hardcoded for now. Need to implement.
702 authType = EAuthType::none;
703
NITIN SHARMAb541a5a2019-07-18 12:46:59 +0000704 return ccSuccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530705}
706
707std::time_t ChannelConfig::getUpdatedFileTime(const std::string& fileName)
708{
709 struct stat fileStat;
710 if (stat(fileName.c_str(), &fileStat) != 0)
711 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700712 lg2::debug("Error in getting last updated time stamp");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530713 return -EIO;
714 }
715 return fileStat.st_mtime;
716}
717
718EChannelAccessMode
719 ChannelConfig::convertToAccessModeIndex(const std::string& mode)
720{
721 auto iter = std::find(accessModeList.begin(), accessModeList.end(), mode);
722 if (iter == accessModeList.end())
723 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700724 lg2::error("Invalid access mode: {MODE_STR}", "MODE_STR", mode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530725 throw std::invalid_argument("Invalid access mode.");
726 }
727
728 return static_cast<EChannelAccessMode>(
729 std::distance(accessModeList.begin(), iter));
730}
731
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530732std::string ChannelConfig::convertToAccessModeString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530733{
734 if (accessModeList.size() <= value)
735 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700736 lg2::error("Invalid access mode: {MODE_IDX}", "MODE_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530737 throw std::invalid_argument("Invalid access mode.");
738 }
739
740 return accessModeList.at(value);
741}
742
743CommandPrivilege
744 ChannelConfig::convertToPrivLimitIndex(const std::string& value)
745{
746 auto iter = std::find(privList.begin(), privList.end(), value);
747 if (iter == privList.end())
748 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700749 lg2::error("Invalid privilege: {PRIV_STR}", "PRIV_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530750 throw std::invalid_argument("Invalid privilege.");
751 }
752
753 return static_cast<CommandPrivilege>(std::distance(privList.begin(), iter));
754}
755
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530756std::string ChannelConfig::convertToPrivLimitString(const uint8_t value)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530757{
758 if (privList.size() <= value)
759 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700760 lg2::error("Invalid privilege: {PRIV_IDX.", "PRIV_IDX", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530761 throw std::invalid_argument("Invalid privilege.");
762 }
763
764 return privList.at(value);
765}
766
767EChannelSessSupported
768 ChannelConfig::convertToSessionSupportIndex(const std::string& value)
769{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500770 auto iter = std::find(sessionSupportList.begin(), sessionSupportList.end(),
771 value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530772 if (iter == sessionSupportList.end())
773 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700774 lg2::error("Invalid session supported: {SESS_STR}", "SESS_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530775 throw std::invalid_argument("Invalid session supported.");
776 }
777
778 return static_cast<EChannelSessSupported>(
779 std::distance(sessionSupportList.begin(), iter));
780}
781
782EChannelMediumType
783 ChannelConfig::convertToMediumTypeIndex(const std::string& value)
784{
785 std::unordered_map<std::string, EChannelMediumType>::iterator it =
786 mediumTypeMap.find(value);
787 if (it == mediumTypeMap.end())
788 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700789 lg2::error("Invalid medium type: {MEDIUM_STR}", "MEDIUM_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530790 throw std::invalid_argument("Invalid medium type.");
791 }
792
793 return static_cast<EChannelMediumType>(it->second);
794}
795
796EChannelProtocolType
797 ChannelConfig::convertToProtocolTypeIndex(const std::string& value)
798{
799 std::unordered_map<std::string, EChannelProtocolType>::iterator it =
800 protocolTypeMap.find(value);
801 if (it == protocolTypeMap.end())
802 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700803 lg2::error("Invalid protocol type: {PROTO_STR}", "PROTO_STR", value);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530804 throw std::invalid_argument("Invalid protocol type.");
805 }
806
807 return static_cast<EChannelProtocolType>(it->second);
808}
809
810Json ChannelConfig::readJsonFile(const std::string& configFile)
811{
812 std::ifstream jsonFile(configFile);
813 if (!jsonFile.good())
814 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700815 lg2::info("JSON file '{FILE_NAME}' not found", "FILE_NAME", configFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530816 return nullptr;
817 }
818
819 Json data = nullptr;
820 try
821 {
822 data = Json::parse(jsonFile, nullptr, false);
823 }
Patrick Williamsa2ad2da2021-10-06 12:21:46 -0500824 catch (const Json::parse_error& e)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530825 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700826 lg2::debug("Corrupted channel config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +0530827 throw std::runtime_error("Corrupted channel config file");
828 }
829
830 return data;
831}
832
833int ChannelConfig::writeJsonFile(const std::string& configFile,
834 const Json& jsonData)
835{
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530836 const std::string tmpFile = configFile + "_tmp";
837 int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
838 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
839 if (fd < 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530840 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700841 lg2::error("Error in creating json file '{FILE_NAME}'", "FILE_NAME",
842 tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530843 return -EIO;
844 }
845 const auto& writeData = jsonData.dump();
846 if (write(fd, writeData.c_str(), writeData.size()) !=
847 static_cast<ssize_t>(writeData.size()))
848 {
849 close(fd);
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700850 lg2::error("Error in writing configuration file '{FILE_NAME}'",
851 "FILE_NAME", tmpFile);
Richard Marian Thomaiyar687df402019-05-09 00:16:53 +0530852 return -EIO;
853 }
854 close(fd);
855
856 if (std::rename(tmpFile.c_str(), configFile.c_str()) != 0)
857 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700858 lg2::error("Error in renaming temporary data file '{FILE_NAME}'",
859 "FILE_NAME", tmpFile);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530860 return -EIO;
861 }
862
AppaRao Puli071f3f22018-05-24 16:45:30 +0530863 return 0;
864}
865
Richard Marian Thomaiyara45cb342018-12-03 15:08:59 +0530866void ChannelConfig::setDefaultChannelConfig(const uint8_t chNum,
AppaRao Puli071f3f22018-05-24 16:45:30 +0530867 const std::string& chName)
868{
869 channelData[chNum].chName = chName;
870 channelData[chNum].chID = chNum;
871 channelData[chNum].isChValid = false;
872 channelData[chNum].activeSessCount = 0;
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700873 channelData[chNum].isManagementNIC = false;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530874
875 channelData[chNum].chInfo.mediumType = defaultMediumType;
876 channelData[chNum].chInfo.protocolType = defaultProtocolType;
877 channelData[chNum].chInfo.sessionSupported = defaultSessionSupported;
878 channelData[chNum].chInfo.isIpmi = defaultIsIpmiState;
879 channelData[chNum].chInfo.authTypeSupported = defaultAuthType;
880}
881
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700882uint8_t ChannelConfig::getManagementNICID()
883{
884 static bool idFound = false;
885 static uint8_t id = 0;
886
887 if (idFound)
888 {
889 return id;
890 }
891
892 for (uint8_t chIdx = 0; chIdx < maxIpmiChannels; chIdx++)
893 {
894 if (channelData[chIdx].isManagementNIC)
895 {
896 id = chIdx;
897 idFound = true;
898 break;
899 }
900 }
901
902 if (!idFound)
903 {
904 id = static_cast<uint8_t>(EChannelID::chanLan1);
905 idFound = true;
906 }
907 return id;
908}
909
AppaRao Puli071f3f22018-05-24 16:45:30 +0530910int ChannelConfig::loadChannelConfig()
911{
912 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
913 channelLock{*channelMutex};
914
915 Json data = readJsonFile(channelConfigDefaultFilename);
Johnathan Manteye5c4f1d2018-12-10 16:24:26 -0800916 if (data.empty())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530917 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700918 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +0530919 return -EIO;
920 }
921
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800922 channelData.fill(ChannelProperties{});
923
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800924 // Collect the list of NIC interfaces connected to the BMC. Use this
925 // information to only add IPMI channels that have active NIC interfaces.
Snehalatha Venkatesh55f5d532021-07-13 11:06:36 +0000926 struct ifaddrs *ifaddr = nullptr, *ifa = nullptr;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800927 if (int err = getifaddrs(&ifaddr); err < 0)
928 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700929 lg2::debug("Unable to acquire network interfaces");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800930 return -EIO;
931 }
932
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800933 for (int chNum = 0; chNum < maxIpmiChannels; chNum++)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530934 {
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800935 try
AppaRao Puli071f3f22018-05-24 16:45:30 +0530936 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530937 std::string chKey = std::to_string(chNum);
938 Json jsonChData = data[chKey].get<Json>();
939 if (jsonChData.is_null())
940 {
AppaRao Puli071f3f22018-05-24 16:45:30 +0530941 // If user didn't want to configure specific channel (say
942 // reserved channel), then load that index with default values.
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800943 setDefaultChannelConfig(chNum, defaultChannelName);
944 continue;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530945 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800946 Json jsonChInfo = jsonChData[channelInfoString].get<Json>();
947 if (jsonChInfo.is_null())
AppaRao Puli071f3f22018-05-24 16:45:30 +0530948 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -0700949 lg2::error("Invalid/corrupted channel config file");
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800950 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800951 return -EBADMSG;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530952 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800953
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800954 bool channelFound = true;
955 // Confirm the LAN channel is present
956 if (jsonChInfo[mediumTypeString].get<std::string>() == "lan-802.3")
957 {
958 channelFound = false;
959 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
960 {
961 if (jsonChData[nameString].get<std::string>() ==
962 ifa->ifa_name)
963 {
964 channelFound = true;
965 break;
966 }
967 }
968 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800969 ChannelProperties& chData = channelData[chNum];
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800970 chData.chID = chNum;
Johnathan Mantey0a2abc82021-02-18 12:39:12 -0800971 chData.chName = jsonChData[nameString].get<std::string>();
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500972 chData.isChValid = channelFound &&
973 jsonChData[isValidString].get<bool>();
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800974 chData.activeSessCount = jsonChData.value(activeSessionsString, 0);
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500975 chData.maxTransferSize = jsonChData.value(maxTransferSizeString,
976 smallChannelSize);
Johnathan Manteyfd61fc32021-04-08 11:05:38 -0700977 if (jsonChData.count(isManagementNIC) != 0)
978 {
979 chData.isManagementNIC =
980 jsonChData[isManagementNIC].get<bool>();
981 }
982
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800983 std::string medTypeStr =
984 jsonChInfo[mediumTypeString].get<std::string>();
985 chData.chInfo.mediumType =
986 static_cast<uint8_t>(convertToMediumTypeIndex(medTypeStr));
987 std::string protoTypeStr =
988 jsonChInfo[protocolTypeString].get<std::string>();
989 chData.chInfo.protocolType =
990 static_cast<uint8_t>(convertToProtocolTypeIndex(protoTypeStr));
991 std::string sessStr =
992 jsonChInfo[sessionSupportedString].get<std::string>();
993 chData.chInfo.sessionSupported =
994 static_cast<uint8_t>(convertToSessionSupportIndex(sessStr));
995 chData.chInfo.isIpmi = jsonChInfo[isIpmiString].get<bool>();
996 chData.chInfo.authTypeSupported = defaultAuthType;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530997 }
Johnathan Mantey4c0435a2018-12-11 13:17:55 -0800998 catch (const Json::exception& e)
999 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001000 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001001 freeifaddrs(ifaddr);
1002
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001003 return -EBADMSG;
1004 }
1005 catch (const std::invalid_argument& e)
1006 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001007 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001008 freeifaddrs(ifaddr);
Johnathan Mantey4c0435a2018-12-11 13:17:55 -08001009 return -EBADMSG;
1010 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301011 }
Johnathan Mantey0a2abc82021-02-18 12:39:12 -08001012 freeifaddrs(ifaddr);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301013
1014 return 0;
1015}
1016
1017int ChannelConfig::readChannelVolatileData()
1018{
1019 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1020 channelLock{*channelMutex};
1021
1022 Json data = readJsonFile(channelVolatileDataFilename);
1023 if (data == nullptr)
1024 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001025 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301026 return -EIO;
1027 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301028 try
1029 {
1030 // Fill in global structure
1031 for (auto it = data.begin(); it != data.end(); ++it)
1032 {
1033 std::string chKey = it.key();
1034 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001035 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301036 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001037 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301038 throw std::out_of_range("Out of range - channel number");
1039 }
1040 Json jsonChData = it.value();
1041 if (!jsonChData.is_null())
1042 {
1043 std::string accModeStr =
1044 jsonChData[accessModeString].get<std::string>();
1045 channelData[chNum].chAccess.chVolatileData.accessMode =
1046 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1047 channelData[chNum].chAccess.chVolatileData.userAuthDisabled =
1048 jsonChData[userAuthDisabledString].get<bool>();
1049 channelData[chNum].chAccess.chVolatileData.perMsgAuthDisabled =
1050 jsonChData[perMsgAuthDisabledString].get<bool>();
1051 channelData[chNum].chAccess.chVolatileData.alertingDisabled =
1052 jsonChData[alertingDisabledString].get<bool>();
1053 std::string privStr =
1054 jsonChData[privLimitString].get<std::string>();
1055 channelData[chNum].chAccess.chVolatileData.privLimit =
1056 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1057 }
1058 else
1059 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001060 lg2::error(
1061 "Invalid/corrupted volatile channel access file '{FILE}'",
1062 "FILE", channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301063 throw std::runtime_error(
1064 "Corrupted volatile channel access file");
1065 }
1066 }
1067 }
1068 catch (const Json::exception& e)
1069 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001070 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301071 throw std::runtime_error("Corrupted volatile channel access file");
1072 }
1073 catch (const std::invalid_argument& e)
1074 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001075 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301076 throw std::runtime_error("Corrupted volatile channel access file");
1077 }
1078
1079 // Update the timestamp
1080 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1081 return 0;
1082}
1083
1084int ChannelConfig::readChannelPersistData()
1085{
1086 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1087 channelLock{*channelMutex};
1088
1089 Json data = readJsonFile(channelNvDataFilename);
1090 if (data == nullptr)
1091 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001092 lg2::debug("Error in opening IPMI Channel data file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301093 return -EIO;
1094 }
AppaRao Puli071f3f22018-05-24 16:45:30 +05301095 try
1096 {
1097 // Fill in global structure
1098 for (auto it = data.begin(); it != data.end(); ++it)
1099 {
1100 std::string chKey = it.key();
1101 uint8_t chNum = std::stoi(chKey, nullptr, 10);
Meera-Kattac1789482021-05-18 09:53:26 +00001102 if (chNum >= maxIpmiChannels)
AppaRao Puli071f3f22018-05-24 16:45:30 +05301103 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001104 lg2::debug("Invalid channel access entry in config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301105 throw std::out_of_range("Out of range - channel number");
1106 }
1107 Json jsonChData = it.value();
1108 if (!jsonChData.is_null())
1109 {
1110 std::string accModeStr =
1111 jsonChData[accessModeString].get<std::string>();
1112 channelData[chNum].chAccess.chNonVolatileData.accessMode =
1113 static_cast<uint8_t>(convertToAccessModeIndex(accModeStr));
1114 channelData[chNum].chAccess.chNonVolatileData.userAuthDisabled =
1115 jsonChData[userAuthDisabledString].get<bool>();
1116 channelData[chNum]
1117 .chAccess.chNonVolatileData.perMsgAuthDisabled =
1118 jsonChData[perMsgAuthDisabledString].get<bool>();
1119 channelData[chNum].chAccess.chNonVolatileData.alertingDisabled =
1120 jsonChData[alertingDisabledString].get<bool>();
1121 std::string privStr =
1122 jsonChData[privLimitString].get<std::string>();
1123 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1124 static_cast<uint8_t>(convertToPrivLimitIndex(privStr));
1125 }
1126 else
1127 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001128 lg2::error("Invalid/corrupted nv channel access file {FILE}",
1129 "FILE", channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301130 throw std::runtime_error("Corrupted nv channel access file");
1131 }
1132 }
1133 }
1134 catch (const Json::exception& e)
1135 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001136 lg2::debug("Json Exception caught: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301137 throw std::runtime_error("Corrupted nv channel access file");
1138 }
1139 catch (const std::invalid_argument& e)
1140 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001141 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301142 throw std::runtime_error("Corrupted nv channel access file");
1143 }
1144
1145 // Update the timestamp
1146 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1147 return 0;
1148}
1149
1150int ChannelConfig::writeChannelVolatileData()
1151{
1152 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1153 channelLock{*channelMutex};
1154 Json outData;
1155
1156 try
1157 {
1158 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1159 {
1160 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1161 {
1162 Json jsonObj;
1163 std::string chKey = std::to_string(chNum);
1164 std::string accModeStr = convertToAccessModeString(
1165 channelData[chNum].chAccess.chVolatileData.accessMode);
1166 jsonObj[accessModeString] = accModeStr;
1167 jsonObj[userAuthDisabledString] =
1168 channelData[chNum].chAccess.chVolatileData.userAuthDisabled;
1169 jsonObj[perMsgAuthDisabledString] =
1170 channelData[chNum]
1171 .chAccess.chVolatileData.perMsgAuthDisabled;
1172 jsonObj[alertingDisabledString] =
1173 channelData[chNum].chAccess.chVolatileData.alertingDisabled;
1174 std::string privStr = convertToPrivLimitString(
1175 channelData[chNum].chAccess.chVolatileData.privLimit);
1176 jsonObj[privLimitString] = privStr;
1177
1178 outData[chKey] = jsonObj;
1179 }
1180 }
1181 }
1182 catch (const std::invalid_argument& e)
1183 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001184 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301185 return -EINVAL;
1186 }
1187
1188 if (writeJsonFile(channelVolatileDataFilename, outData) != 0)
1189 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001190 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301191 return -EIO;
1192 }
1193
1194 // Update the timestamp
1195 voltFileLastUpdatedTime = getUpdatedFileTime(channelVolatileDataFilename);
1196 return 0;
1197}
1198
1199int ChannelConfig::writeChannelPersistData()
1200{
1201 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1202 channelLock{*channelMutex};
1203 Json outData;
1204
1205 try
1206 {
1207 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1208 {
1209 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1210 {
1211 Json jsonObj;
1212 std::string chKey = std::to_string(chNum);
1213 std::string accModeStr = convertToAccessModeString(
1214 channelData[chNum].chAccess.chNonVolatileData.accessMode);
1215 jsonObj[accessModeString] = accModeStr;
1216 jsonObj[userAuthDisabledString] =
1217 channelData[chNum]
1218 .chAccess.chNonVolatileData.userAuthDisabled;
1219 jsonObj[perMsgAuthDisabledString] =
1220 channelData[chNum]
1221 .chAccess.chNonVolatileData.perMsgAuthDisabled;
1222 jsonObj[alertingDisabledString] =
1223 channelData[chNum]
1224 .chAccess.chNonVolatileData.alertingDisabled;
1225 std::string privStr = convertToPrivLimitString(
1226 channelData[chNum].chAccess.chNonVolatileData.privLimit);
1227 jsonObj[privLimitString] = privStr;
1228
1229 outData[chKey] = jsonObj;
1230 }
1231 }
1232 }
1233 catch (const std::invalid_argument& e)
1234 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001235 lg2::error("Corrupted config: {MSG}", "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301236 return -EINVAL;
1237 }
1238
1239 if (writeJsonFile(channelNvDataFilename, outData) != 0)
1240 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001241 lg2::debug("Error in write JSON data to file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301242 return -EIO;
1243 }
1244
1245 // Update the timestamp
1246 nvFileLastUpdatedTime = getUpdatedFileTime(channelNvDataFilename);
1247 return 0;
1248}
1249
1250int ChannelConfig::checkAndReloadNVData()
1251{
1252 std::time_t updateTime = getUpdatedFileTime(channelNvDataFilename);
1253 int ret = 0;
1254 if (updateTime != nvFileLastUpdatedTime || updateTime == -EIO)
1255 {
1256 try
1257 {
1258 ret = readChannelPersistData();
1259 }
1260 catch (const std::exception& e)
1261 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001262 lg2::error("Exception caught in readChannelPersistData: {MSG}",
1263 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301264 ret = -EIO;
1265 }
1266 }
1267 return ret;
1268}
1269
1270int ChannelConfig::checkAndReloadVolatileData()
1271{
1272 std::time_t updateTime = getUpdatedFileTime(channelVolatileDataFilename);
1273 int ret = 0;
1274 if (updateTime != voltFileLastUpdatedTime || updateTime == -EIO)
1275 {
1276 try
1277 {
1278 ret = readChannelVolatileData();
1279 }
1280 catch (const std::exception& e)
1281 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001282 lg2::error("Exception caught in readChannelVolatileData: {MSG}",
1283 "MSG", e.what());
AppaRao Puli071f3f22018-05-24 16:45:30 +05301284 ret = -EIO;
1285 }
1286 }
1287 return ret;
1288}
1289
Johnathan Manteyf92261d2018-12-10 15:49:34 -08001290int ChannelConfig::setDbusProperty(const std::string& service,
AppaRao Puli9613ed72018-09-01 23:46:44 +05301291 const std::string& objPath,
1292 const std::string& interface,
1293 const std::string& property,
1294 const DbusVariant& value)
1295{
1296 try
1297 {
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -05001298 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
1299 "org.freedesktop.DBus.Properties",
1300 "Set");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301301
1302 method.append(interface, property, value);
1303
1304 auto reply = bus.call(method);
1305 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001306 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301307 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001308 lg2::debug(
1309 "set-property {SERVICE}:{OBJPATH}/{INTERFACE}.{PROP} failed: {MSG}",
1310 "SERVICE", service, "OBJPATH", objPath, "INTERFACE", interface,
1311 "PROP", property);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301312 return -EIO;
1313 }
1314
1315 return 0;
1316}
1317
AppaRao Puli9613ed72018-09-01 23:46:44 +05301318int ChannelConfig::syncNetworkChannelConfig()
1319{
1320 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1321 channelLock{*channelMutex};
1322 bool isUpdated = false;
1323 for (uint8_t chNum = 0; chNum < maxIpmiChannels; chNum++)
1324 {
1325 if (getChannelSessionSupport(chNum) != EChannelSessSupported::none)
1326 {
1327 std::string intfPrivStr;
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001328 uint8_t intfPriv = 0;
AppaRao Puli9613ed72018-09-01 23:46:44 +05301329 try
1330 {
AppaRao Puli9613ed72018-09-01 23:46:44 +05301331 std::string networkIntfObj =
Richard Marian Thomaiyar73906b92019-01-04 23:48:02 +05301332 std::string(networkIntfObjectBasePath) + "/" +
1333 channelData[chNum].chName;
George Liu42f64ef2024-02-05 15:03:18 +08001334 auto propValue = ipmi::getDbusProperty(
1335 bus, networkIntfServiceName, networkIntfObj,
1336 networkChConfigIntfName, privilegePropertyString);
1337
1338 intfPrivStr = std::get<std::string>(propValue);
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001339 intfPriv =
1340 static_cast<uint8_t>(convertToPrivLimitIndex(intfPrivStr));
AppaRao Puli9613ed72018-09-01 23:46:44 +05301341 }
Vernon Maueryf442e112019-04-09 11:44:36 -07001342 catch (const std::bad_variant_access& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301343 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001344 lg2::debug("Network interface '{INTERFACE}' does not exist",
1345 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301346 continue;
1347 }
Patrick Williams5d82f472022-07-22 19:26:53 -05001348 catch (const sdbusplus::exception_t& e)
AppaRao Puli9613ed72018-09-01 23:46:44 +05301349 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001350 lg2::debug("Network interface '{INTERFACE}' does not exist",
1351 "INTERFACE", channelData[chNum].chName);
AppaRao Puli9613ed72018-09-01 23:46:44 +05301352 continue;
1353 }
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001354 catch (const std::invalid_argument& e)
1355 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001356 lg2::debug("exception: Invalid privilege");
Jiaqing Zhao826bf662022-11-07 14:33:00 +08001357 continue;
1358 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301359
AppaRao Puli9613ed72018-09-01 23:46:44 +05301360 if (channelData[chNum].chAccess.chNonVolatileData.privLimit !=
1361 intfPriv)
1362 {
1363 isUpdated = true;
1364 channelData[chNum].chAccess.chNonVolatileData.privLimit =
1365 intfPriv;
1366 channelData[chNum].chAccess.chVolatileData.privLimit = intfPriv;
1367 }
1368 }
1369 }
1370
1371 if (isUpdated)
1372 {
1373 // Write persistent data to file
1374 if (writeChannelPersistData() != 0)
1375 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001376 lg2::debug("Failed to update the persistent data file");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301377 return -EIO;
1378 }
1379 // Write Volatile data to file
1380 if (writeChannelVolatileData() != 0)
1381 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001382 lg2::debug("Failed to update the channel volatile data");
AppaRao Puli9613ed72018-09-01 23:46:44 +05301383 return -EIO;
1384 }
1385 }
1386
1387 return 0;
1388}
1389
AppaRao Puli071f3f22018-05-24 16:45:30 +05301390void ChannelConfig::initChannelPersistData()
1391{
Richard Marian Thomaiyare91474c2019-09-01 23:02:47 +05301392 boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
1393 channelLock{*channelMutex};
1394
AppaRao Puli071f3f22018-05-24 16:45:30 +05301395 /* Always read the channel config */
1396 if (loadChannelConfig() != 0)
1397 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001398 lg2::error("Failed to read channel config file");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301399 throw std::ios_base::failure("Failed to load channel configuration");
1400 }
1401
1402 /* Populate the channel persist data */
1403 if (readChannelPersistData() != 0)
1404 {
1405 // Copy default NV data to RW location
Patrick Williams3d8d7932022-06-16 12:01:28 -05001406 std::filesystem::copy_file(channelAccessDefaultFilename,
1407 channelNvDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301408
1409 // Load the channel access NV data
1410 if (readChannelPersistData() != 0)
1411 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001412 lg2::error("Failed to read channel access NV data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301413 throw std::ios_base::failure(
1414 "Failed to read channel access NV configuration");
1415 }
1416 }
1417
1418 // First check the volatile data file
1419 // If not present, load the default values
1420 if (readChannelVolatileData() != 0)
1421 {
1422 // Copy default volatile data to temporary location
1423 // NV file(channelNvDataFilename) must have created by now.
Patrick Williams3d8d7932022-06-16 12:01:28 -05001424 std::filesystem::copy_file(channelNvDataFilename,
1425 channelVolatileDataFilename);
AppaRao Puli071f3f22018-05-24 16:45:30 +05301426
1427 // Load the channel access volatile data
1428 if (readChannelVolatileData() != 0)
1429 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001430 lg2::error("Failed to read channel access volatile data");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301431 throw std::ios_base::failure(
1432 "Failed to read channel access volatile configuration");
1433 }
1434 }
AppaRao Puli9613ed72018-09-01 23:46:44 +05301435
1436 // Synchronize the channel config(priv) with network channel
1437 // configuration(priv) over dbus
1438 if (syncNetworkChannelConfig() != 0)
1439 {
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001440 lg2::error(
AppaRao Puli9613ed72018-09-01 23:46:44 +05301441 "Failed to synchronize data with network channel config over dbus");
1442 throw std::ios_base::failure(
1443 "Failed to synchronize data with network channel config over dbus");
1444 }
1445
Vernon Mauery1e3ed2c2024-03-11 12:53:55 -07001446 lg2::debug("Successfully completed channel data initialization.");
AppaRao Puli071f3f22018-05-24 16:45:30 +05301447 return;
1448}
1449
1450} // namespace ipmi