blob: ac4d1b4e4ea15985ecc3cb3efde910c1144e089b [file] [log] [blame]
William A. Kennington III324d2602022-08-18 18:32:56 -07001#include "config.h"
2
Ratan Gupta3681a502017-06-17 19:20:04 +05303#include "util.hpp"
Ratan Gupta11cef802017-05-29 08:41:48 +05304
Patrick Venture189d44e2018-07-09 12:30:59 -07005#include "config_parser.hpp"
6#include "types.hpp"
Ratan Gupta8804feb2017-05-25 10:49:57 +05307
Ratan Guptabc886292017-07-25 18:29:57 +05308#include <sys/wait.h>
Ratan Gupta3681a502017-06-17 19:20:04 +05309
Patrick Venture189d44e2018-07-09 12:30:59 -070010#include <phosphor-logging/elog-errors.hpp>
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070011#include <phosphor-logging/lg2.hpp>
William A. Kennington III9b2a20d2023-06-17 14:05:48 -070012#include <stdplus/numeric/str.hpp>
William A. Kennington III86642522023-07-24 17:55:55 -070013#include <stdplus/str/buf.hpp>
14#include <stdplus/str/cat.hpp>
Patrick Williams89d734b2023-05-10 07:50:25 -050015#include <xyz/openbmc_project/Common/error.hpp>
16
17#include <cctype>
Ravi Tejaf7116de2024-12-08 22:48:21 -060018#include <fstream>
Patrick Venture189d44e2018-07-09 12:30:59 -070019#include <string>
William A. Kennington IIIfeb7aab2022-10-03 17:21:44 -070020#include <string_view>
Ratan Gupta8804feb2017-05-25 10:49:57 +053021
22namespace phosphor
23{
24namespace network
25{
Ratan Guptabc886292017-07-25 18:29:57 +053026
William A. Kennington III69f45542022-09-24 23:28:14 -070027using std::literals::string_view_literals::operator""sv;
Ratan Gupta8804feb2017-05-25 10:49:57 +053028using namespace phosphor::logging;
Ratan Gupta11cef802017-05-29 08:41:48 +053029using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ravi Tejaf7116de2024-12-08 22:48:21 -060030static constexpr std::string_view lldpdConfigFilePath = "/etc/lldpd.conf";
Ratan Gupta8804feb2017-05-25 10:49:57 +053031
Lei YU3894ce72021-03-18 14:53:42 +080032namespace internal
33{
34
William A. Kennington III86642522023-07-24 17:55:55 -070035void executeCommandinChildProcess(stdplus::zstring_view path, char** args)
Lei YU3894ce72021-03-18 14:53:42 +080036{
37 using namespace std::string_literals;
38 pid_t pid = fork();
Lei YU3894ce72021-03-18 14:53:42 +080039
40 if (pid == 0)
41 {
William A. Kennington III69f45542022-09-24 23:28:14 -070042 execv(path.c_str(), args);
43 exit(255);
Lei YU3894ce72021-03-18 14:53:42 +080044 }
45 else if (pid < 0)
46 {
47 auto error = errno;
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070048 lg2::error("Error occurred during fork: {ERRNO}", "ERRNO", error);
Lei YU3894ce72021-03-18 14:53:42 +080049 elog<InternalFailure>();
50 }
51 else if (pid > 0)
52 {
William A. Kennington III69f45542022-09-24 23:28:14 -070053 int status;
Lei YU3894ce72021-03-18 14:53:42 +080054 while (waitpid(pid, &status, 0) == -1)
55 {
56 if (errno != EINTR)
William A. Kennington III69f45542022-09-24 23:28:14 -070057 {
Lei YU3894ce72021-03-18 14:53:42 +080058 status = -1;
59 break;
60 }
61 }
62
63 if (status < 0)
64 {
William A. Kennington III86642522023-07-24 17:55:55 -070065 stdplus::StrBuf buf;
66 stdplus::strAppend(buf, "`"sv, path, "`"sv);
William A. Kennington III69f45542022-09-24 23:28:14 -070067 for (size_t i = 0; args[i] != nullptr; ++i)
Lei YU3894ce72021-03-18 14:53:42 +080068 {
William A. Kennington III86642522023-07-24 17:55:55 -070069 stdplus::strAppend(buf, " `"sv, args[i], "`"sv);
Lei YU3894ce72021-03-18 14:53:42 +080070 }
William A. Kennington III69f45542022-09-24 23:28:14 -070071 buf.push_back('\0');
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070072 lg2::error("Unable to execute the command {CMD}: {STATUS}", "CMD",
73 buf.data(), "STATUS", status);
Lei YU3894ce72021-03-18 14:53:42 +080074 elog<InternalFailure>();
75 }
76 }
77}
78
Lei YU307554e2021-03-18 14:56:50 +080079/** @brief Get ignored interfaces from environment */
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070080std::string_view getIgnoredInterfacesEnv()
Lei YU307554e2021-03-18 14:56:50 +080081{
82 auto r = std::getenv("IGNORED_INTERFACES");
83 if (r == nullptr)
84 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070085 return "";
Lei YU307554e2021-03-18 14:56:50 +080086 }
87 return r;
88}
89
90/** @brief Parse the comma separated interface names */
William A. Kennington III95530ec2022-08-19 01:44:39 -070091std::unordered_set<std::string_view>
92 parseInterfaces(std::string_view interfaces)
Lei YU307554e2021-03-18 14:56:50 +080093{
William A. Kennington III95530ec2022-08-19 01:44:39 -070094 std::unordered_set<std::string_view> result;
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070095 while (true)
Lei YU307554e2021-03-18 14:56:50 +080096 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070097 auto sep = interfaces.find(',');
98 auto interface = interfaces.substr(0, sep);
99 while (!interface.empty() && std::isspace(interface.front()))
Lei YU307554e2021-03-18 14:56:50 +0800100 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700101 interface.remove_prefix(1);
Lei YU307554e2021-03-18 14:56:50 +0800102 }
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700103 while (!interface.empty() && std::isspace(interface.back()))
Lei YU307554e2021-03-18 14:56:50 +0800104 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700105 interface.remove_suffix(1);
Lei YU307554e2021-03-18 14:56:50 +0800106 }
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700107 if (!interface.empty())
108 {
109 result.insert(interface);
110 }
111 if (sep == interfaces.npos)
112 {
113 break;
114 }
115 interfaces = interfaces.substr(sep + 1);
Lei YU307554e2021-03-18 14:56:50 +0800116 }
117 return result;
118}
119
120/** @brief Get the ignored interfaces */
William A. Kennington III95530ec2022-08-19 01:44:39 -0700121const std::unordered_set<std::string_view>& getIgnoredInterfaces()
Lei YU307554e2021-03-18 14:56:50 +0800122{
123 static auto ignoredInterfaces = parseInterfaces(getIgnoredInterfacesEnv());
124 return ignoredInterfaces;
125}
126
Lei YU3894ce72021-03-18 14:53:42 +0800127} // namespace internal
Ratan Gupta8804feb2017-05-25 10:49:57 +0530128
William A. Kennington III69f45542022-09-24 23:28:14 -0700129std::optional<std::string> interfaceToUbootEthAddr(std::string_view intf)
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700130{
William A. Kennington III69f45542022-09-24 23:28:14 -0700131 constexpr auto pfx = "eth"sv;
132 if (!intf.starts_with(pfx))
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700133 {
134 return std::nullopt;
135 }
William A. Kennington III69f45542022-09-24 23:28:14 -0700136 intf.remove_prefix(pfx.size());
William A. Kennington IIId6bd8fb2022-11-17 18:10:06 -0800137 unsigned idx;
138 try
139 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700140 idx = stdplus::StrToInt<10, unsigned>{}(intf);
William A. Kennington IIId6bd8fb2022-11-17 18:10:06 -0800141 }
142 catch (...)
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700143 {
144 return std::nullopt;
145 }
146 if (idx == 0)
147 {
148 return "ethaddr";
149 }
William A. Kennington III86642522023-07-24 17:55:55 -0700150 stdplus::ToStrHandle<stdplus::IntToStr<10, unsigned>> tsh;
151 return stdplus::strCat("eth"sv, tsh(idx), "addr"sv);
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700152}
153
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700154static std::optional<DHCPVal> systemdParseDHCP(std::string_view str)
155{
156 if (config::icaseeq(str, "ipv4"))
157 {
158 return DHCPVal{.v4 = true, .v6 = false};
159 }
160 if (config::icaseeq(str, "ipv6"))
161 {
162 return DHCPVal{.v4 = false, .v6 = true};
163 }
164 if (auto b = config::parseBool(str); b)
165 {
166 return DHCPVal{.v4 = *b, .v6 = *b};
167 }
168 return std::nullopt;
169}
170
171inline auto systemdParseLast(const config::Parser& config,
172 std::string_view section, std::string_view key,
173 auto&& fun)
174{
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800175 if (!config.getFileExists())
Patrick Williams89d734b2023-05-10 07:50:25 -0500176 {}
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800177 else if (auto str = config.map.getLastValueString(section, key);
178 str == nullptr)
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700179 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700180 lg2::notice(
181 "Unable to get the value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}",
182 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
183 config.getFilename());
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700184 }
185 else if (auto val = fun(*str); !val)
186 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700187 lg2::notice(
188 "Invalid value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}: {CFG_VAL}",
189 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
190 config.getFilename(), "CFG_VAL", *str);
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700191 }
192 else
193 {
194 return val;
195 }
196 return decltype(fun(std::string_view{}))(std::nullopt);
197}
198
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700199bool getIPv6AcceptRA(const config::Parser& config)
Ratan Gupta56187e72017-08-13 09:40:14 +0530200{
William A. Kennington III324d2602022-08-18 18:32:56 -0700201#ifdef ENABLE_IPV6_ACCEPT_RA
202 constexpr bool def = true;
203#else
204 constexpr bool def = false;
205#endif
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700206 return systemdParseLast(config, "Network", "IPv6AcceptRA",
207 config::parseBool)
208 .value_or(def);
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700209}
210
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700211DHCPVal getDHCPValue(const config::Parser& config)
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700212{
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700213 return systemdParseLast(config, "Network", "DHCP", systemdParseDHCP)
214 .value_or(DHCPVal{.v4 = true, .v6 = true});
215}
William A. Kennington III324d2602022-08-18 18:32:56 -0700216
Jishnu CM57dfea92023-05-05 06:07:26 -0500217bool getDHCPProp(const config::Parser& config, DHCPType dhcpType,
218 std::string_view key)
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700219{
Jishnu CM57dfea92023-05-05 06:07:26 -0500220 std::string_view type = (dhcpType == DHCPType::v4) ? "DHCPv4" : "DHCPv6";
221
222 if (!config.map.contains(type))
223 {
224 type = "DHCP";
225 }
226
227 return systemdParseLast(config, type, key, config::parseBool)
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700228 .value_or(true);
Ratan Gupta56187e72017-08-13 09:40:14 +0530229}
230
Ravi Tejaf7116de2024-12-08 22:48:21 -0600231std::map<std::string, bool> parseLLDPConf()
232{
233 std::ifstream lldpdConfig(lldpdConfigFilePath.data());
234 std::map<std::string, bool> portStatus;
235
236 if (!lldpdConfig.is_open())
237 {
238 return portStatus;
239 }
240
241 std::string line;
242 while (std::getline(lldpdConfig, line))
243 {
244 std::string configurePortsStr = "configure ports ";
245 std::string lldpStatusStr = "lldp status ";
246 size_t portStart = line.find(configurePortsStr);
247 if (portStart != std::string::npos)
248 {
249 portStart += configurePortsStr.size();
250 size_t portEnd = line.find(' ', portStart);
251 if (portEnd == std::string::npos)
252 {
253 portEnd = line.length();
254 }
255 std::string portName = line.substr(portStart, portEnd - portStart);
256 size_t pos = line.find(lldpStatusStr);
257 if (pos != std::string::npos)
258 {
259 std::string statusStr = line.substr(pos + lldpStatusStr.size());
260 portStatus[portName] = (statusStr == "disabled") ? false : true;
261 }
262 }
263 }
264 lldpdConfig.close();
265 return portStatus;
266}
267
Gunnar Mills57d9c502018-09-14 14:42:34 -0500268} // namespace network
269} // namespace phosphor