blob: 3e1916ad2e896049493e5a595f890ca8ef67d94d [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>
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 III86642522023-07-24 17:55:55 -070033void executeCommandinChildProcess(stdplus::zstring_view 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 III86642522023-07-24 17:55:55 -070063 stdplus::StrBuf buf;
64 stdplus::strAppend(buf, "`"sv, path, "`"sv);
William A. Kennington III69f45542022-09-24 23:28:14 -070065 for (size_t i = 0; args[i] != nullptr; ++i)
Lei YU3894ce72021-03-18 14:53:42 +080066 {
William A. Kennington III86642522023-07-24 17:55:55 -070067 stdplus::strAppend(buf, " `"sv, args[i], "`"sv);
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 III86642522023-07-24 17:55:55 -0700148 stdplus::ToStrHandle<stdplus::IntToStr<10, unsigned>> tsh;
149 return stdplus::strCat("eth"sv, tsh(idx), "addr"sv);
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700150}
151
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700152static std::optional<DHCPVal> systemdParseDHCP(std::string_view str)
153{
154 if (config::icaseeq(str, "ipv4"))
155 {
156 return DHCPVal{.v4 = true, .v6 = false};
157 }
158 if (config::icaseeq(str, "ipv6"))
159 {
160 return DHCPVal{.v4 = false, .v6 = true};
161 }
162 if (auto b = config::parseBool(str); b)
163 {
164 return DHCPVal{.v4 = *b, .v6 = *b};
165 }
166 return std::nullopt;
167}
168
169inline auto systemdParseLast(const config::Parser& config,
170 std::string_view section, std::string_view key,
171 auto&& fun)
172{
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800173 if (!config.getFileExists())
Patrick Williams89d734b2023-05-10 07:50:25 -0500174 {}
William A. Kennington III4a688fc2022-11-15 15:58:44 -0800175 else if (auto str = config.map.getLastValueString(section, key);
176 str == nullptr)
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700177 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700178 lg2::notice(
179 "Unable to get the value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}",
180 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
181 config.getFilename());
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700182 }
183 else if (auto val = fun(*str); !val)
184 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700185 lg2::notice(
186 "Invalid value of {CFG_SEC}[{CFG_KEY}] from {CFG_FILE}: {CFG_VAL}",
187 "CFG_SEC", section, "CFG_KEY", key, "CFG_FILE",
188 config.getFilename(), "CFG_VAL", *str);
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700189 }
190 else
191 {
192 return val;
193 }
194 return decltype(fun(std::string_view{}))(std::nullopt);
195}
196
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700197bool getIPv6AcceptRA(const config::Parser& config)
Ratan Gupta56187e72017-08-13 09:40:14 +0530198{
William A. Kennington III324d2602022-08-18 18:32:56 -0700199#ifdef ENABLE_IPV6_ACCEPT_RA
200 constexpr bool def = true;
201#else
202 constexpr bool def = false;
203#endif
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700204 return systemdParseLast(config, "Network", "IPv6AcceptRA",
205 config::parseBool)
206 .value_or(def);
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700207}
208
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700209DHCPVal getDHCPValue(const config::Parser& config)
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700210{
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700211 return systemdParseLast(config, "Network", "DHCP", systemdParseDHCP)
212 .value_or(DHCPVal{.v4 = true, .v6 = true});
213}
William A. Kennington III324d2602022-08-18 18:32:56 -0700214
William A. Kennington IIIe94c9ff2022-08-18 20:12:27 -0700215bool getDHCPProp(const config::Parser& config, std::string_view key)
216{
217 return systemdParseLast(config, "DHCP", key, config::parseBool)
218 .value_or(true);
Ratan Gupta56187e72017-08-13 09:40:14 +0530219}
220
Gunnar Mills57d9c502018-09-14 14:42:34 -0500221} // namespace network
222} // namespace phosphor