blob: 46967f5d10613ef6cd0860e39c5b2404f11d2e36 [file] [log] [blame]
Patrick Rudolph9caa64d2023-09-04 11:22:31 +02001#include "config.h"
Gunnar Mills57d9c502018-09-14 14:42:34 -05002
Patrick Venture189d44e2018-07-09 12:30:59 -07003#include "ethernet_interface.hpp"
4
Ratan Gupta497c0c92017-08-22 19:15:59 +05305#include "config_parser.hpp"
Ratan Gupta4f1c18b2017-05-25 12:59:35 +05306#include "network_manager.hpp"
William A. Kennington III2e09d272022-10-14 17:15:00 -07007#include "system_queries.hpp"
William A. Kennington III95530ec2022-08-19 01:44:39 -07008#include "util.hpp"
Ratan Gupta91a99cc2017-04-14 16:32:09 +05309
Ravi Tejaab27a812023-05-02 10:01:53 -050010#include <arpa/inet.h>
11#include <fcntl.h>
William A. Kennington IIId7946a72019-04-19 14:24:09 -070012#include <linux/rtnetlink.h>
William A. Kennington IIIfd862be2022-10-09 18:40:55 -070013#include <net/if.h>
William A. Kennington III9c441fd2023-02-24 13:40:01 -080014#include <net/if_arp.h>
Yuxiao Zhang46938072023-09-26 17:59:14 -070015#include <sys/stat.h>
Ratan Gupta91a99cc2017-04-14 16:32:09 +053016
Patrick Venture189d44e2018-07-09 12:30:59 -070017#include <phosphor-logging/elog-errors.hpp>
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -070018#include <phosphor-logging/lg2.hpp>
William A. Kennington III945878a2024-04-17 01:05:27 -070019#include <stdplus/fd/create.hpp>
William A. Kennington III12beaad2020-06-13 19:30:41 -070020#include <stdplus/raw.hpp>
William A. Kennington III86642522023-07-24 17:55:55 -070021#include <stdplus/str/cat.hpp>
William A. Kennington III69f45542022-09-24 23:28:14 -070022#include <stdplus/zstring.hpp>
Patrick Williams89d734b2023-05-10 07:50:25 -050023#include <xyz/openbmc_project/Common/error.hpp>
24
25#include <algorithm>
26#include <filesystem>
William A. Kennington IIIcafc1512023-07-25 02:22:32 -070027#include <format>
Ratan Gupta2b106532017-07-25 16:05:02 +053028#include <string>
William A. Kennington III26275a32021-07-13 20:32:42 -070029#include <unordered_map>
30#include <variant>
Ratan Gupta82549cc2017-04-21 08:45:23 +053031
Ratan Gupta91a99cc2017-04-14 16:32:09 +053032namespace phosphor
33{
34namespace network
35{
36
37using namespace phosphor::logging;
Ratan Gupta2b106532017-07-25 16:05:02 +053038using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053039using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
40using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050041using Argument = xyz::openbmc_project::Common::InvalidArgument;
William A. Kennington III991a8e82022-10-11 15:02:47 -070042using std::literals::string_view_literals::operator""sv;
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053043constexpr auto RESOLVED_SERVICE = "org.freedesktop.resolve1";
44constexpr auto RESOLVED_INTERFACE = "org.freedesktop.resolve1.Link";
45constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
46constexpr auto RESOLVED_SERVICE_PATH = "/org/freedesktop/resolve1/link/";
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -060047
48constexpr auto TIMESYNCD_SERVICE = "org.freedesktop.timesync1";
49constexpr auto TIMESYNCD_INTERFACE = "org.freedesktop.timesync1.Manager";
50constexpr auto TIMESYNCD_SERVICE_PATH = "/org/freedesktop/timesync1";
51
Manojkiran Edaacd6dd52019-10-15 15:00:51 +053052constexpr auto METHOD_GET = "Get";
Ratan Gupta2b106532017-07-25 16:05:02 +053053
William A. Kennington III2e09d272022-10-14 17:15:00 -070054template <typename Func>
55inline decltype(std::declval<Func>()())
56 ignoreError(std::string_view msg, stdplus::zstring_view intf,
57 decltype(std::declval<Func>()()) fallback, Func&& func) noexcept
William A. Kennington III5dad2aa2022-01-21 16:00:17 -080058{
William A. Kennington III4ee7a7e2022-10-11 16:37:22 -070059 try
60 {
William A. Kennington III2e09d272022-10-14 17:15:00 -070061 return func();
William A. Kennington III4ee7a7e2022-10-11 16:37:22 -070062 }
William A. Kennington III2e09d272022-10-14 17:15:00 -070063 catch (const std::exception& e)
William A. Kennington III4ee7a7e2022-10-11 16:37:22 -070064 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -070065 lg2::error("{MSG} failed on {NET_INTF}: {ERROR}", "MSG", msg,
66 "NET_INTF", intf, "ERROR", e);
William A. Kennington III4ee7a7e2022-10-11 16:37:22 -070067 }
William A. Kennington III2e09d272022-10-14 17:15:00 -070068 return fallback;
William A. Kennington III4ee7a7e2022-10-11 16:37:22 -070069}
William A. Kennington IIId298f932022-10-17 14:31:38 -070070
William A. Kennington IIId298f932022-10-17 14:31:38 -070071static std::string makeObjPath(std::string_view root, std::string_view intf)
72{
William A. Kennington III86642522023-07-24 17:55:55 -070073 auto ret = stdplus::strCat(root, "/"sv, intf);
William A. Kennington IIId298f932022-10-17 14:31:38 -070074 std::replace(ret.begin() + ret.size() - intf.size(), ret.end(), '.', '_');
75 return ret;
76}
77
William A. Kennington IIIbbf5e9e2023-02-01 14:58:38 -080078template <typename Addr>
79static bool validIntfIP(Addr a) noexcept
80{
81 return a.isUnicast() && !a.isLoopback();
82}
83
Patrick Williamsad205022024-08-16 15:20:07 -040084EthernetInterface::EthernetInterface(
85 stdplus::PinnedRef<sdbusplus::bus_t> bus,
86 stdplus::PinnedRef<Manager> manager, const AllIntfInfo& info,
87 std::string_view objRoot, const config::Parser& config, bool enabled) :
William A. Kennington III13d665c2022-11-15 20:34:40 -080088 EthernetInterface(bus, manager, info, makeObjPath(objRoot, *info.intf.name),
William A. Kennington IIIb6452542022-11-15 18:09:12 -080089 config, enabled)
Patrick Williams89d734b2023-05-10 07:50:25 -050090{}
William A. Kennington IIId298f932022-10-17 14:31:38 -070091
Patrick Williamsad205022024-08-16 15:20:07 -040092EthernetInterface::EthernetInterface(
93 stdplus::PinnedRef<sdbusplus::bus_t> bus,
94 stdplus::PinnedRef<Manager> manager, const AllIntfInfo& info,
95 std::string&& objPath, const config::Parser& config, bool enabled) :
96 Ifaces(bus, objPath.c_str(), Ifaces::action::defer_emit), manager(manager),
97 bus(bus), objPath(std::move(objPath))
Ratan Gupta91a99cc2017-04-14 16:32:09 +053098{
William A. Kennington IIId99e6db2022-11-15 20:39:45 -080099 interfaceName(*info.intf.name, true);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700100 auto dhcpVal = getDHCPValue(config);
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800101 EthernetInterfaceIntf::dhcp4(dhcpVal.v4, true);
102 EthernetInterfaceIntf::dhcp6(dhcpVal.v6, true);
103 EthernetInterfaceIntf::ipv6AcceptRA(getIPv6AcceptRA(config), true);
104 EthernetInterfaceIntf::nicEnabled(enabled, true);
Ravi Tejaa5a09442020-07-17 00:57:33 -0500105
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700106 EthernetInterfaceIntf::ntpServers(
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800107 config.map.getValueStrings("Network", "NTP"), true);
Ratan Gupta613a0122020-04-24 15:18:53 +0530108
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800109 updateInfo(info.intf, true);
110
111 if (info.defgw4)
112 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700113 EthernetInterface::defaultGateway(stdplus::toStr(*info.defgw4), true);
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800114 }
115 if (info.defgw6)
116 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700117 EthernetInterface::defaultGateway6(stdplus::toStr(*info.defgw6), true);
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800118 }
119 emit_object_added();
William A. Kennington IIId298f932022-10-17 14:31:38 -0700120
William A. Kennington III13d665c2022-11-15 20:34:40 -0800121 if (info.intf.vlan_id)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700122 {
William A. Kennington III13d665c2022-11-15 20:34:40 -0800123 if (!info.intf.parent_idx)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700124 {
125 std::runtime_error("Missing parent link");
126 }
William A. Kennington III13d665c2022-11-15 20:34:40 -0800127 vlan.emplace(bus, this->objPath.c_str(), info.intf, *this);
128 }
William A. Kennington IIIfad525c2024-04-17 00:51:59 -0700129 dhcp4Conf.emplace(bus, this->objPath + "/dhcp4", *this, DHCPType::v4);
130 dhcp6Conf.emplace(bus, this->objPath + "/dhcp6", *this, DHCPType::v6);
William A. Kennington III13d665c2022-11-15 20:34:40 -0800131 for (const auto& [_, addr] : info.addrs)
132 {
133 addAddr(addr);
134 }
135 for (const auto& [_, neigh] : info.staticNeighs)
136 {
137 addStaticNeigh(neigh);
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700138 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500139 for (const auto& [_, staticGateway] : info.staticGateways)
140 {
141 addStaticGateway(staticGateway);
142 }
Ratan Gupta29b0e432017-05-25 12:51:40 +0530143}
144
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800145void EthernetInterface::updateInfo(const InterfaceInfo& info, bool skipSignal)
William A. Kennington IIId298f932022-10-17 14:31:38 -0700146{
William A. Kennington III876927c2022-11-17 16:20:15 -0800147 ifIdx = info.idx;
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800148 EthernetInterfaceIntf::linkUp(info.flags & IFF_RUNNING, skipSignal);
William A. Kennington IIId298f932022-10-17 14:31:38 -0700149 if (info.mac)
150 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700151 MacAddressIntf::macAddress(stdplus::toStr(*info.mac), skipSignal);
William A. Kennington IIId298f932022-10-17 14:31:38 -0700152 }
153 if (info.mtu)
154 {
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800155 EthernetInterfaceIntf::mtu(*info.mtu, skipSignal);
William A. Kennington IIId298f932022-10-17 14:31:38 -0700156 }
William A. Kennington III21539662022-11-15 14:53:11 -0800157 if (ifIdx > 0)
158 {
159 auto ethInfo = ignoreError("GetEthInfo", *info.name, {}, [&] {
160 return system::getEthInfo(*info.name);
161 });
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800162 EthernetInterfaceIntf::autoNeg(ethInfo.autoneg, skipSignal);
163 EthernetInterfaceIntf::speed(ethInfo.speed, skipSignal);
William A. Kennington III21539662022-11-15 14:53:11 -0800164 }
William A. Kennington IIId298f932022-10-17 14:31:38 -0700165}
166
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800167void EthernetInterface::addAddr(const AddressInfo& info)
168{
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800169 IP::AddressOrigin origin = IP::AddressOrigin::Static;
Ravi Teja86c4f442023-07-19 22:26:39 -0500170 if (dhcpIsEnabled(info.ifaddr.getAddr()))
171 {
172 origin = IP::AddressOrigin::DHCP;
173 }
174
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800175#ifdef LINK_LOCAL_AUTOCONFIGURATION
176 if (info.scope == RT_SCOPE_LINK)
177 {
178 origin = IP::AddressOrigin::LinkLocal;
179 }
180#endif
181
Ravi Tejac6201202023-03-28 21:29:58 -0500182 if ((info.scope == RT_SCOPE_UNIVERSE) && (info.flags & IFA_F_PERMANENT))
183 {
184 origin = IP::AddressOrigin::Static;
185 }
186 if ((info.scope == RT_SCOPE_UNIVERSE) &&
187 ((info.flags & IFA_F_NOPREFIXROUTE) &&
188 (info.flags & IFA_F_MANAGETEMPADDR)))
189 {
190 origin = IP::AddressOrigin::SLAAC;
191 }
192 else if ((info.scope == RT_SCOPE_UNIVERSE) &&
193 ((info.flags & IFA_F_NOPREFIXROUTE)))
194 {
195 origin = IP::AddressOrigin::DHCP;
196 }
197
William A. Kennington III77747f62022-11-07 23:11:15 -0800198 auto it = addrs.find(info.ifaddr);
199 if (it == addrs.end())
200 {
201 addrs.emplace(info.ifaddr, std::make_unique<IPAddress>(
202 bus, std::string_view(objPath), *this,
203 info.ifaddr, origin));
204 }
205 else
206 {
207 it->second->IPIfaces::origin(origin);
208 }
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800209}
210
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800211void EthernetInterface::addStaticNeigh(const NeighborInfo& info)
212{
William A. Kennington IIId3615142022-11-12 01:28:33 -0800213 if (!info.mac || !info.addr)
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800214 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700215 lg2::error("Missing neighbor mac on {NET_INTF}", "NET_INTF",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700216 interfaceName());
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800217 return;
218 }
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800219
220 if (auto it = staticNeighbors.find(*info.addr); it != staticNeighbors.end())
221 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700222 it->second->NeighborObj::macAddress(stdplus::toStr(*info.mac));
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800223 }
224 else
225 {
Patrick Williamsad205022024-08-16 15:20:07 -0400226 staticNeighbors.emplace(
227 *info.addr, std::make_unique<Neighbor>(
228 bus, std::string_view(objPath), *this, *info.addr,
229 *info.mac, Neighbor::State::Permanent));
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800230 }
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800231}
232
Ravi Tejaab27a812023-05-02 10:01:53 -0500233void EthernetInterface::addStaticGateway(const StaticGatewayInfo& info)
234{
235 if (!info.gateway)
236 {
237 lg2::error("Missing static gateway on {NET_INTF}", "NET_INTF",
238 interfaceName());
239 return;
240 }
241
242 IP::Protocol protocolType;
243 if (*info.protocol == "IPv4")
244 {
245 protocolType = IP::Protocol::IPv4;
246 }
247 else if (*info.protocol == "IPv6")
248 {
249 protocolType = IP::Protocol::IPv6;
250 }
251
252 if (auto it = staticGateways.find(*info.gateway);
253 it != staticGateways.end())
254 {
255 it->second->StaticGatewayObj::gateway(*info.gateway);
256 }
257 else
258 {
259 staticGateways.emplace(*info.gateway,
260 std::make_unique<StaticGateway>(
261 bus, std::string_view(objPath), *this,
262 *info.gateway, protocolType));
263 }
264}
265
Patrick Williams6aef7692021-05-01 06:39:41 -0500266ObjectPath EthernetInterface::ip(IP::Protocol protType, std::string ipaddress,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700267 uint8_t prefixLength, std::string)
Ratan Gupta82549cc2017-04-21 08:45:23 +0530268{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700269 std::optional<stdplus::InAnyAddr> addr;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700270 try
Ratan Guptafc2c7242017-05-29 08:46:06 +0530271 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700272 switch (protType)
273 {
274 case IP::Protocol::IPv4:
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700275 addr.emplace(stdplus::fromStr<stdplus::In4Addr>(ipaddress));
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700276 break;
277 case IP::Protocol::IPv6:
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700278 addr.emplace(stdplus::fromStr<stdplus::In6Addr>(ipaddress));
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700279 break;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700280 default:
281 throw std::logic_error("Exhausted protocols");
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700282 }
William A. Kennington III30f3ba22023-06-28 15:50:12 -0700283 if (!std::visit([](auto ip) { return validIntfIP(ip); }, *addr))
284 {
285 throw std::invalid_argument("not unicast");
286 }
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500287 }
William A. Kennington III59e5b912022-11-02 02:49:46 -0700288 catch (const std::exception& e)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500289 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700290 lg2::error("Invalid IP {NET_IP}: {ERROR}", "NET_IP", ipaddress, "ERROR",
291 e);
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500292 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"),
293 Argument::ARGUMENT_VALUE(ipaddress.c_str()));
294 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700295 std::optional<stdplus::SubnetAny> ifaddr;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700296 try
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500297 {
William A. Kennington III30f3ba22023-06-28 15:50:12 -0700298 if (prefixLength == 0)
299 {
300 throw std::invalid_argument("default route");
301 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700302 ifaddr.emplace(*addr, prefixLength);
William A. Kennington III59e5b912022-11-02 02:49:46 -0700303 }
304 catch (const std::exception& e)
305 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700306 lg2::error("Invalid prefix length {NET_PFX}: {ERROR}", "NET_PFX",
307 prefixLength, "ERROR", e);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500308 elog<InvalidArgument>(
309 Argument::ARGUMENT_NAME("prefixLength"),
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700310 Argument::ARGUMENT_VALUE(stdplus::toStr(prefixLength).c_str()));
Ratan Guptafc2c7242017-05-29 08:46:06 +0530311 }
312
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700313 auto it = addrs.find(*ifaddr);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800314 if (it == addrs.end())
315 {
316 it = std::get<0>(addrs.emplace(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700317 *ifaddr,
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800318 std::make_unique<IPAddress>(bus, std::string_view(objPath), *this,
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700319 *ifaddr, IP::AddressOrigin::Static)));
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800320 }
321 else
322 {
William A. Kennington IIIadd08712022-11-17 16:31:19 -0800323 if (it->second->origin() == IP::AddressOrigin::Static)
324 {
325 return it->second->getObjPath();
326 }
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800327 it->second->IPIfaces::origin(IP::AddressOrigin::Static);
328 }
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530329
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700330 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800331 manager.get().reloadConfigs();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700332
William A. Kennington III434a9432022-11-04 18:38:46 -0700333 return it->second->getObjPath();
Ratan Gupta82549cc2017-04-21 08:45:23 +0530334}
335
Patrick Williams6aef7692021-05-01 06:39:41 -0500336ObjectPath EthernetInterface::neighbor(std::string ipAddress,
337 std::string macAddress)
William A. Kennington III08505792019-01-30 16:00:04 -0800338{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700339 std::optional<stdplus::InAnyAddr> addr;
William A. Kennington III434a9432022-11-04 18:38:46 -0700340 try
William A. Kennington III08505792019-01-30 16:00:04 -0800341 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700342 addr.emplace(stdplus::fromStr<stdplus::InAnyAddr>(ipAddress));
William A. Kennington III434a9432022-11-04 18:38:46 -0700343 }
344 catch (const std::exception& e)
345 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700346 lg2::error("Not a valid IP address {NET_IP}: {ERROR}", "NET_IP",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700347 ipAddress, "ERROR", e);
Patrick Williams6aef7692021-05-01 06:39:41 -0500348 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipAddress"),
349 Argument::ARGUMENT_VALUE(ipAddress.c_str()));
William A. Kennington III08505792019-01-30 16:00:04 -0800350 }
William A. Kennington III434a9432022-11-04 18:38:46 -0700351
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700352 std::optional<stdplus::EtherAddr> lladdr;
William A. Kennington III434a9432022-11-04 18:38:46 -0700353 try
William A. Kennington III08505792019-01-30 16:00:04 -0800354 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700355 lladdr.emplace(stdplus::fromStr<stdplus::EtherAddr>(macAddress));
William A. Kennington III434a9432022-11-04 18:38:46 -0700356 }
357 catch (const std::exception& e)
358 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700359 lg2::error("Not a valid MAC address {NET_MAC}: {ERROR}", "NET_MAC",
360 macAddress, "ERROR", e);
Patrick Williams6aef7692021-05-01 06:39:41 -0500361 elog<InvalidArgument>(Argument::ARGUMENT_NAME("macAddress"),
362 Argument::ARGUMENT_VALUE(macAddress.c_str()));
William A. Kennington III08505792019-01-30 16:00:04 -0800363 }
364
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700365 auto it = staticNeighbors.find(*addr);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800366 if (it == staticNeighbors.end())
367 {
368 it = std::get<0>(staticNeighbors.emplace(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700369 *addr, std::make_unique<Neighbor>(bus, std::string_view(objPath),
370 *this, *addr, *lladdr,
371 Neighbor::State::Permanent)));
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800372 }
373 else
374 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700375 auto str = stdplus::toStr(*lladdr);
William A. Kennington IIIadd08712022-11-17 16:31:19 -0800376 if (it->second->macAddress() == str)
377 {
378 return it->second->getObjPath();
379 }
380 it->second->NeighborObj::macAddress(str);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800381 }
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700382
383 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800384 manager.get().reloadConfigs();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700385
William A. Kennington III434a9432022-11-04 18:38:46 -0700386 return it->second->getObjPath();
William A. Kennington III08505792019-01-30 16:00:04 -0800387}
388
Ravi Tejaab27a812023-05-02 10:01:53 -0500389ObjectPath EthernetInterface::staticGateway(std::string gateway,
390 IP::Protocol protocolType)
391{
392 std::optional<stdplus::InAnyAddr> addr;
393 std::string route;
394 try
395 {
kokilav0779db72025-01-07 10:21:51 -0600396 switch (protocolType)
397 {
398 case IP::Protocol::IPv4:
399 addr.emplace(stdplus::fromStr<stdplus::In4Addr>(gateway));
400 break;
401 case IP::Protocol::IPv6:
402 addr.emplace(stdplus::fromStr<stdplus::In6Addr>(gateway));
403 break;
404 default:
405 throw std::logic_error("Exhausted protocols");
406 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500407 route = gateway;
408 }
409 catch (const std::exception& e)
410 {
411 lg2::error("Not a valid IP address {GATEWAY}: {ERROR}", "GATEWAY",
412 gateway, "ERROR", e);
413 elog<InvalidArgument>(Argument::ARGUMENT_NAME("gateway"),
414 Argument::ARGUMENT_VALUE(gateway.c_str()));
415 }
416
417 auto it = staticGateways.find(route);
418 if (it == staticGateways.end())
419 {
420 it = std::get<0>(staticGateways.emplace(
421 route,
422 std::make_unique<StaticGateway>(bus, std::string_view(objPath),
423 *this, gateway, protocolType)));
424 }
425 else
426 {
427 it->second->StaticGatewayObj::gateway(gateway);
428 }
429
430 writeConfigurationFile();
431 manager.get().reloadConfigs();
432
433 return it->second->getObjPath();
434}
435
Patrick Williams6aef7692021-05-01 06:39:41 -0500436bool EthernetInterface::ipv6AcceptRA(bool value)
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700437{
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700438 if (ipv6AcceptRA() != EthernetInterfaceIntf::ipv6AcceptRA(value))
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700439 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700440 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800441 manager.get().reloadConfigs();
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700442 }
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700443 return value;
444}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700445
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700446bool EthernetInterface::dhcp4(bool value)
447{
448 if (dhcp4() != EthernetInterfaceIntf::dhcp4(value))
449 {
450 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800451 manager.get().reloadConfigs();
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700452 }
453 return value;
454}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700455
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700456bool EthernetInterface::dhcp6(bool value)
457{
458 if (dhcp6() != EthernetInterfaceIntf::dhcp6(value))
459 {
460 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800461 manager.get().reloadConfigs();
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700462 }
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700463 return value;
464}
465
Patrick Williams6aef7692021-05-01 06:39:41 -0500466EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled(DHCPConf value)
Ratan Gupta87c13982017-06-15 09:27:27 +0530467{
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700468 auto old4 = EthernetInterfaceIntf::dhcp4();
Patrick Williamsad205022024-08-16 15:20:07 -0400469 auto new4 = EthernetInterfaceIntf::dhcp4(
470 value == DHCPConf::v4 || value == DHCPConf::v4v6stateless ||
471 value == DHCPConf::both);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700472 auto old6 = EthernetInterfaceIntf::dhcp6();
Patrick Williamsad205022024-08-16 15:20:07 -0400473 auto new6 = EthernetInterfaceIntf::dhcp6(
474 value == DHCPConf::v6 || value == DHCPConf::both);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700475 auto oldra = EthernetInterfaceIntf::ipv6AcceptRA();
476 auto newra = EthernetInterfaceIntf::ipv6AcceptRA(
477 value == DHCPConf::v6stateless || value == DHCPConf::v4v6stateless ||
478 value == DHCPConf::v6 || value == DHCPConf::both);
479
480 if (old4 != new4 || old6 != new6 || oldra != newra)
Ratan Gupta5978dd12017-07-25 13:47:13 +0530481 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700482 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800483 manager.get().reloadConfigs();
Ratan Gupta5978dd12017-07-25 13:47:13 +0530484 }
Ratan Gupta87c13982017-06-15 09:27:27 +0530485 return value;
486}
487
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700488EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled() const
489{
490 if (dhcp6())
491 {
492 return dhcp4() ? DHCPConf::both : DHCPConf::v6;
493 }
494 else if (dhcp4())
495 {
496 return ipv6AcceptRA() ? DHCPConf::v4v6stateless : DHCPConf::v4;
497 }
498 return ipv6AcceptRA() ? DHCPConf::v6stateless : DHCPConf::none;
499}
500
Tejas Patil2c0fc562021-08-03 19:13:46 +0530501size_t EthernetInterface::mtu(size_t value)
502{
William A. Kennington III2e09d272022-10-14 17:15:00 -0700503 const size_t old = EthernetInterfaceIntf::mtu();
504 if (value == old)
Tejas Patil2c0fc562021-08-03 19:13:46 +0530505 {
506 return value;
507 }
William A. Kennington III2e09d272022-10-14 17:15:00 -0700508 const auto ifname = interfaceName();
William A. Kennington III3e471c52022-10-27 19:46:07 -0700509 return EthernetInterfaceIntf::mtu(ignoreError("SetMTU", ifname, old, [&] {
William A. Kennington III2e09d272022-10-14 17:15:00 -0700510 system::setMTU(ifname, value);
511 return value;
512 }));
Tejas Patil2c0fc562021-08-03 19:13:46 +0530513}
514
Patrick Williams6aef7692021-05-01 06:39:41 -0500515bool EthernetInterface::nicEnabled(bool value)
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700516{
Patrick Williams6aef7692021-05-01 06:39:41 -0500517 if (value == EthernetInterfaceIntf::nicEnabled())
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700518 {
519 return value;
520 }
521
William A. Kennington IIIc922d5e2022-01-21 01:08:31 -0800522 EthernetInterfaceIntf::nicEnabled(value);
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700523 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800524 manager.get().reloadConfigs();
Johnathan Manteyfaa72e52020-01-08 10:38:58 -0800525
526 return value;
527}
528
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530529ServerList EthernetInterface::staticNameServers(ServerList value)
530{
nitinkotania581cb0b2023-03-21 00:28:55 -0500531 std::vector<std::string> dnsUniqueValues;
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700532 for (auto& ip : value)
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530533 {
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700534 try
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530535 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700536 ip = stdplus::toStr(stdplus::fromStr<stdplus::InAnyAddr>(ip));
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700537 }
538 catch (const std::exception& e)
539 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700540 lg2::error("Not a valid IP address {NET_IP}: {ERROR}", "NET_IP", ip,
541 "ERROR", e);
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700542 elog<InvalidArgument>(Argument::ARGUMENT_NAME("StaticNameserver"),
543 Argument::ARGUMENT_VALUE(ip.c_str()));
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530544 }
nitinkotania581cb0b2023-03-21 00:28:55 -0500545 if (std::find(dnsUniqueValues.begin(), dnsUniqueValues.end(), ip) ==
546 dnsUniqueValues.end())
547 {
548 dnsUniqueValues.push_back(ip);
549 }
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530550 }
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700551
nitinkotania581cb0b2023-03-21 00:28:55 -0500552 value =
553 EthernetInterfaceIntf::staticNameServers(std::move(dnsUniqueValues));
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700554
555 writeConfigurationFile();
556 manager.get().reloadConfigs();
557
558 return value;
Ratan Gupta6dec3902017-08-20 15:28:12 +0530559}
560
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600561void EthernetInterface::loadNTPServers(const config::Parser& config)
562{
Jishnu CM4fe86132024-09-15 12:02:56 -0500563 ServerList ntpServerList = getNTPServerFromTimeSyncd();
564 ServerList staticNTPServers = config.map.getValueStrings("Network", "NTP");
565
566 std::unordered_set<std::string> staticNTPServersSet(
567 staticNTPServers.begin(), staticNTPServers.end());
568 ServerList networkSuppliedServers;
569
570 std::copy_if(ntpServerList.begin(), ntpServerList.end(),
571 std::back_inserter(networkSuppliedServers),
572 [&staticNTPServersSet](const std::string& server) {
573 return staticNTPServersSet.find(server) ==
574 staticNTPServersSet.end();
575 });
576
577 EthernetInterfaceIntf::ntpServers(networkSuppliedServers);
578 EthernetInterfaceIntf::staticNTPServers(staticNTPServers);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600579}
580
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700581void EthernetInterface::loadNameServers(const config::Parser& config)
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530582{
583 EthernetInterfaceIntf::nameservers(getNameServerFromResolvd());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700584 EthernetInterfaceIntf::staticNameServers(
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700585 config.map.getValueStrings("Network", "DNS"));
Ratan Gupta6dec3902017-08-20 15:28:12 +0530586}
587
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600588ServerList EthernetInterface::getNTPServerFromTimeSyncd()
589{
590 ServerList servers; // Variable to capture the NTP Server IPs
Patrick Williamsad205022024-08-16 15:20:07 -0400591 auto method =
592 bus.get().new_method_call(TIMESYNCD_SERVICE, TIMESYNCD_SERVICE_PATH,
593 PROPERTY_INTERFACE, METHOD_GET);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600594
595 method.append(TIMESYNCD_INTERFACE, "LinkNTPServers");
596
597 try
598 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800599 auto reply = bus.get().call(method);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600600 std::variant<ServerList> response;
601 reply.read(response);
602 servers = std::get<ServerList>(response);
603 }
604 catch (const sdbusplus::exception::SdBusError& e)
605 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700606 lg2::error("Failed to get NTP server information from "
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700607 "systemd-timesyncd: {ERROR}",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700608 "ERROR", e);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600609 }
610
611 return servers;
612}
613
Ravi Teja4f8b9a02023-09-06 13:41:52 -0500614ServerList EthernetInterface::nameservers() const
615{
616 return getNameServerFromResolvd();
617}
618
619ServerList EthernetInterface::getNameServerFromResolvd() const
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530620{
621 ServerList servers;
William A. Kennington IIIcafc1512023-07-25 02:22:32 -0700622 auto OBJ_PATH = std::format("{}{}", RESOLVED_SERVICE_PATH, ifIdx);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530623
624 /*
625 The DNS property under org.freedesktop.resolve1.Link interface contains
626 an array containing all DNS servers currently used by resolved. It
627 contains similar information as the DNS server data written to
628 /run/systemd/resolve/resolv.conf.
629
630 Each structure in the array consists of a numeric network interface index,
631 an address family, and a byte array containing the DNS server address
632 (either 4 bytes in length for IPv4 or 16 bytes in lengths for IPv6).
633 The array contains DNS servers configured system-wide, including those
634 possibly read from a foreign /etc/resolv.conf or the DNS= setting in
635 /etc/systemd/resolved.conf, as well as per-interface DNS server
636 information either retrieved from systemd-networkd or configured by
637 external software via SetLinkDNS().
638 */
639
640 using type = std::vector<std::tuple<int32_t, std::vector<uint8_t>>>;
641 std::variant<type> name; // Variable to capture the DNS property
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800642 auto method = bus.get().new_method_call(RESOLVED_SERVICE, OBJ_PATH.c_str(),
643 PROPERTY_INTERFACE, METHOD_GET);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530644
645 method.append(RESOLVED_INTERFACE, "DNS");
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530646
647 try
648 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800649 auto reply = bus.get().call(method);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530650 reply.read(name);
651 }
Patrick Williamsc38b0712022-07-22 19:26:54 -0500652 catch (const sdbusplus::exception_t& e)
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530653 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700654 lg2::error(
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700655 "Failed to get DNS information from systemd-resolved: {ERROR}",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700656 "ERROR", e);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530657 }
658 auto tupleVector = std::get_if<type>(&name);
659 for (auto i = tupleVector->begin(); i != tupleVector->end(); ++i)
660 {
Alexander Filippov983da552021-02-08 15:26:54 +0300661 int addressFamily = std::get<0>(*i);
662 std::vector<uint8_t>& ipaddress = std::get<1>(*i);
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700663 servers.push_back(stdplus::toStr(
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700664 addrFromBuf(addressFamily, stdplus::raw::asView<char>(ipaddress))));
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530665 }
666 return servers;
667}
668
William A. Kennington IIId298f932022-10-17 14:31:38 -0700669ObjectPath EthernetInterface::createVLAN(uint16_t id)
Ratan Gupta5978dd12017-07-25 13:47:13 +0530670{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700671 auto idStr = stdplus::toStr(id);
William A. Kennington III86642522023-07-24 17:55:55 -0700672 auto intfName = stdplus::strCat(interfaceName(), "."sv, idStr);
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800673 if (manager.get().interfaces.find(intfName) !=
674 manager.get().interfaces.end())
Jiaqing Zhao33b4eaa2022-04-12 23:11:40 +0800675 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700676 lg2::error("VLAN {NET_VLAN} already exists", "NET_VLAN", id);
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700677 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VLANId"),
678 Argument::ARGUMENT_VALUE(idStr.c_str()));
Jiaqing Zhao33b4eaa2022-04-12 23:11:40 +0800679 }
680
William A. Kennington IIId298f932022-10-17 14:31:38 -0700681 auto objRoot = std::string_view(objPath).substr(0, objPath.rfind('/'));
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700682 auto macStr = MacAddressIntf::macAddress();
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700683 std::optional<stdplus::EtherAddr> mac;
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700684 if (!macStr.empty())
685 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700686 mac.emplace(stdplus::fromStr<stdplus::EtherAddr>(macStr));
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700687 }
William A. Kennington III13d665c2022-11-15 20:34:40 -0800688 auto info = AllIntfInfo{InterfaceInfo{
William A. Kennington III9c441fd2023-02-24 13:40:01 -0800689 .type = ARPHRD_ETHER,
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700690 .idx = 0, // TODO: Query the correct value after creation
691 .flags = 0,
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700692 .name = intfName,
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700693 .mac = std::move(mac),
694 .mtu = mtu(),
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700695 .parent_idx = ifIdx,
696 .vlan_id = id,
William A. Kennington III13d665c2022-11-15 20:34:40 -0800697 }};
Ratan Gupta5978dd12017-07-25 13:47:13 +0530698
Patrick Williams6aef7692021-05-01 06:39:41 -0500699 // Pass the parents nicEnabled property, so that the child
Manojkiran Edaca8b91b2020-05-28 09:28:42 +0530700 // VLAN interface can inherit.
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700701 auto vlanIntf = std::make_unique<EthernetInterface>(
William A. Kennington IIIb6452542022-11-15 18:09:12 -0800702 bus, manager, info, objRoot, config::Parser(), nicEnabled());
William A. Kennington IIId298f932022-10-17 14:31:38 -0700703 ObjectPath ret = vlanIntf->objPath;
Ratan Gupta5978dd12017-07-25 13:47:13 +0530704
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800705 manager.get().interfaces.emplace(intfName, std::move(vlanIntf));
Ratan Gupta5978dd12017-07-25 13:47:13 +0530706
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700707 // write the device file for the vlan interface.
708 config::Parser config;
709 auto& netdev = config.map["NetDev"].emplace_back();
710 netdev["Name"].emplace_back(intfName);
711 netdev["Kind"].emplace_back("vlan");
712 config.map["VLAN"].emplace_back()["Id"].emplace_back(std::move(idStr));
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800713 config.writeFile(
714 config::pathForIntfDev(manager.get().getConfDir(), intfName));
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700715
716 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800717 manager.get().reloadConfigs();
William A. Kennington IIIf4b4ff82019-04-09 19:06:52 -0700718
William A. Kennington III7b90bc82022-11-17 14:55:12 -0800719 return ret;
Ratan Gupta5978dd12017-07-25 13:47:13 +0530720}
Ratan Gupta2b106532017-07-25 16:05:02 +0530721
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600722ServerList EthernetInterface::staticNTPServers(ServerList value)
Ratan Gupta497c0c92017-08-22 19:15:59 +0530723{
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700724 value = EthernetInterfaceIntf::staticNTPServers(std::move(value));
Ratan Gupta497c0c92017-08-22 19:15:59 +0530725
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700726 writeConfigurationFile();
727 manager.get().reloadConfigs();
728
729 return value;
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600730}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700731
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600732ServerList EthernetInterface::ntpServers(ServerList /*servers*/)
733{
734 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property"));
Ratan Gupta497c0c92017-08-22 19:15:59 +0530735}
Ratan Gupta2b106532017-07-25 16:05:02 +0530736
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700737static constexpr std::string_view tfStr(bool value)
738{
739 return value ? "true"sv : "false"sv;
740}
741
William A. Kennington III945878a2024-04-17 01:05:27 -0700742static void writeUpdatedTime(const Manager& manager,
743 const std::filesystem::path& netFile)
744{
745 // JFFS2 doesn't have the time granularity to deal with sub-second
746 // updates. Since we can have multiple file updates within a second
747 // around a reload, we need a location which gives that precision for
748 // future networkd detected reloads. TMPFS gives us this property.
749 if (manager.getConfDir() == "/etc/systemd/network"sv)
750 {
751 auto dir = stdplus::strCat(netFile.native(), ".d");
752 dir.replace(1, 3, "run"); // Replace /etc with /run
753 auto file = dir + "/updated.conf";
754 try
755 {
756 std::filesystem::create_directories(dir);
757 using namespace stdplus::fd;
758 futimens(
759 open(file,
760 OpenFlags(OpenAccess::WriteOnly).set(OpenFlag::Create),
761 0644)
762 .get(),
763 nullptr);
764 }
765 catch (const std::exception& e)
766 {
767 lg2::error("Failed to write time updated file {FILE}: {ERROR}",
768 "FILE", file, "ERROR", e.what());
769 }
770 }
771}
772
Ratan Gupta2b106532017-07-25 16:05:02 +0530773void EthernetInterface::writeConfigurationFile()
774{
William A. Kennington III95a49a22022-08-18 17:50:05 -0700775 config::Parser config;
776 config.map["Match"].emplace_back()["Name"].emplace_back(interfaceName());
Ratan Gupta2b106532017-07-25 16:05:02 +0530777 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700778 auto& link = config.map["Link"].emplace_back();
Johnathan Mantey609c12d2022-02-03 09:23:09 -0800779#ifdef PERSIST_MAC
William A. Kennington III95a49a22022-08-18 17:50:05 -0700780 auto mac = MacAddressIntf::macAddress();
781 if (!mac.empty())
782 {
783 link["MACAddress"].emplace_back(mac);
784 }
Johnathan Mantey609c12d2022-02-03 09:23:09 -0800785#endif
William A. Kennington III95a49a22022-08-18 17:50:05 -0700786 if (!EthernetInterfaceIntf::nicEnabled())
787 {
Johnathan Mantey8e3c1fb2024-03-12 13:07:50 -0700788 link["ActivationPolicy"].emplace_back("down");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700789 }
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700790 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700791 {
792 auto& network = config.map["Network"].emplace_back();
793 auto& lla = network["LinkLocalAddressing"];
Oskar Senftad21fc22018-07-26 16:32:23 -0400794#ifdef LINK_LOCAL_AUTOCONFIGURATION
William A. Kennington III95a49a22022-08-18 17:50:05 -0700795 lla.emplace_back("yes");
Oskar Senftad21fc22018-07-26 16:32:23 -0400796#else
William A. Kennington III95a49a22022-08-18 17:50:05 -0700797 lla.emplace_back("no");
Oskar Senftad21fc22018-07-26 16:32:23 -0400798#endif
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700799 network["IPv6AcceptRA"].emplace_back(ipv6AcceptRA() ? "true" : "false");
800 network["DHCP"].emplace_back(dhcp4() ? (dhcp6() ? "true" : "ipv4")
801 : (dhcp6() ? "ipv6" : "false"));
Nagaraju Goruganti210420a2018-03-07 09:22:28 -0600802 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700803 auto& vlans = network["VLAN"];
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800804 for (const auto& [_, intf] : manager.get().interfaces)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700805 {
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700806 if (intf->vlan && intf->vlan->parentIdx == ifIdx)
807 {
808 vlans.emplace_back(intf->interfaceName());
809 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700810 }
811 }
812 {
813 auto& ntps = network["NTP"];
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600814 for (const auto& ntp : EthernetInterfaceIntf::staticNTPServers())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700815 {
816 ntps.emplace_back(ntp);
817 }
818 }
819 {
820 auto& dnss = network["DNS"];
821 for (const auto& dns : EthernetInterfaceIntf::staticNameServers())
822 {
823 dnss.emplace_back(dns);
824 }
825 }
826 {
827 auto& address = network["Address"];
William A. Kennington III59e5b912022-11-02 02:49:46 -0700828 for (const auto& addr : addrs)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700829 {
Johnathan Mantey3865db22023-09-27 12:39:16 -0700830 if (addr.second->origin() == IP::AddressOrigin::Static)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700831 {
William A. Kennington IIIcafc1512023-07-25 02:22:32 -0700832 address.emplace_back(stdplus::toStr(addr.first));
William A. Kennington III95a49a22022-08-18 17:50:05 -0700833 }
834 }
835 }
836 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700837 if (!dhcp4())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700838 {
Ravi Teja91f60562024-04-17 06:26:43 -0500839 auto gateway4 = EthernetInterfaceIntf::defaultGateway();
840 if (!gateway4.empty())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700841 {
Ravi Teja91f60562024-04-17 06:26:43 -0500842 auto& gateway4route = config.map["Route"].emplace_back();
843 gateway4route["Gateway"].emplace_back(gateway4);
844 gateway4route["GatewayOnLink"].emplace_back("true");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700845 }
846 }
Ratan Gupta2b106532017-07-25 16:05:02 +0530847
William A. Kennington III05cbc5b2023-07-20 19:37:30 -0700848 if (!ipv6AcceptRA())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700849 {
850 auto gateway6 = EthernetInterfaceIntf::defaultGateway6();
851 if (!gateway6.empty())
852 {
Ravi Teja91f60562024-04-17 06:26:43 -0500853 auto& gateway6route = config.map["Route"].emplace_back();
854 gateway6route["Gateway"].emplace_back(gateway6);
855 gateway6route["GatewayOnLink"].emplace_back("true");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700856 }
857 }
Nagaraju Goruganti210420a2018-03-07 09:22:28 -0600858 }
Johnathan Mantey817012a2020-01-30 15:07:39 -0800859 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700860 config.map["IPv6AcceptRA"].emplace_back()["DHCPv6Client"].emplace_back(
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700861 dhcp6() ? "true" : "false");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500862 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700863 auto& neighbors = config.map["Neighbor"];
864 for (const auto& sneighbor : staticNeighbors)
Lei YUcb2d4082021-08-12 15:26:49 +0800865 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700866 auto& neighbor = neighbors.emplace_back();
867 neighbor["Address"].emplace_back(sneighbor.second->ipAddress());
868 neighbor["MACAddress"].emplace_back(sneighbor.second->macAddress());
Lei YUcb2d4082021-08-12 15:26:49 +0800869 }
Ravi Tejaa5a09442020-07-17 00:57:33 -0500870 }
Ravi Tejaa5a09442020-07-17 00:57:33 -0500871 {
Jishnu CM57dfea92023-05-05 06:07:26 -0500872 auto& dhcp4 = config.map["DHCPv4"].emplace_back();
873 dhcp4["ClientIdentifier"].emplace_back("mac");
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700874 dhcp4["UseDNS"].emplace_back(tfStr(dhcp4Conf->dnsEnabled()));
875 dhcp4["UseDomains"].emplace_back(tfStr(dhcp4Conf->domainEnabled()));
876 dhcp4["UseNTP"].emplace_back(tfStr(dhcp4Conf->ntpEnabled()));
877 dhcp4["UseHostname"].emplace_back(tfStr(dhcp4Conf->hostNameEnabled()));
Jishnu CM57dfea92023-05-05 06:07:26 -0500878 dhcp4["SendHostname"].emplace_back(
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700879 tfStr(dhcp4Conf->sendHostNameEnabled()));
Jishnu CM57dfea92023-05-05 06:07:26 -0500880 }
881 {
882 auto& dhcp6 = config.map["DHCPv6"].emplace_back();
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700883 dhcp6["UseDNS"].emplace_back(tfStr(dhcp6Conf->dnsEnabled()));
884 dhcp6["UseDomains"].emplace_back(tfStr(dhcp6Conf->domainEnabled()));
885 dhcp6["UseNTP"].emplace_back(tfStr(dhcp6Conf->ntpEnabled()));
886 dhcp6["UseHostname"].emplace_back(tfStr(dhcp6Conf->hostNameEnabled()));
William A. Kennington III44937b12024-04-17 00:28:20 -0700887 dhcp6["SendHostname"].emplace_back(
888 tfStr(dhcp6Conf->sendHostNameEnabled()));
Ravi Tejaa5a09442020-07-17 00:57:33 -0500889 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500890
891 {
892 auto& sroutes = config.map["Route"];
893 for (const auto& temp : staticGateways)
894 {
895 auto& staticGateway = sroutes.emplace_back();
896 staticGateway["Gateway"].emplace_back(temp.second->gateway());
897 staticGateway["GatewayOnLink"].emplace_back("true");
898 }
899 }
900
Patrick Williamsad205022024-08-16 15:20:07 -0400901 auto path =
902 config::pathForIntfConf(manager.get().getConfDir(), interfaceName());
William A. Kennington III95a49a22022-08-18 17:50:05 -0700903 config.writeFile(path);
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700904 lg2::info("Wrote networkd file: {CFG_FILE}", "CFG_FILE", path);
William A. Kennington III945878a2024-04-17 01:05:27 -0700905 writeUpdatedTime(manager, path);
Ratan Gupta2b106532017-07-25 16:05:02 +0530906}
907
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800908std::string EthernetInterface::macAddress([[maybe_unused]] std::string value)
Ratan Guptabd303b12017-08-18 17:10:07 +0530909{
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700910 if (vlan)
911 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700912 lg2::error("Tried to set MAC address on VLAN");
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700913 elog<InternalFailure>();
914 }
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800915#ifdef PERSIST_MAC
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700916 stdplus::EtherAddr newMAC;
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600917 try
918 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700919 newMAC = stdplus::fromStr<stdplus::EtherAddr>(value);
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600920 }
kokilavf51a2c62024-12-12 02:18:34 -0600921 catch (const std::exception& e)
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600922 {
Milton D. Miller IIe0349902025-04-12 23:23:04 +0000923 lg2::error("Invalid MAC address {NET_MAC}: {ERROR}", "NET_MAC", value,
kokilavf51a2c62024-12-12 02:18:34 -0600924 "ERROR", e);
925 elog<InvalidArgument>(Argument::ARGUMENT_NAME("netmac"),
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600926 Argument::ARGUMENT_VALUE(value.c_str()));
927 }
kokilavf51a2c62024-12-12 02:18:34 -0600928
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700929 if (!newMAC.isUnicast())
Ratan Guptabd303b12017-08-18 17:10:07 +0530930 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700931 lg2::error("MAC Address {NET_MAC} is not valid", "NET_MAC", value);
Gunnar Mills90480c42018-06-19 16:02:17 -0500932 elog<InvalidArgument>(Argument::ARGUMENT_NAME("MACAddress"),
933 Argument::ARGUMENT_VALUE(value.c_str()));
Ratan Guptabd303b12017-08-18 17:10:07 +0530934 }
935
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300936 auto interface = interfaceName();
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700937 auto validMAC = stdplus::toStr(newMAC);
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300938
William A. Kennington III1137a972019-04-20 20:49:58 -0700939 // We don't need to update the system if the address is unchanged
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700940 auto oldMAC =
941 stdplus::fromStr<stdplus::EtherAddr>(MacAddressIntf::macAddress());
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700942 if (newMAC != oldMAC)
Ratan Guptabd303b12017-08-18 17:10:07 +0530943 {
William A. Kennington III1137a972019-04-20 20:49:58 -0700944 // Update everything that depends on the MAC value
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800945 for (const auto& [_, intf] : manager.get().interfaces)
Ratan Guptabd303b12017-08-18 17:10:07 +0530946 {
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700947 if (intf->vlan && intf->vlan->parentIdx == ifIdx)
948 {
949 intf->MacAddressIntf::macAddress(validMAC);
950 }
Ratan Guptabd303b12017-08-18 17:10:07 +0530951 }
Patrick Williams6aef7692021-05-01 06:39:41 -0500952 MacAddressIntf::macAddress(validMAC);
Ratan Guptabd303b12017-08-18 17:10:07 +0530953
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700954 writeConfigurationFile();
William A. Kennington III945878a2024-04-17 01:05:27 -0700955 manager.get().addReloadPreHook([interface, manager = manager]() {
William A. Kennington III6bfdf3e2021-11-09 17:15:12 -0800956 // The MAC and LLADDRs will only update if the NIC is already down
William A. Kennington III2e09d272022-10-14 17:15:00 -0700957 system::setNICUp(interface, false);
William A. Kennington III945878a2024-04-17 01:05:27 -0700958 writeUpdatedTime(
959 manager,
960 config::pathForIntfConf(manager.get().getConfDir(), interface));
William A. Kennington III6bfdf3e2021-11-09 17:15:12 -0800961 });
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800962 manager.get().reloadConfigs();
Ratan Gupta677ae122017-09-18 16:28:50 +0530963 }
William A. Kennington III1137a972019-04-20 20:49:58 -0700964
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300965#ifdef HAVE_UBOOT_ENV
966 // Ensure that the valid address is stored in the u-boot-env
William A. Kennington III69f45542022-09-24 23:28:14 -0700967 auto envVar = interfaceToUbootEthAddr(interface);
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300968 if (envVar)
969 {
Asmitha Karunanithi33bc9a92020-08-13 08:48:33 -0500970 // Trimming MAC addresses that are out of range. eg: AA:FF:FF:FF:FF:100;
971 // and those having more than 6 bytes. eg: AA:AA:AA:AA:AA:AA:BB
972 execute("/sbin/fw_setenv", "fw_setenv", envVar->c_str(),
973 validMAC.c_str());
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300974 }
975#endif // HAVE_UBOOT_ENV
976
William A. Kennington III1137a972019-04-20 20:49:58 -0700977 return value;
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800978#else
979 elog<NotAllowed>(
980 NotAllowedArgument::REASON("Writing MAC address is not allowed"));
981#endif // PERSIST_MAC
Ratan Guptabd303b12017-08-18 17:10:07 +0530982}
983
Ratan Guptae9c9b812017-09-22 17:15:37 +0530984void EthernetInterface::deleteAll()
985{
Ratan Guptae9c9b812017-09-22 17:15:37 +0530986 // clear all the ip on the interface
987 addrs.clear();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700988
989 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800990 manager.get().reloadConfigs();
Ratan Guptae9c9b812017-09-22 17:15:37 +0530991}
992
William A. Kennington IIId4ff7312023-02-03 14:19:17 -0800993template <typename Addr>
994static void normalizeGateway(std::string& gw)
Ravi Tejaa5a09442020-07-17 00:57:33 -0500995{
William A. Kennington IIId4ff7312023-02-03 14:19:17 -0800996 if (gw.empty())
997 {
998 return;
999 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001000 try
Ravi Tejaa5a09442020-07-17 00:57:33 -05001001 {
William A. Kennington III9ca5c8e2022-12-14 14:40:52 -08001002 auto ip = stdplus::fromStr<Addr>(gw);
1003 if (ip == Addr{})
1004 {
1005 gw.clear();
1006 return;
1007 }
William A. Kennington IIIbbf5e9e2023-02-01 14:58:38 -08001008 if (!validIntfIP(ip))
1009 {
1010 throw std::invalid_argument("Invalid unicast");
1011 }
William A. Kennington III9ca5c8e2022-12-14 14:40:52 -08001012 gw = stdplus::toStr(ip);
Ravi Tejaa5a09442020-07-17 00:57:33 -05001013 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001014 catch (const std::exception& e)
Ravi Tejaa5a09442020-07-17 00:57:33 -05001015 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001016 lg2::error("Invalid GW `{NET_GW}`: {ERROR}", "NET_GW", gw, "ERROR", e);
Ravi Tejaa5a09442020-07-17 00:57:33 -05001017 elog<InvalidArgument>(Argument::ARGUMENT_NAME("GATEWAY"),
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001018 Argument::ARGUMENT_VALUE(gw.c_str()));
Ravi Tejaa5a09442020-07-17 00:57:33 -05001019 }
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001020}
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001021
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001022std::string EthernetInterface::defaultGateway(std::string gateway)
1023{
1024 normalizeGateway<stdplus::In4Addr>(gateway);
1025 if (gateway != defaultGateway())
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001026 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001027 gateway = EthernetInterfaceIntf::defaultGateway(std::move(gateway));
Yuxiao Zhangaf38fe92023-10-12 13:50:50 -07001028 writeConfigurationFile();
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001029 manager.get().reloadConfigs();
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001030 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001031 return gateway;
Ravi Tejaa5a09442020-07-17 00:57:33 -05001032}
1033
1034std::string EthernetInterface::defaultGateway6(std::string gateway)
1035{
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001036 normalizeGateway<stdplus::In6Addr>(gateway);
1037 if (gateway != defaultGateway6())
Ravi Tejaa5a09442020-07-17 00:57:33 -05001038 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001039 gateway = EthernetInterfaceIntf::defaultGateway6(std::move(gateway));
Yuxiao Zhangaf38fe92023-10-12 13:50:50 -07001040 writeConfigurationFile();
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001041 manager.get().reloadConfigs();
Ravi Tejaa5a09442020-07-17 00:57:33 -05001042 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001043 return gateway;
Ravi Tejaa5a09442020-07-17 00:57:33 -05001044}
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001045
1046EthernetInterface::VlanProperties::VlanProperties(
1047 sdbusplus::bus_t& bus, stdplus::const_zstring objPath,
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001048 const InterfaceInfo& info, stdplus::PinnedRef<EthernetInterface> eth) :
William A. Kennington IIIb6452542022-11-15 18:09:12 -08001049 VlanIfaces(bus, objPath.c_str(), VlanIfaces::action::defer_emit),
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001050 parentIdx(*info.parent_idx), eth(eth)
1051{
William A. Kennington IIId99e6db2022-11-15 20:39:45 -08001052 VlanIntf::id(*info.vlan_id, true);
1053 emit_object_added();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001054}
1055
1056void EthernetInterface::VlanProperties::delete_()
1057{
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001058 auto intf = eth.get().interfaceName();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001059
1060 // Remove all configs for the current interface
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001061 const auto& confDir = eth.get().manager.get().getConfDir();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001062 std::error_code ec;
1063 std::filesystem::remove(config::pathForIntfConf(confDir, intf), ec);
1064 std::filesystem::remove(config::pathForIntfDev(confDir, intf), ec);
1065
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001066 if (eth.get().ifIdx > 0)
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001067 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001068 eth.get().manager.get().interfacesByIdx.erase(eth.get().ifIdx);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001069 }
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001070 auto it = eth.get().manager.get().interfaces.find(intf);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001071 auto obj = std::move(it->second);
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001072 eth.get().manager.get().interfaces.erase(it);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001073
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001074 // Write an updated parent interface since it has a VLAN entry
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001075 for (const auto& [_, intf] : eth.get().manager.get().interfaces)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001076 {
1077 if (intf->ifIdx == parentIdx)
1078 {
1079 intf->writeConfigurationFile();
1080 }
1081 }
1082
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001083 if (eth.get().ifIdx > 0)
William A. Kennington III67b09da2022-10-31 14:09:53 -07001084 {
William A. Kennington III6d217512022-11-17 16:18:01 -08001085 // We need to forcibly delete the interface as systemd does not
Patrick Williamsad205022024-08-16 15:20:07 -04001086 eth.get().manager.get().addReloadPostHook([idx = eth.get().ifIdx]() {
1087 system::deleteIntf(idx);
1088 });
William A. Kennington III6d217512022-11-17 16:18:01 -08001089
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001090 // Ignore the interface so the reload doesn't re-query it
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001091 eth.get().manager.get().ignoredIntf.emplace(eth.get().ifIdx);
William A. Kennington III67b09da2022-10-31 14:09:53 -07001092 }
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001093
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001094 eth.get().manager.get().reloadConfigs();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001095}
1096
Jishnu CM57dfea92023-05-05 06:07:26 -05001097void EthernetInterface::reloadConfigs()
1098{
1099 manager.get().reloadConfigs();
1100}
1101
Gunnar Mills57d9c502018-09-14 14:42:34 -05001102} // namespace network
1103} // namespace phosphor