blob: 71023723876192a783a51304aaa5353b3014728c [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
William A. Kennington III1c776022022-01-05 14:12:16 -08008#include <fmt/compile.h>
9#include <fmt/format.h>
Ratan Guptabc886292017-07-25 18:29:57 +053010#include <sys/wait.h>
Ratan Gupta3681a502017-06-17 19:20:04 +053011
Patrick Venture189d44e2018-07-09 12:30:59 -070012#include <phosphor-logging/elog-errors.hpp>
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070013#include <phosphor-logging/lg2.hpp>
Patrick Williams89d734b2023-05-10 07:50:25 -050014#include <xyz/openbmc_project/Common/error.hpp>
15
16#include <cctype>
Patrick Venture189d44e2018-07-09 12:30:59 -070017#include <string>
William A. Kennington IIIfeb7aab2022-10-03 17:21:44 -070018#include <string_view>
Ratan Gupta8804feb2017-05-25 10:49:57 +053019
20namespace phosphor
21{
22namespace network
23{
Ratan Guptabc886292017-07-25 18:29:57 +053024
William A. Kennington III69f45542022-09-24 23:28:14 -070025using std::literals::string_view_literals::operator""sv;
Ratan Gupta8804feb2017-05-25 10:49:57 +053026using namespace phosphor::logging;
Ratan Gupta11cef802017-05-29 08:41:48 +053027using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta8804feb2017-05-25 10:49:57 +053028
Lei YU3894ce72021-03-18 14:53:42 +080029namespace internal
30{
31
William A. Kennington III69f45542022-09-24 23:28:14 -070032void executeCommandinChildProcess(stdplus::const_zstring path, char** args)
Lei YU3894ce72021-03-18 14:53:42 +080033{
34 using namespace std::string_literals;
35 pid_t pid = fork();
Lei YU3894ce72021-03-18 14:53:42 +080036
37 if (pid == 0)
38 {
William A. Kennington III69f45542022-09-24 23:28:14 -070039 execv(path.c_str(), args);
40 exit(255);
Lei YU3894ce72021-03-18 14:53:42 +080041 }
42 else if (pid < 0)
43 {
44 auto error = errno;
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070045 lg2::error("Error occurred during fork: {ERRNO}", "ERRNO", error);
Lei YU3894ce72021-03-18 14:53:42 +080046 elog<InternalFailure>();
47 }
48 else if (pid > 0)
49 {
William A. Kennington III69f45542022-09-24 23:28:14 -070050 int status;
Lei YU3894ce72021-03-18 14:53:42 +080051 while (waitpid(pid, &status, 0) == -1)
52 {
53 if (errno != EINTR)
William A. Kennington III69f45542022-09-24 23:28:14 -070054 {
Lei YU3894ce72021-03-18 14:53:42 +080055 status = -1;
56 break;
57 }
58 }
59
60 if (status < 0)
61 {
William A. Kennington III69f45542022-09-24 23:28:14 -070062 fmt::memory_buffer buf;
63 fmt::format_to(fmt::appender(buf), "`{}`", path);
64 for (size_t i = 0; args[i] != nullptr; ++i)
Lei YU3894ce72021-03-18 14:53:42 +080065 {
William A. Kennington III69f45542022-09-24 23:28:14 -070066 fmt::format_to(fmt::appender(buf), " `{}`", args[i]);
Lei YU3894ce72021-03-18 14:53:42 +080067 }
William A. Kennington III69f45542022-09-24 23:28:14 -070068 buf.push_back('\0');
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070069 lg2::error("Unable to execute the command {CMD}: {STATUS}", "CMD",
70 buf.data(), "STATUS", status);
Lei YU3894ce72021-03-18 14:53:42 +080071 elog<InternalFailure>();
72 }
73 }
74}
75
Lei YU307554e2021-03-18 14:56:50 +080076/** @brief Get ignored interfaces from environment */
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070077std::string_view getIgnoredInterfacesEnv()
Lei YU307554e2021-03-18 14:56:50 +080078{
79 auto r = std::getenv("IGNORED_INTERFACES");
80 if (r == nullptr)
81 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070082 return "";
Lei YU307554e2021-03-18 14:56:50 +080083 }
84 return r;
85}
86
87/** @brief Parse the comma separated interface names */
William A. Kennington III95530ec2022-08-19 01:44:39 -070088std::unordered_set<std::string_view>
89 parseInterfaces(std::string_view interfaces)
Lei YU307554e2021-03-18 14:56:50 +080090{
William A. Kennington III95530ec2022-08-19 01:44:39 -070091 std::unordered_set<std::string_view> result;
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070092 while (true)
Lei YU307554e2021-03-18 14:56:50 +080093 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070094 auto sep = interfaces.find(',');
95 auto interface = interfaces.substr(0, sep);
96 while (!interface.empty() && std::isspace(interface.front()))
Lei YU307554e2021-03-18 14:56:50 +080097 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070098 interface.remove_prefix(1);
Lei YU307554e2021-03-18 14:56:50 +080099 }
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700100 while (!interface.empty() && std::isspace(interface.back()))
Lei YU307554e2021-03-18 14:56:50 +0800101 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700102 interface.remove_suffix(1);
Lei YU307554e2021-03-18 14:56:50 +0800103 }
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700104 if (!interface.empty())
105 {
106 result.insert(interface);
107 }
108 if (sep == interfaces.npos)
109 {
110 break;
111 }
112 interfaces = interfaces.substr(sep + 1);
Lei YU307554e2021-03-18 14:56:50 +0800113 }
114 return result;
115}
116
117/** @brief Get the ignored interfaces */
William A. Kennington III95530ec2022-08-19 01:44:39 -0700118const std::unordered_set<std::string_view>& getIgnoredInterfaces()
Lei YU307554e2021-03-18 14:56:50 +0800119{
120 static auto ignoredInterfaces = parseInterfaces(getIgnoredInterfacesEnv());
121 return ignoredInterfaces;
122}
123
Lei YU3894ce72021-03-18 14:53:42 +0800124} // namespace internal
Ratan Gupta8804feb2017-05-25 10:49:57 +0530125
William A. Kennington III69f45542022-09-24 23:28:14 -0700126std::optional<std::string> interfaceToUbootEthAddr(std::string_view intf)
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700127{
William A. Kennington III69f45542022-09-24 23:28:14 -0700128 constexpr auto pfx = "eth"sv;
129 if (!intf.starts_with(pfx))
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700130 {
131 return std::nullopt;
132 }
William A. Kennington III69f45542022-09-24 23:28:14 -0700133 intf.remove_prefix(pfx.size());
William A. Kennington IIId6bd8fb2022-11-17 18:10:06 -0800134 unsigned idx;
135 try
136 {
137 idx = DecodeInt<unsigned, 10>{}(intf);
138 }
139 catch (...)
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700140 {
141 return std::nullopt;
142 }
143 if (idx == 0)
144 {
145 return "ethaddr";
146 }
William A. Kennington III69f45542022-09-24 23:28:14 -0700147 return fmt::format(FMT_COMPILE("eth{}addr"), idx);
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700148}
149
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700150static std::optional<DHCPVal> systemdParseDHCP(std::string_view str)
151{
152 if (config::icaseeq(str, "ipv4"))
153 {
154 return DHCPVal{.v4 = true, .v6 = false};
155 }
156 if (config::icaseeq(str, "ipv6"))
157 {
158 return DHCPVal{.v4 = false, .v6 = true};
159 }
160 if (auto b = config::parseBool(str); b)
161 {
162 return DHCPVal{.v4 = *b, .v6 = *b};
163 }
164 return std::nullopt;
165}
166
167inline auto systemdParseLast(const config::Parser& config,
168 std::string_view section, std::string_view key,
169 auto&& fun)
170{
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800171 if (!config.getFileExists())
Patrick Williams89d734b2023-05-10 07:50:25 -0500172 {}
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800173 else if (auto str = config.map.getLastValueString(section, key);
174 str == nullptr)
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700175 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700176 lg2::notice(
177 "Unable to get the value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}",
178 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
179 config.getFilename());
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700180 }
181 else if (auto val = fun(*str); !val)
182 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700183 lg2::notice(
184 "Invalid value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}: {CFG_VAL}",
185 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
186 config.getFilename(), "CFG_VAL", *str);
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700187 }
188 else
189 {
190 return val;
191 }
192 return decltype(fun(std::string_view{}))(std::nullopt);
193}
194
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700195bool getIPv6AcceptRA(const config::Parser& config)
Ratan Gupta56187e72017-08-13 09:40:14 +0530196{
William A. Kennington III324d2602022-08-18 18:32:56 -0700197#ifdef ENABLE_IPV6_ACCEPT_RA
198 constexpr bool def = true;
199#else
200 constexpr bool def = false;
201#endif
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700202 return systemdParseLast(config, "Network", "IPv6AcceptRA",
203 config::parseBool)
204 .value_or(def);
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700205}
206
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700207DHCPVal getDHCPValue(const config::Parser& config)
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700208{
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700209 return systemdParseLast(config, "Network", "DHCP", systemdParseDHCP)
210 .value_or(DHCPVal{.v4 = true, .v6 = true});
211}
William A. Kennington III324d2602022-08-18 18:32:56 -0700212
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700213bool getDHCPProp(const config::Parser& config, std::string_view key)
214{
215 return systemdParseLast(config, "DHCP", key, config::parseBool)
216 .value_or(true);
Ratan Gupta56187e72017-08-13 09:40:14 +0530217}
218
Gunnar Mills57d9c502018-09-14 14:42:34 -0500219} // namespace network
220} // namespace phosphor