blob: 2634e1160ff0f4e5be6e737d20c768ce6a30e4b9 [file] [log] [blame]
Gunnar Mills57d9c502018-09-14 14:42:34 -05001#include "config.h"
2
Ratan Gupta6811f822017-04-14 16:34:56 +05303#include "network_manager.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07004
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07005#include "config_parser.hpp"
Ratan Gupta5978dd12017-07-25 13:47:13 +05306#include "ipaddress.hpp"
William A. Kennington III2e09d272022-10-14 17:15:00 -07007#include "system_queries.hpp"
William A. Kennington III3a70fa22018-09-20 18:48:20 -07008#include "types.hpp"
William A. Kennington IIIb8006122022-11-13 18:15:15 -08009#include "util.hpp"
10
William A. Kennington III57ca9612022-11-14 15:26:47 -080011#include <linux/if_addr.h>
William A. Kennington III7310ac72022-11-14 15:44:00 -080012#include <linux/neighbour.h>
William A. Kennington IIIb8006122022-11-13 18:15:15 -080013#include <net/if.h>
Ratan Gupta738a67f2017-04-21 10:38:05 +053014
Manojkiran Edacc099a82020-05-11 14:25:16 +053015#include <filesystem>
Patrick Venture189d44e2018-07-09 12:30:59 -070016#include <fstream>
Patrick Venture189d44e2018-07-09 12:30:59 -070017#include <phosphor-logging/elog-errors.hpp>
18#include <phosphor-logging/log.hpp>
William A. Kennington III80d29012022-11-12 02:31:40 -080019#include <sdbusplus/message.hpp>
Patrick Venture189d44e2018-07-09 12:30:59 -070020#include <xyz/openbmc_project/Common/error.hpp>
Ratan Gupta6811f822017-04-14 16:34:56 +053021
William A. Kennington IIIf1aa51c2019-02-12 19:58:11 -080022constexpr char SYSTEMD_BUSNAME[] = "org.freedesktop.systemd1";
23constexpr char SYSTEMD_PATH[] = "/org/freedesktop/systemd1";
24constexpr char SYSTEMD_INTERFACE[] = "org.freedesktop.systemd1.Manager";
Manojkiran Edacc099a82020-05-11 14:25:16 +053025constexpr auto FirstBootFile = "/var/lib/network/firstBoot_";
William A. Kennington IIIf1aa51c2019-02-12 19:58:11 -080026
William A. Kennington III56ecc782021-10-07 18:44:50 -070027constexpr char NETWORKD_BUSNAME[] = "org.freedesktop.network1";
28constexpr char NETWORKD_PATH[] = "/org/freedesktop/network1";
29constexpr char NETWORKD_INTERFACE[] = "org.freedesktop.network1.Manager";
30
Ratan Gupta6811f822017-04-14 16:34:56 +053031namespace phosphor
32{
33namespace network
34{
Ratan Gupta82549cc2017-04-21 08:45:23 +053035
William A. Kennington IIId41db382021-11-09 20:42:29 -080036extern std::unique_ptr<Timer> refreshObjectTimer;
William A. Kennington IIIc7cf25f2021-11-09 16:16:59 -080037extern std::unique_ptr<Timer> reloadTimer;
Ratan Gupta6811f822017-04-14 16:34:56 +053038using namespace phosphor::logging;
Ratan Guptaef85eb92017-06-15 08:57:54 +053039using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Jiaqing Zhaob685cb62022-04-12 22:57:34 +080040using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Gupta6811f822017-04-14 16:34:56 +053041
William A. Kennington III80d29012022-11-12 02:31:40 -080042static constexpr const char enabledMatch[] =
43 "type='signal',sender='org.freedesktop.network1',path_namespace='/org/"
44 "freedesktop/network1/"
45 "link',interface='org.freedesktop.DBus.Properties',member='"
46 "PropertiesChanged',arg0='org.freedesktop.network1.Link',";
47
Patrick Williamsc38b0712022-07-22 19:26:54 -050048Manager::Manager(sdbusplus::bus_t& bus, const char* objPath,
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070049 const fs::path& confDir) :
Patrick Williams166b9592022-03-30 16:09:16 -050050 details::VLANCreateIface(bus, objPath,
51 details::VLANCreateIface::action::defer_emit),
William A. Kennington III80d29012022-11-12 02:31:40 -080052 bus(bus), objectPath(objPath),
53 systemdNetworkdEnabledMatch(
54 bus, enabledMatch, [&](sdbusplus::message_t& m) {
55 std::string intf;
56 std::unordered_map<std::string, std::variant<std::string>> values;
57 try
58 {
59 m.read(intf, values);
60 auto it = values.find("AdministrativeState");
61 if (it == values.end())
62 {
63 return;
64 }
65 const std::string_view obj = m.get_path();
66 auto sep = obj.rfind('/');
67 if (sep == obj.npos || sep + 3 > obj.size())
68 {
69 throw std::invalid_argument("Invalid obj path");
70 }
71 auto ifidx = DecodeInt<unsigned, 10>{}(obj.substr(sep + 3));
72 const auto& state = std::get<std::string>(it->second);
73 handleAdminState(state, ifidx);
74 }
75 catch (const std::exception& e)
76 {
77 log<level::ERR>(
78 fmt::format("AdministrativeState match parsing failed: {}",
79 e.what())
80 .c_str(),
81 entry("ERROR=%s", e.what()));
82 }
83 })
Ratan Gupta6811f822017-04-14 16:34:56 +053084{
Ratan Gupta255d5142017-08-10 09:02:08 +053085 setConfDir(confDir);
William A. Kennington III80d29012022-11-12 02:31:40 -080086 std::vector<
87 std::tuple<int32_t, std::string, sdbusplus::message::object_path>>
88 links;
89 try
90 {
91 auto rsp =
92 bus.new_method_call("org.freedesktop.network1",
93 "/org/freedesktop/network1",
94 "org.freedesktop.network1.Manager", "ListLinks")
95 .call();
96 rsp.read(links);
97 }
98 catch (const sdbusplus::exception::SdBusError& e)
99 {
100 // Any failures are systemd-network not being ready
101 }
102 for (const auto& link : links)
103 {
104 unsigned ifidx = std::get<0>(link);
105 auto obj = fmt::format("/org/freedesktop/network1/link/_3{}", ifidx);
106 auto req =
107 bus.new_method_call("org.freedesktop.network1", obj.c_str(),
108 "org.freedesktop.DBus.Properties", "Get");
109 req.append("org.freedesktop.network1.Link", "AdministrativeState");
110 auto rsp = req.call();
111 std::variant<std::string> val;
112 rsp.read(val);
113 handleAdminState(std::get<std::string>(val), ifidx);
114 }
Ratan Guptaef85eb92017-06-15 08:57:54 +0530115}
116
117void Manager::setConfDir(const fs::path& dir)
118{
119 confDir = dir;
Ratan Gupta255d5142017-08-10 09:02:08 +0530120
121 if (!fs::exists(confDir))
122 {
123 if (!fs::create_directories(confDir))
124 {
125 log<level::ERR>("Unable to create the network conf dir",
126 entry("DIR=%s", confDir.c_str()));
127 elog<InternalFailure>();
128 }
129 }
Ratan Gupta29b0e432017-05-25 12:51:40 +0530130}
131
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800132void Manager::createInterface(const UndiscoveredInfo& info, bool enabled)
William A. Kennington III80d29012022-11-12 02:31:40 -0800133{
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800134 if (!info.intf.name)
135 {
136 auto msg = fmt::format("Can't create interface without name: {}",
137 info.intf.idx);
138 log<level::ERR>(msg.c_str(), entry("IFIDX=%u", info.intf.idx));
139 return;
140 }
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800141 removeInterface(info.intf);
142 config::Parser config(config::pathForIntfConf(confDir, *info.intf.name));
William A. Kennington III80d29012022-11-12 02:31:40 -0800143 auto intf = std::make_unique<EthernetInterface>(
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800144 bus, *this, info.intf, objectPath, config, true, enabled);
William A. Kennington III80d29012022-11-12 02:31:40 -0800145 intf->createIPAddressObjects();
146 intf->createStaticNeighborObjects();
147 intf->loadNameServers(config);
148 intf->loadNTPServers(config);
149 auto ptr = intf.get();
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800150 interfaces.insert_or_assign(*info.intf.name, std::move(intf));
151 interfacesByIdx.insert_or_assign(info.intf.idx, ptr);
William A. Kennington III80d29012022-11-12 02:31:40 -0800152}
153
William A. Kennington III0813a242022-11-12 18:07:11 -0800154void Manager::addInterface(const InterfaceInfo& info)
155{
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800156 if (info.flags & IFF_LOOPBACK)
157 {
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800158 ignoredIntf.emplace(info.idx);
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800159 return;
160 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800161 if (info.name)
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800162 {
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800163 const auto& ignored = internal::getIgnoredInterfaces();
164 if (ignored.find(*info.name) != ignored.end())
165 {
166 static std::unordered_set<std::string> ignored;
167 if (!ignored.contains(*info.name))
168 {
169 ignored.emplace(*info.name);
170 auto msg = fmt::format("Ignoring interface {}\n", *info.name);
171 log<level::INFO>(msg.c_str());
172 }
173 ignoredIntf.emplace(info.idx);
174 return;
175 }
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800176 }
177
William A. Kennington III0813a242022-11-12 18:07:11 -0800178 auto it = systemdNetworkdEnabled.find(info.idx);
179 if (it != systemdNetworkdEnabled.end())
180 {
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800181 createInterface({info}, it->second);
William A. Kennington III0813a242022-11-12 18:07:11 -0800182 }
183 else
184 {
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800185 undiscoveredIntfInfo.insert_or_assign(
186 info.idx, UndiscoveredInfo{std::move(info)});
William A. Kennington III0813a242022-11-12 18:07:11 -0800187 }
188}
189
190void Manager::removeInterface(const InterfaceInfo& info)
191{
192 auto iit = interfacesByIdx.find(info.idx);
193 auto nit = interfaces.end();
194 if (info.name)
195 {
196 nit = interfaces.find(*info.name);
197 if (nit != interfaces.end() && iit != interfacesByIdx.end() &&
198 nit->second.get() != iit->second)
199 {
200 fmt::print(stderr, "Removed interface desync detected\n");
201 fflush(stderr);
202 std::abort();
203 }
204 }
205 else if (iit != interfacesByIdx.end())
206 {
207 for (nit = interfaces.begin(); nit != interfaces.end(); ++nit)
208 {
209 if (nit->second.get() == iit->second)
210 {
211 break;
212 }
213 }
214 }
215
216 if (iit != interfacesByIdx.end())
217 {
218 interfacesByIdx.erase(iit);
219 }
220 else
221 {
222 undiscoveredIntfInfo.erase(info.idx);
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800223 ignoredIntf.erase(info.idx);
William A. Kennington III0813a242022-11-12 18:07:11 -0800224 }
225 if (nit != interfaces.end())
226 {
227 interfaces.erase(nit);
228 }
229}
230
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800231void Manager::addAddress(const AddressInfo& info)
232{
William A. Kennington III57ca9612022-11-14 15:26:47 -0800233 if (info.flags & IFA_F_DEPRECATED)
234 {
235 return;
236 }
237 if (auto it = interfacesByIdx.find(info.ifidx); it != interfacesByIdx.end())
238 {
239 it->second->addAddr(info);
240 }
241 else if (auto it = undiscoveredIntfInfo.find(info.ifidx);
242 it != undiscoveredIntfInfo.end())
243 {
244 it->second.addrs.insert_or_assign(info.ifaddr, info);
245 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800246 else if (!ignoredIntf.contains(info.ifidx))
William A. Kennington III57ca9612022-11-14 15:26:47 -0800247 {
248 throw std::runtime_error(
249 fmt::format("Interface `{}` not found for addr", info.ifidx));
250 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800251}
252
253void Manager::removeAddress(const AddressInfo& info)
254{
William A. Kennington III57ca9612022-11-14 15:26:47 -0800255 if (auto it = interfacesByIdx.find(info.ifidx); it != interfacesByIdx.end())
256 {
257 it->second->addrs.erase(info.ifaddr);
258 }
259 else if (auto it = undiscoveredIntfInfo.find(info.ifidx);
260 it != undiscoveredIntfInfo.end())
261 {
262 it->second.addrs.erase(info.ifaddr);
263 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800264}
265
266void Manager::addNeighbor(const NeighborInfo& info)
267{
William A. Kennington III7310ac72022-11-14 15:44:00 -0800268 if (!(info.state & NUD_PERMANENT) || !info.addr)
269 {
270 return;
271 }
272 if (auto it = interfacesByIdx.find(info.ifidx); it != interfacesByIdx.end())
273 {
274 it->second->addStaticNeigh(info);
275 }
276 else if (auto it = undiscoveredIntfInfo.find(info.ifidx);
277 it != undiscoveredIntfInfo.end())
278 {
279 it->second.staticNeighs.insert_or_assign(*info.addr, info);
280 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800281 else if (!ignoredIntf.contains(info.ifidx))
William A. Kennington III7310ac72022-11-14 15:44:00 -0800282 {
283 throw std::runtime_error(
284 fmt::format("Interface `{}` not found for neigh", info.ifidx));
285 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800286}
287
288void Manager::removeNeighbor(const NeighborInfo& info)
289{
William A. Kennington III7310ac72022-11-14 15:44:00 -0800290 if (!info.addr)
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800291 {
William A. Kennington III7310ac72022-11-14 15:44:00 -0800292 return;
293 }
294 if (auto it = interfacesByIdx.find(info.ifidx); it != interfacesByIdx.end())
295 {
296 it->second->staticNeighbors.erase(*info.addr);
297 }
298 else if (auto it = undiscoveredIntfInfo.find(info.ifidx);
299 it != undiscoveredIntfInfo.end())
300 {
301 it->second.staticNeighs.erase(*info.addr);
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800302 }
303}
304
305void Manager::addDefGw(unsigned ifidx, InAddrAny addr)
306{
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800307 if (auto it = interfacesByIdx.find(ifidx); it != interfacesByIdx.end())
308 {
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800309 std::visit(
310 [&](auto addr) {
311 if constexpr (std::is_same_v<in_addr, decltype(addr)>)
312 {
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800313 it->second->EthernetInterfaceIntf::defaultGateway(
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800314 std::to_string(addr));
315 }
316 else if constexpr (std::is_same_v<in6_addr, decltype(addr)>)
317 {
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800318 it->second->EthernetInterfaceIntf::defaultGateway6(
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800319 std::to_string(addr));
320 }
321 else
322 {
323 static_assert(!std::is_same_v<void, decltype(addr)>);
324 }
325 },
326 addr);
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800327 }
328 else if (auto it = undiscoveredIntfInfo.find(ifidx);
329 it != undiscoveredIntfInfo.end())
330 {
331 std::visit(
332 [&](auto addr) {
333 if constexpr (std::is_same_v<in_addr, decltype(addr)>)
334 {
335 it->second.defgw4.emplace(addr);
336 }
337 else if constexpr (std::is_same_v<in6_addr, decltype(addr)>)
338 {
339 it->second.defgw6.emplace(addr);
340 }
341 else
342 {
343 static_assert(!std::is_same_v<void, decltype(addr)>);
344 }
345 },
346 addr);
347 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800348 else if (!ignoredIntf.contains(ifidx))
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800349 {
350 auto msg = fmt::format("Interface `{}` not found for gw", ifidx);
351 log<level::ERR>(msg.c_str(), entry("IFIDX=%u", ifidx));
352 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800353}
354
355void Manager::removeDefGw(unsigned ifidx, InAddrAny addr)
356{
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800357 if (auto it = interfacesByIdx.find(ifidx); it != interfacesByIdx.end())
358 {
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800359 std::visit(
360 [&](auto addr) {
361 if constexpr (std::is_same_v<in_addr, decltype(addr)>)
362 {
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800363 if (it->second->defaultGateway() == std::to_string(addr))
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800364 {
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800365 it->second->EthernetInterfaceIntf::defaultGateway("");
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800366 }
367 }
368 else if constexpr (std::is_same_v<in6_addr, decltype(addr)>)
369 {
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800370 if (it->second->defaultGateway6() == std::to_string(addr))
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800371 {
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800372 it->second->EthernetInterfaceIntf::defaultGateway6("");
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800373 }
374 }
375 else
376 {
377 static_assert(!std::is_same_v<void, decltype(addr)>);
378 }
379 },
380 addr);
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800381 }
382 else if (auto it = undiscoveredIntfInfo.find(ifidx);
383 it != undiscoveredIntfInfo.end())
384 {
385 std::visit(
386 [&](auto addr) {
387 if constexpr (std::is_same_v<in_addr, decltype(addr)>)
388 {
389 if (it->second.defgw4 == addr)
390 {
391 it->second.defgw4.reset();
392 }
393 }
394 else if constexpr (std::is_same_v<in6_addr, decltype(addr)>)
395 {
396 if (it->second.defgw6 == addr)
397 {
398 it->second.defgw6.reset();
399 }
400 }
401 else
402 {
403 static_assert(!std::is_same_v<void, decltype(addr)>);
404 }
405 },
406 addr);
407 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800408}
409
Ratan Gupta29b0e432017-05-25 12:51:40 +0530410void Manager::createInterfaces()
411{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500412 // clear all the interfaces first
Ratan Guptaef85eb92017-06-15 08:57:54 +0530413 interfaces.clear();
William A. Kennington III67b09da2022-10-31 14:09:53 -0700414 interfacesByIdx.clear();
William A. Kennington III80d29012022-11-12 02:31:40 -0800415 for (auto& info : system::getInterfaces())
Ratan Gupta6811f822017-04-14 16:34:56 +0530416 {
William A. Kennington III0813a242022-11-12 18:07:11 -0800417 addInterface(info);
Ratan Gupta6811f822017-04-14 16:34:56 +0530418 }
419}
420
Ratan Guptaef85eb92017-06-15 08:57:54 +0530421void Manager::createChildObjects()
422{
William A. Kennington IIIe0564842021-10-23 16:02:22 -0700423 routeTable.refresh();
424
Ratan Guptaef85eb92017-06-15 08:57:54 +0530425 // creates the ethernet interface dbus object.
426 createInterfaces();
Ratan Guptae05083a2017-09-16 07:12:11 +0530427
428 systemConf.reset(nullptr);
429 dhcpConf.reset(nullptr);
430
Ratan Guptaef85eb92017-06-15 08:57:54 +0530431 fs::path objPath = objectPath;
432 objPath /= "config";
Ratan Guptae05083a2017-09-16 07:12:11 +0530433
434 // create the system conf object.
Ratan Guptaef85eb92017-06-15 08:57:54 +0530435 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
Jiaqing Zhao24b5a612022-04-11 16:46:16 +0800436 bus, objPath.string());
Ratan Guptad16f88c2017-07-11 17:47:57 +0530437 // create the dhcp conf object.
438 objPath /= "dhcp";
439 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
Gunnar Mills57d9c502018-09-14 14:42:34 -0500440 bus, objPath.string(), *this);
Ratan Guptaef85eb92017-06-15 08:57:54 +0530441}
442
William A. Kennington III085bbdc2022-10-05 02:45:37 -0700443ObjectPath Manager::vlan(std::string interfaceName, uint32_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +0530444{
Jiaqing Zhaob685cb62022-04-12 22:57:34 +0800445 if (id == 0 || id >= 4095)
446 {
447 log<level::ERR>("VLAN ID is not valid", entry("VLANID=%u", id));
448 elog<InvalidArgument>(
449 Argument::ARGUMENT_NAME("VLANId"),
450 Argument::ARGUMENT_VALUE(std::to_string(id).c_str()));
451 }
452
William A. Kennington III96444792022-10-05 15:16:22 -0700453 auto it = interfaces.find(interfaceName);
454 if (it == interfaces.end())
455 {
456 using ResourceErr =
457 phosphor::logging::xyz::openbmc_project::Common::ResourceNotFound;
458 elog<ResourceNotFound>(ResourceErr::RESOURCE(interfaceName.c_str()));
459 }
460 return it->second->createVLAN(id);
Ratan Gupta6811f822017-04-14 16:34:56 +0530461}
462
Michael Tritz29f2fd62017-05-22 15:27:26 -0500463void Manager::reset()
464{
William A. Kennington III9a1d9af2021-11-09 17:51:05 -0800465 if (fs::is_directory(confDir))
Michael Tritz29f2fd62017-05-22 15:27:26 -0500466 {
William A. Kennington III9a1d9af2021-11-09 17:51:05 -0800467 for (const auto& file : fs::directory_iterator(confDir))
468 {
469 fs::remove(file.path());
470 }
Michael Tritz29f2fd62017-05-22 15:27:26 -0500471 }
William A. Kennington III9a1d9af2021-11-09 17:51:05 -0800472 log<level::INFO>("Network Factory Reset queued.");
Michael Tritz29f2fd62017-05-22 15:27:26 -0500473}
474
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530475// Need to merge the below function with the code which writes the
476// config file during factory reset.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500477// TODO openbmc/openbmc#1751
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530478void Manager::writeToConfigurationFile()
479{
480 // write all the static ip address in the systemd-network conf file
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530481 for (const auto& intf : interfaces)
482 {
Ratan Gupta2b106532017-07-25 16:05:02 +0530483 intf.second->writeConfigurationFile();
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530484 }
Ratan Guptae05083a2017-09-16 07:12:11 +0530485}
486
William A. Kennington III6f39c5e2021-05-13 18:39:23 -0700487#ifdef SYNC_MAC_FROM_INVENTORY
Manojkiran Edacc099a82020-05-11 14:25:16 +0530488void Manager::setFistBootMACOnInterface(
489 const std::pair<std::string, std::string>& inventoryEthPair)
490{
491 for (const auto& interface : interfaces)
492 {
493 if (interface.first == inventoryEthPair.first)
494 {
495 auto returnMAC =
Patrick Williams6aef7692021-05-01 06:39:41 -0500496 interface.second->macAddress(inventoryEthPair.second);
Manojkiran Edacc099a82020-05-11 14:25:16 +0530497 if (returnMAC == inventoryEthPair.second)
498 {
499 log<level::INFO>("Set the MAC on "),
500 entry("interface : ", interface.first.c_str()),
501 entry("MAC : ", inventoryEthPair.second.c_str());
502 std::error_code ec;
503 if (std::filesystem::is_directory("/var/lib/network", ec))
504 {
505 std::ofstream persistentFile(FirstBootFile +
506 interface.first);
507 }
508 break;
509 }
510 else
511 {
512 log<level::INFO>("MAC is Not Set on ethernet Interface");
513 }
514 }
515 }
516}
517
518#endif
519
William A. Kennington III85dc57a2022-11-07 16:53:24 -0800520void Manager::reloadConfigsNoRefresh()
William A. Kennington III56ecc782021-10-07 18:44:50 -0700521{
William A. Kennington IIIc7cf25f2021-11-09 16:16:59 -0800522 reloadTimer->restartOnce(reloadTimeout);
William A. Kennington III85dc57a2022-11-07 16:53:24 -0800523}
524
525void Manager::reloadConfigs()
526{
527 reloadConfigsNoRefresh();
William A. Kennington IIId41db382021-11-09 20:42:29 -0800528 // Ensure that the next refresh happens after reconfiguration
529 refreshObjectTimer->setRemaining(reloadTimeout + refreshTimeout);
William A. Kennington IIIc7cf25f2021-11-09 16:16:59 -0800530}
531
532void Manager::doReloadConfigs()
533{
William A. Kennington III6ff633a2021-11-09 17:09:12 -0800534 for (auto& hook : reloadPreHooks)
535 {
536 try
537 {
538 hook();
539 }
540 catch (const std::exception& ex)
541 {
542 log<level::ERR>("Failed executing reload hook, ignoring",
543 entry("ERR=%s", ex.what()));
544 }
545 }
546 reloadPreHooks.clear();
William A. Kennington III56ecc782021-10-07 18:44:50 -0700547 try
548 {
549 auto method = bus.new_method_call(NETWORKD_BUSNAME, NETWORKD_PATH,
550 NETWORKD_INTERFACE, "Reload");
551 bus.call_noreply(method);
552 }
Patrick Williamsc38b0712022-07-22 19:26:54 -0500553 catch (const sdbusplus::exception_t& ex)
William A. Kennington III56ecc782021-10-07 18:44:50 -0700554 {
555 log<level::ERR>("Failed to reload configuration",
556 entry("ERR=%s", ex.what()));
557 elog<InternalFailure>();
558 }
William A. Kennington IIId41db382021-11-09 20:42:29 -0800559 // Ensure reconfiguration has enough time
William A. Kennington III85dc57a2022-11-07 16:53:24 -0800560 if (refreshObjectTimer->isEnabled())
561 {
562 refreshObjectTimer->setRemaining(refreshTimeout);
563 }
William A. Kennington III56ecc782021-10-07 18:44:50 -0700564}
565
William A. Kennington III80d29012022-11-12 02:31:40 -0800566void Manager::handleAdminState(std::string_view state, unsigned ifidx)
567{
568 if (state == "initialized" || state == "linger")
569 {
570 systemdNetworkdEnabled.erase(ifidx);
571 }
572 else
573 {
574 bool managed = state != "unmanaged";
575 systemdNetworkdEnabled.insert_or_assign(ifidx, managed);
576 if (auto it = undiscoveredIntfInfo.find(ifidx);
577 it != undiscoveredIntfInfo.end())
578 {
579 auto info = std::move(it->second);
580 undiscoveredIntfInfo.erase(it);
William A. Kennington III0813a242022-11-12 18:07:11 -0800581 createInterface(info, managed);
William A. Kennington III80d29012022-11-12 02:31:40 -0800582 }
583 else if (auto it = interfacesByIdx.find(ifidx);
584 it != interfacesByIdx.end())
585 {
586 it->second->EthernetInterfaceIntf::nicEnabled(managed);
587 }
588 }
589}
590
Gunnar Mills57d9c502018-09-14 14:42:34 -0500591} // namespace network
592} // namespace phosphor