blob: b04cfd64c8613fc62e20e1937216b6445717e2d4 [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>
William A. Kennington III9b2a20d2023-06-17 14:05:48 -070014#include <stdplus/numeric/str.hpp>
Patrick Williams89d734b2023-05-10 07:50:25 -050015#include <xyz/openbmc_project/Common/error.hpp>
16
17#include <cctype>
Patrick Venture189d44e2018-07-09 12:30:59 -070018#include <string>
William A. Kennington IIIfeb7aab2022-10-03 17:21:44 -070019#include <string_view>
Ratan Gupta8804feb2017-05-25 10:49:57 +053020
21namespace phosphor
22{
23namespace network
24{
Ratan Guptabc886292017-07-25 18:29:57 +053025
William A. Kennington III69f45542022-09-24 23:28:14 -070026using std::literals::string_view_literals::operator""sv;
Ratan Gupta8804feb2017-05-25 10:49:57 +053027using namespace phosphor::logging;
Ratan Gupta11cef802017-05-29 08:41:48 +053028using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Gupta8804feb2017-05-25 10:49:57 +053029
Lei YU3894ce72021-03-18 14:53:42 +080030namespace internal
31{
32
William A. Kennington III69f45542022-09-24 23:28:14 -070033void executeCommandinChildProcess(stdplus::const_zstring path, char** args)
Lei YU3894ce72021-03-18 14:53:42 +080034{
35 using namespace std::string_literals;
36 pid_t pid = fork();
Lei YU3894ce72021-03-18 14:53:42 +080037
38 if (pid == 0)
39 {
William A. Kennington III69f45542022-09-24 23:28:14 -070040 execv(path.c_str(), args);
41 exit(255);
Lei YU3894ce72021-03-18 14:53:42 +080042 }
43 else if (pid < 0)
44 {
45 auto error = errno;
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070046 lg2::error("Error occurred during fork: {ERRNO}", "ERRNO", error);
Lei YU3894ce72021-03-18 14:53:42 +080047 elog<InternalFailure>();
48 }
49 else if (pid > 0)
50 {
William A. Kennington III69f45542022-09-24 23:28:14 -070051 int status;
Lei YU3894ce72021-03-18 14:53:42 +080052 while (waitpid(pid, &status, 0) == -1)
53 {
54 if (errno != EINTR)
William A. Kennington III69f45542022-09-24 23:28:14 -070055 {
Lei YU3894ce72021-03-18 14:53:42 +080056 status = -1;
57 break;
58 }
59 }
60
61 if (status < 0)
62 {
William A. Kennington III69f45542022-09-24 23:28:14 -070063 fmt::memory_buffer buf;
64 fmt::format_to(fmt::appender(buf), "`{}`", path);
65 for (size_t i = 0; args[i] != nullptr; ++i)
Lei YU3894ce72021-03-18 14:53:42 +080066 {
William A. Kennington III69f45542022-09-24 23:28:14 -070067 fmt::format_to(fmt::appender(buf), " `{}`", args[i]);
Lei YU3894ce72021-03-18 14:53:42 +080068 }
William A. Kennington III69f45542022-09-24 23:28:14 -070069 buf.push_back('\0');
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070070 lg2::error("Unable to execute the command {CMD}: {STATUS}", "CMD",
71 buf.data(), "STATUS", status);
Lei YU3894ce72021-03-18 14:53:42 +080072 elog<InternalFailure>();
73 }
74 }
75}
76
Lei YU307554e2021-03-18 14:56:50 +080077/** @brief Get ignored interfaces from environment */
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070078std::string_view getIgnoredInterfacesEnv()
Lei YU307554e2021-03-18 14:56:50 +080079{
80 auto r = std::getenv("IGNORED_INTERFACES");
81 if (r == nullptr)
82 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070083 return "";
Lei YU307554e2021-03-18 14:56:50 +080084 }
85 return r;
86}
87
88/** @brief Parse the comma separated interface names */
William A. Kennington III95530ec2022-08-19 01:44:39 -070089std::unordered_set<std::string_view>
90 parseInterfaces(std::string_view interfaces)
Lei YU307554e2021-03-18 14:56:50 +080091{
William A. Kennington III95530ec2022-08-19 01:44:39 -070092 std::unordered_set<std::string_view> result;
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070093 while (true)
Lei YU307554e2021-03-18 14:56:50 +080094 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070095 auto sep = interfaces.find(',');
96 auto interface = interfaces.substr(0, sep);
97 while (!interface.empty() && std::isspace(interface.front()))
Lei YU307554e2021-03-18 14:56:50 +080098 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -070099 interface.remove_prefix(1);
Lei YU307554e2021-03-18 14:56:50 +0800100 }
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700101 while (!interface.empty() && std::isspace(interface.back()))
Lei YU307554e2021-03-18 14:56:50 +0800102 {
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700103 interface.remove_suffix(1);
Lei YU307554e2021-03-18 14:56:50 +0800104 }
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700105 if (!interface.empty())
106 {
107 result.insert(interface);
108 }
109 if (sep == interfaces.npos)
110 {
111 break;
112 }
113 interfaces = interfaces.substr(sep + 1);
Lei YU307554e2021-03-18 14:56:50 +0800114 }
115 return result;
116}
117
118/** @brief Get the ignored interfaces */
William A. Kennington III95530ec2022-08-19 01:44:39 -0700119const std::unordered_set<std::string_view>& getIgnoredInterfaces()
Lei YU307554e2021-03-18 14:56:50 +0800120{
121 static auto ignoredInterfaces = parseInterfaces(getIgnoredInterfacesEnv());
122 return ignoredInterfaces;
123}
124
Lei YU3894ce72021-03-18 14:53:42 +0800125} // namespace internal
Ratan Gupta8804feb2017-05-25 10:49:57 +0530126
William A. Kennington III69f45542022-09-24 23:28:14 -0700127std::optional<std::string> interfaceToUbootEthAddr(std::string_view intf)
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700128{
William A. Kennington III69f45542022-09-24 23:28:14 -0700129 constexpr auto pfx = "eth"sv;
130 if (!intf.starts_with(pfx))
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700131 {
132 return std::nullopt;
133 }
William A. Kennington III69f45542022-09-24 23:28:14 -0700134 intf.remove_prefix(pfx.size());
William A. Kennington IIId6bd8fb2022-11-17 18:10:06 -0800135 unsigned idx;
136 try
137 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700138 idx = stdplus::StrToInt<10, unsigned>{}(intf);
William A. Kennington IIId6bd8fb2022-11-17 18:10:06 -0800139 }
140 catch (...)
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700141 {
142 return std::nullopt;
143 }
144 if (idx == 0)
145 {
146 return "ethaddr";
147 }
William A. Kennington III69f45542022-09-24 23:28:14 -0700148 return fmt::format(FMT_COMPILE("eth{}addr"), idx);
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700149}
150
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700151static std::optional<DHCPVal> systemdParseDHCP(std::string_view str)
152{
153 if (config::icaseeq(str, "ipv4"))
154 {
155 return DHCPVal{.v4 = true, .v6 = false};
156 }
157 if (config::icaseeq(str, "ipv6"))
158 {
159 return DHCPVal{.v4 = false, .v6 = true};
160 }
161 if (auto b = config::parseBool(str); b)
162 {
163 return DHCPVal{.v4 = *b, .v6 = *b};
164 }
165 return std::nullopt;
166}
167
168inline auto systemdParseLast(const config::Parser& config,
169 std::string_view section, std::string_view key,
170 auto&& fun)
171{
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800172 if (!config.getFileExists())
Patrick Williams89d734b2023-05-10 07:50:25 -0500173 {}
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800174 else if (auto str = config.map.getLastValueString(section, key);
175 str == nullptr)
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700176 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700177 lg2::notice(
178 "Unable to get the value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}",
179 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
180 config.getFilename());
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700181 }
182 else if (auto val = fun(*str); !val)
183 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700184 lg2::notice(
185 "Invalid value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}: {CFG_VAL}",
186 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
187 config.getFilename(), "CFG_VAL", *str);
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700188 }
189 else
190 {
191 return val;
192 }
193 return decltype(fun(std::string_view{}))(std::nullopt);
194}
195
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700196bool getIPv6AcceptRA(const config::Parser& config)
Ratan Gupta56187e72017-08-13 09:40:14 +0530197{
William A. Kennington III324d2602022-08-18 18:32:56 -0700198#ifdef ENABLE_IPV6_ACCEPT_RA
199 constexpr bool def = true;
200#else
201 constexpr bool def = false;
202#endif
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700203 return systemdParseLast(config, "Network", "IPv6AcceptRA",
204 config::parseBool)
205 .value_or(def);
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700206}
207
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700208DHCPVal getDHCPValue(const config::Parser& config)
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700209{
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700210 return systemdParseLast(config, "Network", "DHCP", systemdParseDHCP)
211 .value_or(DHCPVal{.v4 = true, .v6 = true});
212}
William A. Kennington III324d2602022-08-18 18:32:56 -0700213
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700214bool getDHCPProp(const config::Parser& config, std::string_view key)
215{
216 return systemdParseLast(config, "DHCP", key, config::parseBool)
217 .value_or(true);
Ratan Gupta56187e72017-08-13 09:40:14 +0530218}
219
Gunnar Mills57d9c502018-09-14 14:42:34 -0500220} // namespace network
221} // namespace phosphor