blob: b14c1069b7f668624c1adf56dc29987ca7febb89 [file] [log] [blame]
Ratan Gupta6811f822017-04-14 16:34:56 +05301#include "network_manager.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07002
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07003#include "config_parser.hpp"
Ratan Gupta5978dd12017-07-25 13:47:13 +05304#include "ipaddress.hpp"
William A. Kennington III2e09d272022-10-14 17:15:00 -07005#include "system_queries.hpp"
William A. Kennington III3a70fa22018-09-20 18:48:20 -07006#include "types.hpp"
William A. Kennington IIIb8006122022-11-13 18:15:15 -08007#include "util.hpp"
8
William A. Kennington III57ca9612022-11-14 15:26:47 -08009#include <linux/if_addr.h>
William A. Kennington III7310ac72022-11-14 15:44:00 -080010#include <linux/neighbour.h>
William A. Kennington IIIb8006122022-11-13 18:15:15 -080011#include <net/if.h>
William A. Kennington III9c441fd2023-02-24 13:40:01 -080012#include <net/if_arp.h>
Ratan Gupta738a67f2017-04-21 10:38:05 +053013
Patrick Venture189d44e2018-07-09 12:30:59 -070014#include <phosphor-logging/elog-errors.hpp>
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070015#include <phosphor-logging/lg2.hpp>
William A. Kennington III80d29012022-11-12 02:31:40 -080016#include <sdbusplus/message.hpp>
William A. Kennington III9b2a20d2023-06-17 14:05:48 -070017#include <stdplus/numeric/str.hpp>
William A. Kennington III9ede1b72022-11-21 01:59:28 -080018#include <stdplus/pinned.hpp>
William A. Kennington IIIb7401962023-07-21 16:36:11 -070019#include <stdplus/print.hpp>
Patrick Venture189d44e2018-07-09 12:30:59 -070020#include <xyz/openbmc_project/Common/error.hpp>
Ratan Gupta6811f822017-04-14 16:34:56 +053021
Patrick Williams89d734b2023-05-10 07:50:25 -050022#include <filesystem>
23
Ratan Gupta6811f822017-04-14 16:34:56 +053024namespace phosphor
25{
26namespace network
27{
Ratan Gupta82549cc2017-04-21 08:45:23 +053028
Ratan Gupta6811f822017-04-14 16:34:56 +053029using namespace phosphor::logging;
Ratan Guptaef85eb92017-06-15 08:57:54 +053030using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Jiaqing Zhaob685cb62022-04-12 22:57:34 +080031using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Gupta6811f822017-04-14 16:34:56 +053032
William A. Kennington III80d29012022-11-12 02:31:40 -080033static constexpr const char enabledMatch[] =
34 "type='signal',sender='org.freedesktop.network1',path_namespace='/org/"
35 "freedesktop/network1/"
36 "link',interface='org.freedesktop.DBus.Properties',member='"
37 "PropertiesChanged',arg0='org.freedesktop.network1.Link',";
38
William A. Kennington III9ede1b72022-11-21 01:59:28 -080039Manager::Manager(stdplus::PinnedRef<sdbusplus::bus_t> bus,
William A. Kennington IIId40046b2023-06-30 20:36:11 -070040 stdplus::PinnedRef<DelayedExecutor> reload,
41 stdplus::zstring_view objPath,
William A. Kennington III5b179382022-11-15 15:23:26 -080042 const std::filesystem::path& confDir) :
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -080043 ManagerIface(bus, objPath.c_str(), ManagerIface::action::defer_emit),
44 reload(reload), bus(bus), objPath(std::string(objPath)), confDir(confDir),
William A. Kennington III80d29012022-11-12 02:31:40 -080045 systemdNetworkdEnabledMatch(
William A. Kennington III9ede1b72022-11-21 01:59:28 -080046 bus, enabledMatch,
47 [man = stdplus::PinnedRef(*this)](sdbusplus::message_t& m) {
Patrick Williams89d734b2023-05-10 07:50:25 -050048 std::string intf;
49 std::unordered_map<std::string, std::variant<std::string>> values;
50 try
51 {
52 m.read(intf, values);
53 auto it = values.find("AdministrativeState");
54 if (it == values.end())
55 {
56 return;
57 }
58 const std::string_view obj = m.get_path();
59 auto sep = obj.rfind('/');
60 if (sep == obj.npos || sep + 3 > obj.size())
61 {
62 throw std::invalid_argument("Invalid obj path");
63 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -070064 auto ifidx = stdplus::StrToInt<10, uint16_t>{}(obj.substr(sep + 3));
Patrick Williams89d734b2023-05-10 07:50:25 -050065 const auto& state = std::get<std::string>(it->second);
66 man.get().handleAdminState(state, ifidx);
67 }
68 catch (const std::exception& e)
69 {
70 lg2::error("AdministrativeState match parsing failed: {ERROR}", "ERROR",
71 e);
72 }
William A. Kennington III80d29012022-11-12 02:31:40 -080073 })
Ratan Gupta6811f822017-04-14 16:34:56 +053074{
William A. Kennington IIId40046b2023-06-30 20:36:11 -070075 reload.get().setCallback([&]() {
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -080076 for (auto& hook : reloadPreHooks)
77 {
78 try
79 {
80 hook();
81 }
82 catch (const std::exception& ex)
83 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070084 lg2::error("Failed executing reload hook, ignoring: {ERROR}",
85 "ERROR", ex);
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -080086 }
87 }
88 reloadPreHooks.clear();
89 try
90 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -080091 bus.get()
William A. Kennington IIIaf77f822023-06-23 02:17:20 -070092 .new_method_call("org.freedesktop.network1",
93 "/org/freedesktop/network1",
94 "org.freedesktop.network1.Manager", "Reload")
William A. Kennington III9ede1b72022-11-21 01:59:28 -080095 .call();
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070096 lg2::info("Reloaded systemd-networkd");
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -080097 }
98 catch (const sdbusplus::exception_t& ex)
99 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700100 lg2::error("Failed to reload configuration: {ERROR}", "ERROR", ex);
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -0800101 reloadPostHooks.clear();
102 }
103 for (auto& hook : reloadPostHooks)
104 {
105 try
106 {
107 hook();
108 }
109 catch (const std::exception& ex)
110 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700111 lg2::error("Failed executing reload hook, ignoring: {ERROR}",
112 "ERROR", ex);
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -0800113 }
114 }
115 reloadPostHooks.clear();
116 });
William A. Kennington III80d29012022-11-12 02:31:40 -0800117 std::vector<
118 std::tuple<int32_t, std::string, sdbusplus::message::object_path>>
119 links;
120 try
121 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800122 auto rsp = bus.get()
123 .new_method_call("org.freedesktop.network1",
124 "/org/freedesktop/network1",
125 "org.freedesktop.network1.Manager",
126 "ListLinks")
127 .call();
William A. Kennington III80d29012022-11-12 02:31:40 -0800128 rsp.read(links);
129 }
130 catch (const sdbusplus::exception::SdBusError& e)
131 {
132 // Any failures are systemd-network not being ready
133 }
134 for (const auto& link : links)
135 {
136 unsigned ifidx = std::get<0>(link);
137 auto obj = fmt::format("/org/freedesktop/network1/link/_3{}", ifidx);
138 auto req =
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800139 bus.get().new_method_call("org.freedesktop.network1", obj.c_str(),
140 "org.freedesktop.DBus.Properties", "Get");
William A. Kennington III80d29012022-11-12 02:31:40 -0800141 req.append("org.freedesktop.network1.Link", "AdministrativeState");
142 auto rsp = req.call();
143 std::variant<std::string> val;
144 rsp.read(val);
145 handleAdminState(std::get<std::string>(val), ifidx);
146 }
Ratan Guptaef85eb92017-06-15 08:57:54 +0530147
William A. Kennington III5b179382022-11-15 15:23:26 -0800148 std::filesystem::create_directories(confDir);
149 systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
150 bus, (this->objPath / "config").str);
151 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
152 bus, (this->objPath / "dhcp").str, *this);
Ratan Gupta29b0e432017-05-25 12:51:40 +0530153}
154
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800155void Manager::createInterface(const AllIntfInfo& info, bool enabled)
William A. Kennington III80d29012022-11-12 02:31:40 -0800156{
William A. Kennington III93f5c6d2022-11-17 16:23:44 -0800157 if (ignoredIntf.find(info.intf.idx) != ignoredIntf.end())
158 {
159 return;
160 }
William A. Kennington III5b179382022-11-15 15:23:26 -0800161 if (auto it = interfacesByIdx.find(info.intf.idx);
162 it != interfacesByIdx.end())
163 {
William A. Kennington III5b179382022-11-15 15:23:26 -0800164 if (info.intf.name && *info.intf.name != it->second->interfaceName())
165 {
William A. Kennington IIIbf290462022-11-15 19:44:25 -0800166 interfaces.erase(it->second->interfaceName());
167 interfacesByIdx.erase(it);
William A. Kennington III5b179382022-11-15 15:23:26 -0800168 }
William A. Kennington IIIbf290462022-11-15 19:44:25 -0800169 else
170 {
171 it->second->updateInfo(info.intf);
172 return;
173 }
William A. Kennington III5b179382022-11-15 15:23:26 -0800174 }
William A. Kennington III876927c2022-11-17 16:20:15 -0800175 else if (info.intf.name)
176 {
177 auto it = interfaces.find(*info.intf.name);
178 if (it != interfaces.end())
179 {
180 it->second->updateInfo(info.intf);
181 return;
182 }
183 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800184 if (!info.intf.name)
185 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700186 lg2::error("Can't create interface without name: {NET_IDX}", "NET_IDX",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700187 info.intf.idx);
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800188 return;
189 }
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800190 config::Parser config(config::pathForIntfConf(confDir, *info.intf.name));
William A. Kennington III80d29012022-11-12 02:31:40 -0800191 auto intf = std::make_unique<EthernetInterface>(
William A. Kennington III13d665c2022-11-15 20:34:40 -0800192 bus, *this, info, objPath.str, config, enabled);
William A. Kennington III80d29012022-11-12 02:31:40 -0800193 intf->loadNameServers(config);
194 intf->loadNTPServers(config);
195 auto ptr = intf.get();
William A. Kennington IIIf30d5602022-11-13 17:09:55 -0800196 interfaces.insert_or_assign(*info.intf.name, std::move(intf));
197 interfacesByIdx.insert_or_assign(info.intf.idx, ptr);
William A. Kennington III80d29012022-11-12 02:31:40 -0800198}
199
William A. Kennington III0813a242022-11-12 18:07:11 -0800200void Manager::addInterface(const InterfaceInfo& info)
201{
William A. Kennington III9c441fd2023-02-24 13:40:01 -0800202 if (info.type != ARPHRD_ETHER)
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800203 {
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800204 ignoredIntf.emplace(info.idx);
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800205 return;
206 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800207 if (info.name)
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800208 {
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800209 const auto& ignored = internal::getIgnoredInterfaces();
210 if (ignored.find(*info.name) != ignored.end())
211 {
212 static std::unordered_set<std::string> ignored;
213 if (!ignored.contains(*info.name))
214 {
215 ignored.emplace(*info.name);
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700216 lg2::info("Ignoring interface {NET_INTF}", "NET_INTF",
217 *info.name);
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800218 }
219 ignoredIntf.emplace(info.idx);
220 return;
221 }
William A. Kennington IIIb8006122022-11-13 18:15:15 -0800222 }
223
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800224 auto infoIt = intfInfo.find(info.idx);
225 if (infoIt != intfInfo.end())
William A. Kennington III0813a242022-11-12 18:07:11 -0800226 {
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800227 infoIt->second.intf = info;
William A. Kennington III0813a242022-11-12 18:07:11 -0800228 }
229 else
230 {
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800231 infoIt = std::get<0>(intfInfo.emplace(info.idx, AllIntfInfo{info}));
232 }
233
234 if (auto it = systemdNetworkdEnabled.find(info.idx);
235 it != systemdNetworkdEnabled.end())
236 {
237 createInterface(infoIt->second, it->second);
William A. Kennington III0813a242022-11-12 18:07:11 -0800238 }
239}
240
241void Manager::removeInterface(const InterfaceInfo& info)
242{
243 auto iit = interfacesByIdx.find(info.idx);
244 auto nit = interfaces.end();
245 if (info.name)
246 {
247 nit = interfaces.find(*info.name);
248 if (nit != interfaces.end() && iit != interfacesByIdx.end() &&
249 nit->second.get() != iit->second)
250 {
William A. Kennington IIIb7401962023-07-21 16:36:11 -0700251 stdplus::print(stderr, "Removed interface desync detected\n");
William A. Kennington III0813a242022-11-12 18:07:11 -0800252 fflush(stderr);
253 std::abort();
254 }
255 }
256 else if (iit != interfacesByIdx.end())
257 {
258 for (nit = interfaces.begin(); nit != interfaces.end(); ++nit)
259 {
260 if (nit->second.get() == iit->second)
261 {
262 break;
263 }
264 }
265 }
266
267 if (iit != interfacesByIdx.end())
268 {
269 interfacesByIdx.erase(iit);
270 }
271 else
272 {
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800273 ignoredIntf.erase(info.idx);
William A. Kennington III0813a242022-11-12 18:07:11 -0800274 }
275 if (nit != interfaces.end())
276 {
277 interfaces.erase(nit);
278 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800279 intfInfo.erase(info.idx);
William A. Kennington III0813a242022-11-12 18:07:11 -0800280}
281
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800282void Manager::addAddress(const AddressInfo& info)
283{
William A. Kennington III57ca9612022-11-14 15:26:47 -0800284 if (info.flags & IFA_F_DEPRECATED)
285 {
286 return;
287 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800288 if (auto it = intfInfo.find(info.ifidx); it != intfInfo.end())
William A. Kennington III57ca9612022-11-14 15:26:47 -0800289 {
290 it->second.addrs.insert_or_assign(info.ifaddr, info);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800291 if (auto it = interfacesByIdx.find(info.ifidx);
292 it != interfacesByIdx.end())
293 {
294 it->second->addAddr(info);
295 }
William A. Kennington III57ca9612022-11-14 15:26:47 -0800296 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800297 else if (!ignoredIntf.contains(info.ifidx))
William A. Kennington III57ca9612022-11-14 15:26:47 -0800298 {
299 throw std::runtime_error(
300 fmt::format("Interface `{}` not found for addr", info.ifidx));
301 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800302}
303
304void Manager::removeAddress(const AddressInfo& info)
305{
William A. Kennington III57ca9612022-11-14 15:26:47 -0800306 if (auto it = interfacesByIdx.find(info.ifidx); it != interfacesByIdx.end())
307 {
308 it->second->addrs.erase(info.ifaddr);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800309 if (auto it = intfInfo.find(info.ifidx); it != intfInfo.end())
310 {
311 it->second.addrs.erase(info.ifaddr);
312 }
William A. Kennington III57ca9612022-11-14 15:26:47 -0800313 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800314}
315
316void Manager::addNeighbor(const NeighborInfo& info)
317{
William A. Kennington III7310ac72022-11-14 15:44:00 -0800318 if (!(info.state & NUD_PERMANENT) || !info.addr)
319 {
320 return;
321 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800322 if (auto it = intfInfo.find(info.ifidx); it != intfInfo.end())
William A. Kennington III7310ac72022-11-14 15:44:00 -0800323 {
324 it->second.staticNeighs.insert_or_assign(*info.addr, info);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800325 if (auto it = interfacesByIdx.find(info.ifidx);
326 it != interfacesByIdx.end())
327 {
328 it->second->addStaticNeigh(info);
329 }
William A. Kennington III7310ac72022-11-14 15:44:00 -0800330 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800331 else if (!ignoredIntf.contains(info.ifidx))
William A. Kennington III7310ac72022-11-14 15:44:00 -0800332 {
333 throw std::runtime_error(
334 fmt::format("Interface `{}` not found for neigh", info.ifidx));
335 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800336}
337
338void Manager::removeNeighbor(const NeighborInfo& info)
339{
William A. Kennington III7310ac72022-11-14 15:44:00 -0800340 if (!info.addr)
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800341 {
William A. Kennington III7310ac72022-11-14 15:44:00 -0800342 return;
343 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800344 if (auto it = intfInfo.find(info.ifidx); it != intfInfo.end())
William A. Kennington III7310ac72022-11-14 15:44:00 -0800345 {
346 it->second.staticNeighs.erase(*info.addr);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800347 if (auto it = interfacesByIdx.find(info.ifidx);
348 it != interfacesByIdx.end())
349 {
350 it->second->staticNeighbors.erase(*info.addr);
351 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800352 }
353}
354
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700355void Manager::addDefGw(unsigned ifidx, stdplus::InAnyAddr addr)
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800356{
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800357 if (auto it = intfInfo.find(ifidx); it != intfInfo.end())
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800358 {
359 std::visit(
360 [&](auto addr) {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700361 if constexpr (std::is_same_v<stdplus::In4Addr, decltype(addr)>)
Patrick Williams89d734b2023-05-10 07:50:25 -0500362 {
363 it->second.defgw4.emplace(addr);
364 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500365 else
366 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700367 static_assert(std::is_same_v<stdplus::In6Addr, decltype(addr)>);
368 it->second.defgw6.emplace(addr);
Patrick Williams89d734b2023-05-10 07:50:25 -0500369 }
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800370 },
371 addr);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800372 if (auto it = interfacesByIdx.find(ifidx); it != interfacesByIdx.end())
373 {
374 std::visit(
375 [&](auto addr) {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700376 if constexpr (std::is_same_v<stdplus::In4Addr, decltype(addr)>)
Patrick Williams89d734b2023-05-10 07:50:25 -0500377 {
378 it->second->EthernetInterfaceIntf::defaultGateway(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700379 stdplus::toStr(addr));
Patrick Williams89d734b2023-05-10 07:50:25 -0500380 }
381 else
382 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700383 static_assert(
384 std::is_same_v<stdplus::In6Addr, decltype(addr)>);
385 it->second->EthernetInterfaceIntf::defaultGateway6(
386 stdplus::toStr(addr));
Patrick Williams89d734b2023-05-10 07:50:25 -0500387 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800388 },
389 addr);
390 }
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800391 }
William A. Kennington III3ee5b7e2022-11-15 15:04:37 -0800392 else if (!ignoredIntf.contains(ifidx))
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800393 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700394 lg2::error("Interface {NET_IDX} not found for gw", "NET_IDX", ifidx);
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800395 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800396}
397
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700398void Manager::removeDefGw(unsigned ifidx, stdplus::InAnyAddr addr)
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800399{
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800400 if (auto it = intfInfo.find(ifidx); it != intfInfo.end())
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800401 {
402 std::visit(
403 [&](auto addr) {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700404 if constexpr (std::is_same_v<stdplus::In4Addr, decltype(addr)>)
Patrick Williams89d734b2023-05-10 07:50:25 -0500405 {
406 if (it->second.defgw4 == addr)
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800407 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500408 it->second.defgw4.reset();
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800409 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500410 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700411 else
Patrick Williams89d734b2023-05-10 07:50:25 -0500412 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700413 static_assert(std::is_same_v<stdplus::In6Addr, decltype(addr)>);
Patrick Williams89d734b2023-05-10 07:50:25 -0500414 if (it->second.defgw6 == addr)
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800415 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500416 it->second.defgw6.reset();
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800417 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500418 }
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800419 },
420 addr);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800421 if (auto it = interfacesByIdx.find(ifidx); it != interfacesByIdx.end())
422 {
423 std::visit(
424 [&](auto addr) {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700425 if constexpr (std::is_same_v<stdplus::In4Addr, decltype(addr)>)
Patrick Williams89d734b2023-05-10 07:50:25 -0500426 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700427 stdplus::ToStrHandle<stdplus::ToStr<stdplus::In4Addr>> tsh;
428 if (it->second->defaultGateway() == tsh(addr))
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800429 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500430 it->second->EthernetInterfaceIntf::defaultGateway("");
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800431 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500432 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700433 else
Patrick Williams89d734b2023-05-10 07:50:25 -0500434 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700435 static_assert(
436 std::is_same_v<stdplus::In6Addr, decltype(addr)>);
437 stdplus::ToStrHandle<stdplus::ToStr<stdplus::In6Addr>> tsh;
438 if (it->second->defaultGateway6() == tsh(addr))
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800439 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500440 it->second->EthernetInterfaceIntf::defaultGateway6("");
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800441 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500442 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800443 },
444 addr);
445 }
William A. Kennington IIIbb9e9092022-11-14 15:58:02 -0800446 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -0800447}
448
William A. Kennington III085bbdc2022-10-05 02:45:37 -0700449ObjectPath Manager::vlan(std::string interfaceName, uint32_t id)
Ratan Gupta6811f822017-04-14 16:34:56 +0530450{
Jiaqing Zhaob685cb62022-04-12 22:57:34 +0800451 if (id == 0 || id >= 4095)
452 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700453 lg2::error("VLAN ID {NET_VLAN} is not valid", "NET_VLAN", id);
Jiaqing Zhaob685cb62022-04-12 22:57:34 +0800454 elog<InvalidArgument>(
455 Argument::ARGUMENT_NAME("VLANId"),
456 Argument::ARGUMENT_VALUE(std::to_string(id).c_str()));
457 }
458
William A. Kennington III96444792022-10-05 15:16:22 -0700459 auto it = interfaces.find(interfaceName);
460 if (it == interfaces.end())
461 {
462 using ResourceErr =
463 phosphor::logging::xyz::openbmc_project::Common::ResourceNotFound;
464 elog<ResourceNotFound>(ResourceErr::RESOURCE(interfaceName.c_str()));
465 }
466 return it->second->createVLAN(id);
Ratan Gupta6811f822017-04-14 16:34:56 +0530467}
468
Michael Tritz29f2fd62017-05-22 15:27:26 -0500469void Manager::reset()
470{
William A. Kennington III5b179382022-11-15 15:23:26 -0800471 for (const auto& dirent : std::filesystem::directory_iterator(confDir))
Michael Tritz29f2fd62017-05-22 15:27:26 -0500472 {
William A. Kennington III5b179382022-11-15 15:23:26 -0800473 std::error_code ec;
474 std::filesystem::remove(dirent.path(), ec);
Michael Tritz29f2fd62017-05-22 15:27:26 -0500475 }
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700476 lg2::info("Network data purged.");
Michael Tritz29f2fd62017-05-22 15:27:26 -0500477}
478
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530479// Need to merge the below function with the code which writes the
480// config file during factory reset.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500481// TODO openbmc/openbmc#1751
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530482void Manager::writeToConfigurationFile()
483{
484 // write all the static ip address in the systemd-network conf file
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530485 for (const auto& intf : interfaces)
486 {
Ratan Gupta2b106532017-07-25 16:05:02 +0530487 intf.second->writeConfigurationFile();
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530488 }
Ratan Guptae05083a2017-09-16 07:12:11 +0530489}
490
William A. Kennington III80d29012022-11-12 02:31:40 -0800491void Manager::handleAdminState(std::string_view state, unsigned ifidx)
492{
493 if (state == "initialized" || state == "linger")
494 {
495 systemdNetworkdEnabled.erase(ifidx);
496 }
497 else
498 {
499 bool managed = state != "unmanaged";
500 systemdNetworkdEnabled.insert_or_assign(ifidx, managed);
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800501 if (auto it = interfacesByIdx.find(ifidx); it != interfacesByIdx.end())
William A. Kennington III80d29012022-11-12 02:31:40 -0800502 {
503 it->second->EthernetInterfaceIntf::nicEnabled(managed);
504 }
William A. Kennington III2fb0c872022-11-15 19:35:39 -0800505 else if (auto it = intfInfo.find(ifidx); it != intfInfo.end())
506 {
507 createInterface(it->second, managed);
508 }
William A. Kennington III80d29012022-11-12 02:31:40 -0800509 }
510}
511
Gunnar Mills57d9c502018-09-14 14:42:34 -0500512} // namespace network
513} // namespace phosphor