blob: b04bc2d5574ef3b9d0902e918161c87f1c7aa314 [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>
Patrick Williams618ac412025-04-27 02:31:49 -040055inline decltype(std::declval<Func>()()) ignoreError(
56 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 Tejaf7116de2024-12-08 22:48:21 -0600105 auto lldpVal = parseLLDPConf();
106 if (!lldpVal.empty())
107 {
108 EthernetInterfaceIntf::emitLLDP(lldpVal[interfaceName()], true);
109 }
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700110 EthernetInterfaceIntf::ntpServers(
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800111 config.map.getValueStrings("Network", "NTP"), true);
Ratan Gupta613a0122020-04-24 15:18:53 +0530112
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800113 updateInfo(info.intf, true);
114
115 if (info.defgw4)
116 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700117 EthernetInterface::defaultGateway(stdplus::toStr(*info.defgw4), true);
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800118 }
119 if (info.defgw6)
120 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700121 EthernetInterface::defaultGateway6(stdplus::toStr(*info.defgw6), true);
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800122 }
123 emit_object_added();
William A. Kennington IIId298f932022-10-17 14:31:38 -0700124
William A. Kennington III13d665c2022-11-15 20:34:40 -0800125 if (info.intf.vlan_id)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700126 {
William A. Kennington III13d665c2022-11-15 20:34:40 -0800127 if (!info.intf.parent_idx)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700128 {
129 std::runtime_error("Missing parent link");
130 }
William A. Kennington III13d665c2022-11-15 20:34:40 -0800131 vlan.emplace(bus, this->objPath.c_str(), info.intf, *this);
132 }
William A. Kennington IIIfad525c2024-04-17 00:51:59 -0700133 dhcp4Conf.emplace(bus, this->objPath + "/dhcp4", *this, DHCPType::v4);
134 dhcp6Conf.emplace(bus, this->objPath + "/dhcp6", *this, DHCPType::v6);
William A. Kennington III13d665c2022-11-15 20:34:40 -0800135 for (const auto& [_, addr] : info.addrs)
136 {
137 addAddr(addr);
138 }
139 for (const auto& [_, neigh] : info.staticNeighs)
140 {
141 addStaticNeigh(neigh);
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700142 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500143 for (const auto& [_, staticGateway] : info.staticGateways)
144 {
145 addStaticGateway(staticGateway);
146 }
Ratan Gupta29b0e432017-05-25 12:51:40 +0530147}
148
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800149void EthernetInterface::updateInfo(const InterfaceInfo& info, bool skipSignal)
William A. Kennington IIId298f932022-10-17 14:31:38 -0700150{
William A. Kennington III876927c2022-11-17 16:20:15 -0800151 ifIdx = info.idx;
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800152 EthernetInterfaceIntf::linkUp(info.flags & IFF_RUNNING, skipSignal);
William A. Kennington IIId298f932022-10-17 14:31:38 -0700153 if (info.mac)
154 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700155 MacAddressIntf::macAddress(stdplus::toStr(*info.mac), skipSignal);
William A. Kennington IIId298f932022-10-17 14:31:38 -0700156 }
157 if (info.mtu)
158 {
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800159 EthernetInterfaceIntf::mtu(*info.mtu, skipSignal);
William A. Kennington IIId298f932022-10-17 14:31:38 -0700160 }
William A. Kennington III21539662022-11-15 14:53:11 -0800161 if (ifIdx > 0)
162 {
163 auto ethInfo = ignoreError("GetEthInfo", *info.name, {}, [&] {
164 return system::getEthInfo(*info.name);
165 });
William A. Kennington IIId99e6db2022-11-15 20:39:45 -0800166 EthernetInterfaceIntf::autoNeg(ethInfo.autoneg, skipSignal);
167 EthernetInterfaceIntf::speed(ethInfo.speed, skipSignal);
William A. Kennington III21539662022-11-15 14:53:11 -0800168 }
William A. Kennington IIId298f932022-10-17 14:31:38 -0700169}
170
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800171void EthernetInterface::addAddr(const AddressInfo& info)
172{
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800173 IP::AddressOrigin origin = IP::AddressOrigin::Static;
Ravi Teja86c4f442023-07-19 22:26:39 -0500174 if (dhcpIsEnabled(info.ifaddr.getAddr()))
175 {
176 origin = IP::AddressOrigin::DHCP;
177 }
178
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800179#ifdef LINK_LOCAL_AUTOCONFIGURATION
180 if (info.scope == RT_SCOPE_LINK)
181 {
182 origin = IP::AddressOrigin::LinkLocal;
183 }
184#endif
185
Ravi Tejac6201202023-03-28 21:29:58 -0500186 if ((info.scope == RT_SCOPE_UNIVERSE) && (info.flags & IFA_F_PERMANENT))
187 {
188 origin = IP::AddressOrigin::Static;
189 }
190 if ((info.scope == RT_SCOPE_UNIVERSE) &&
191 ((info.flags & IFA_F_NOPREFIXROUTE) &&
192 (info.flags & IFA_F_MANAGETEMPADDR)))
193 {
194 origin = IP::AddressOrigin::SLAAC;
195 }
196 else if ((info.scope == RT_SCOPE_UNIVERSE) &&
197 ((info.flags & IFA_F_NOPREFIXROUTE)))
198 {
199 origin = IP::AddressOrigin::DHCP;
200 }
201
William A. Kennington III77747f62022-11-07 23:11:15 -0800202 auto it = addrs.find(info.ifaddr);
203 if (it == addrs.end())
204 {
205 addrs.emplace(info.ifaddr, std::make_unique<IPAddress>(
206 bus, std::string_view(objPath), *this,
207 info.ifaddr, origin));
208 }
209 else
210 {
211 it->second->IPIfaces::origin(origin);
212 }
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800213}
214
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800215void EthernetInterface::addStaticNeigh(const NeighborInfo& info)
216{
William A. Kennington IIId3615142022-11-12 01:28:33 -0800217 if (!info.mac || !info.addr)
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800218 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700219 lg2::error("Missing neighbor mac on {NET_INTF}", "NET_INTF",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700220 interfaceName());
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800221 return;
222 }
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800223
224 if (auto it = staticNeighbors.find(*info.addr); it != staticNeighbors.end())
225 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700226 it->second->NeighborObj::macAddress(stdplus::toStr(*info.mac));
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800227 }
228 else
229 {
Patrick Williamsad205022024-08-16 15:20:07 -0400230 staticNeighbors.emplace(
231 *info.addr, std::make_unique<Neighbor>(
232 bus, std::string_view(objPath), *this, *info.addr,
233 *info.mac, Neighbor::State::Permanent));
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800234 }
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800235}
236
Ravi Tejaab27a812023-05-02 10:01:53 -0500237void EthernetInterface::addStaticGateway(const StaticGatewayInfo& info)
238{
239 if (!info.gateway)
240 {
241 lg2::error("Missing static gateway on {NET_INTF}", "NET_INTF",
242 interfaceName());
243 return;
244 }
245
246 IP::Protocol protocolType;
247 if (*info.protocol == "IPv4")
248 {
249 protocolType = IP::Protocol::IPv4;
250 }
251 else if (*info.protocol == "IPv6")
252 {
253 protocolType = IP::Protocol::IPv6;
254 }
255
256 if (auto it = staticGateways.find(*info.gateway);
257 it != staticGateways.end())
258 {
259 it->second->StaticGatewayObj::gateway(*info.gateway);
260 }
261 else
262 {
263 staticGateways.emplace(*info.gateway,
264 std::make_unique<StaticGateway>(
265 bus, std::string_view(objPath), *this,
266 *info.gateway, protocolType));
267 }
268}
269
Patrick Williams6aef7692021-05-01 06:39:41 -0500270ObjectPath EthernetInterface::ip(IP::Protocol protType, std::string ipaddress,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700271 uint8_t prefixLength, std::string)
Ratan Gupta82549cc2017-04-21 08:45:23 +0530272{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700273 std::optional<stdplus::InAnyAddr> addr;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700274 try
Ratan Guptafc2c7242017-05-29 08:46:06 +0530275 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700276 switch (protType)
277 {
278 case IP::Protocol::IPv4:
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700279 addr.emplace(stdplus::fromStr<stdplus::In4Addr>(ipaddress));
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700280 break;
281 case IP::Protocol::IPv6:
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700282 addr.emplace(stdplus::fromStr<stdplus::In6Addr>(ipaddress));
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700283 break;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700284 default:
285 throw std::logic_error("Exhausted protocols");
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700286 }
William A. Kennington III30f3ba22023-06-28 15:50:12 -0700287 if (!std::visit([](auto ip) { return validIntfIP(ip); }, *addr))
288 {
289 throw std::invalid_argument("not unicast");
290 }
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500291 }
William A. Kennington III59e5b912022-11-02 02:49:46 -0700292 catch (const std::exception& e)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500293 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700294 lg2::error("Invalid IP {NET_IP}: {ERROR}", "NET_IP", ipaddress, "ERROR",
295 e);
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500296 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"),
297 Argument::ARGUMENT_VALUE(ipaddress.c_str()));
298 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700299 std::optional<stdplus::SubnetAny> ifaddr;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700300 try
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500301 {
William A. Kennington III30f3ba22023-06-28 15:50:12 -0700302 if (prefixLength == 0)
303 {
304 throw std::invalid_argument("default route");
305 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700306 ifaddr.emplace(*addr, prefixLength);
William A. Kennington III59e5b912022-11-02 02:49:46 -0700307 }
308 catch (const std::exception& e)
309 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700310 lg2::error("Invalid prefix length {NET_PFX}: {ERROR}", "NET_PFX",
311 prefixLength, "ERROR", e);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500312 elog<InvalidArgument>(
313 Argument::ARGUMENT_NAME("prefixLength"),
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700314 Argument::ARGUMENT_VALUE(stdplus::toStr(prefixLength).c_str()));
Ratan Guptafc2c7242017-05-29 08:46:06 +0530315 }
316
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700317 auto it = addrs.find(*ifaddr);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800318 if (it == addrs.end())
319 {
320 it = std::get<0>(addrs.emplace(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700321 *ifaddr,
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800322 std::make_unique<IPAddress>(bus, std::string_view(objPath), *this,
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700323 *ifaddr, IP::AddressOrigin::Static)));
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800324 }
325 else
326 {
William A. Kennington IIIadd08712022-11-17 16:31:19 -0800327 if (it->second->origin() == IP::AddressOrigin::Static)
328 {
329 return it->second->getObjPath();
330 }
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800331 it->second->IPIfaces::origin(IP::AddressOrigin::Static);
332 }
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530333
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700334 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800335 manager.get().reloadConfigs();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700336
William A. Kennington III434a9432022-11-04 18:38:46 -0700337 return it->second->getObjPath();
Ratan Gupta82549cc2017-04-21 08:45:23 +0530338}
339
Patrick Williams6aef7692021-05-01 06:39:41 -0500340ObjectPath EthernetInterface::neighbor(std::string ipAddress,
341 std::string macAddress)
William A. Kennington III08505792019-01-30 16:00:04 -0800342{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700343 std::optional<stdplus::InAnyAddr> addr;
William A. Kennington III434a9432022-11-04 18:38:46 -0700344 try
William A. Kennington III08505792019-01-30 16:00:04 -0800345 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700346 addr.emplace(stdplus::fromStr<stdplus::InAnyAddr>(ipAddress));
William A. Kennington III434a9432022-11-04 18:38:46 -0700347 }
348 catch (const std::exception& e)
349 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700350 lg2::error("Not a valid IP address {NET_IP}: {ERROR}", "NET_IP",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700351 ipAddress, "ERROR", e);
Patrick Williams6aef7692021-05-01 06:39:41 -0500352 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipAddress"),
353 Argument::ARGUMENT_VALUE(ipAddress.c_str()));
William A. Kennington III08505792019-01-30 16:00:04 -0800354 }
William A. Kennington III434a9432022-11-04 18:38:46 -0700355
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700356 std::optional<stdplus::EtherAddr> lladdr;
William A. Kennington III434a9432022-11-04 18:38:46 -0700357 try
William A. Kennington III08505792019-01-30 16:00:04 -0800358 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700359 lladdr.emplace(stdplus::fromStr<stdplus::EtherAddr>(macAddress));
William A. Kennington III434a9432022-11-04 18:38:46 -0700360 }
361 catch (const std::exception& e)
362 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700363 lg2::error("Not a valid MAC address {NET_MAC}: {ERROR}", "NET_MAC",
364 macAddress, "ERROR", e);
Patrick Williams6aef7692021-05-01 06:39:41 -0500365 elog<InvalidArgument>(Argument::ARGUMENT_NAME("macAddress"),
366 Argument::ARGUMENT_VALUE(macAddress.c_str()));
William A. Kennington III08505792019-01-30 16:00:04 -0800367 }
368
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700369 auto it = staticNeighbors.find(*addr);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800370 if (it == staticNeighbors.end())
371 {
372 it = std::get<0>(staticNeighbors.emplace(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700373 *addr, std::make_unique<Neighbor>(bus, std::string_view(objPath),
374 *this, *addr, *lladdr,
375 Neighbor::State::Permanent)));
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800376 }
377 else
378 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700379 auto str = stdplus::toStr(*lladdr);
William A. Kennington IIIadd08712022-11-17 16:31:19 -0800380 if (it->second->macAddress() == str)
381 {
382 return it->second->getObjPath();
383 }
384 it->second->NeighborObj::macAddress(str);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800385 }
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700386
387 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800388 manager.get().reloadConfigs();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700389
William A. Kennington III434a9432022-11-04 18:38:46 -0700390 return it->second->getObjPath();
William A. Kennington III08505792019-01-30 16:00:04 -0800391}
392
Ravi Tejaab27a812023-05-02 10:01:53 -0500393ObjectPath EthernetInterface::staticGateway(std::string gateway,
394 IP::Protocol protocolType)
395{
396 std::optional<stdplus::InAnyAddr> addr;
397 std::string route;
398 try
399 {
kokilav0779db72025-01-07 10:21:51 -0600400 switch (protocolType)
401 {
402 case IP::Protocol::IPv4:
403 addr.emplace(stdplus::fromStr<stdplus::In4Addr>(gateway));
404 break;
405 case IP::Protocol::IPv6:
406 addr.emplace(stdplus::fromStr<stdplus::In6Addr>(gateway));
407 break;
408 default:
409 throw std::logic_error("Exhausted protocols");
410 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500411 route = gateway;
412 }
413 catch (const std::exception& e)
414 {
415 lg2::error("Not a valid IP address {GATEWAY}: {ERROR}", "GATEWAY",
416 gateway, "ERROR", e);
417 elog<InvalidArgument>(Argument::ARGUMENT_NAME("gateway"),
418 Argument::ARGUMENT_VALUE(gateway.c_str()));
419 }
420
421 auto it = staticGateways.find(route);
422 if (it == staticGateways.end())
423 {
424 it = std::get<0>(staticGateways.emplace(
425 route,
426 std::make_unique<StaticGateway>(bus, std::string_view(objPath),
427 *this, gateway, protocolType)));
428 }
429 else
430 {
431 it->second->StaticGatewayObj::gateway(gateway);
432 }
433
434 writeConfigurationFile();
435 manager.get().reloadConfigs();
436
437 return it->second->getObjPath();
438}
439
Patrick Williams6aef7692021-05-01 06:39:41 -0500440bool EthernetInterface::ipv6AcceptRA(bool value)
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700441{
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700442 if (ipv6AcceptRA() != EthernetInterfaceIntf::ipv6AcceptRA(value))
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700443 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700444 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800445 manager.get().reloadConfigs();
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700446 }
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700447 return value;
448}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700449
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700450bool EthernetInterface::dhcp4(bool value)
451{
452 if (dhcp4() != EthernetInterfaceIntf::dhcp4(value))
453 {
454 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800455 manager.get().reloadConfigs();
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700456 }
457 return value;
458}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700459
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700460bool EthernetInterface::dhcp6(bool value)
461{
462 if (dhcp6() != EthernetInterfaceIntf::dhcp6(value))
463 {
464 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800465 manager.get().reloadConfigs();
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700466 }
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700467 return value;
468}
469
Patrick Williams6aef7692021-05-01 06:39:41 -0500470EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled(DHCPConf value)
Ratan Gupta87c13982017-06-15 09:27:27 +0530471{
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700472 auto old4 = EthernetInterfaceIntf::dhcp4();
Patrick Williamsad205022024-08-16 15:20:07 -0400473 auto new4 = EthernetInterfaceIntf::dhcp4(
474 value == DHCPConf::v4 || value == DHCPConf::v4v6stateless ||
475 value == DHCPConf::both);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700476 auto old6 = EthernetInterfaceIntf::dhcp6();
Patrick Williamsad205022024-08-16 15:20:07 -0400477 auto new6 = EthernetInterfaceIntf::dhcp6(
478 value == DHCPConf::v6 || value == DHCPConf::both);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700479 auto oldra = EthernetInterfaceIntf::ipv6AcceptRA();
480 auto newra = EthernetInterfaceIntf::ipv6AcceptRA(
481 value == DHCPConf::v6stateless || value == DHCPConf::v4v6stateless ||
482 value == DHCPConf::v6 || value == DHCPConf::both);
483
484 if (old4 != new4 || old6 != new6 || oldra != newra)
Ratan Gupta5978dd12017-07-25 13:47:13 +0530485 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700486 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800487 manager.get().reloadConfigs();
Ratan Gupta5978dd12017-07-25 13:47:13 +0530488 }
Ratan Gupta87c13982017-06-15 09:27:27 +0530489 return value;
490}
491
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700492EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled() const
493{
494 if (dhcp6())
495 {
496 return dhcp4() ? DHCPConf::both : DHCPConf::v6;
497 }
498 else if (dhcp4())
499 {
500 return ipv6AcceptRA() ? DHCPConf::v4v6stateless : DHCPConf::v4;
501 }
502 return ipv6AcceptRA() ? DHCPConf::v6stateless : DHCPConf::none;
503}
504
Tejas Patil2c0fc562021-08-03 19:13:46 +0530505size_t EthernetInterface::mtu(size_t value)
506{
William A. Kennington III2e09d272022-10-14 17:15:00 -0700507 const size_t old = EthernetInterfaceIntf::mtu();
508 if (value == old)
Tejas Patil2c0fc562021-08-03 19:13:46 +0530509 {
510 return value;
511 }
William A. Kennington III2e09d272022-10-14 17:15:00 -0700512 const auto ifname = interfaceName();
William A. Kennington III3e471c52022-10-27 19:46:07 -0700513 return EthernetInterfaceIntf::mtu(ignoreError("SetMTU", ifname, old, [&] {
William A. Kennington III2e09d272022-10-14 17:15:00 -0700514 system::setMTU(ifname, value);
515 return value;
516 }));
Tejas Patil2c0fc562021-08-03 19:13:46 +0530517}
518
Patrick Williams6aef7692021-05-01 06:39:41 -0500519bool EthernetInterface::nicEnabled(bool value)
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700520{
Patrick Williams6aef7692021-05-01 06:39:41 -0500521 if (value == EthernetInterfaceIntf::nicEnabled())
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700522 {
523 return value;
524 }
525
William A. Kennington IIIc922d5e2022-01-21 01:08:31 -0800526 EthernetInterfaceIntf::nicEnabled(value);
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700527 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800528 manager.get().reloadConfigs();
Johnathan Manteyfaa72e52020-01-08 10:38:58 -0800529
530 return value;
531}
532
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530533ServerList EthernetInterface::staticNameServers(ServerList value)
534{
nitinkotania581cb0b2023-03-21 00:28:55 -0500535 std::vector<std::string> dnsUniqueValues;
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700536 for (auto& ip : value)
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530537 {
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700538 try
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530539 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700540 ip = stdplus::toStr(stdplus::fromStr<stdplus::InAnyAddr>(ip));
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700541 }
542 catch (const std::exception& e)
543 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700544 lg2::error("Not a valid IP address {NET_IP}: {ERROR}", "NET_IP", ip,
545 "ERROR", e);
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700546 elog<InvalidArgument>(Argument::ARGUMENT_NAME("StaticNameserver"),
547 Argument::ARGUMENT_VALUE(ip.c_str()));
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530548 }
nitinkotania581cb0b2023-03-21 00:28:55 -0500549 if (std::find(dnsUniqueValues.begin(), dnsUniqueValues.end(), ip) ==
550 dnsUniqueValues.end())
551 {
552 dnsUniqueValues.push_back(ip);
553 }
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530554 }
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700555
nitinkotania581cb0b2023-03-21 00:28:55 -0500556 value =
557 EthernetInterfaceIntf::staticNameServers(std::move(dnsUniqueValues));
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700558
559 writeConfigurationFile();
560 manager.get().reloadConfigs();
561
562 return value;
Ratan Gupta6dec3902017-08-20 15:28:12 +0530563}
564
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600565void EthernetInterface::loadNTPServers(const config::Parser& config)
566{
Jishnu CM4fe86132024-09-15 12:02:56 -0500567 ServerList ntpServerList = getNTPServerFromTimeSyncd();
568 ServerList staticNTPServers = config.map.getValueStrings("Network", "NTP");
569
570 std::unordered_set<std::string> staticNTPServersSet(
571 staticNTPServers.begin(), staticNTPServers.end());
572 ServerList networkSuppliedServers;
573
574 std::copy_if(ntpServerList.begin(), ntpServerList.end(),
575 std::back_inserter(networkSuppliedServers),
576 [&staticNTPServersSet](const std::string& server) {
577 return staticNTPServersSet.find(server) ==
578 staticNTPServersSet.end();
579 });
580
581 EthernetInterfaceIntf::ntpServers(networkSuppliedServers);
582 EthernetInterfaceIntf::staticNTPServers(staticNTPServers);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600583}
584
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700585void EthernetInterface::loadNameServers(const config::Parser& config)
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530586{
587 EthernetInterfaceIntf::nameservers(getNameServerFromResolvd());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700588 EthernetInterfaceIntf::staticNameServers(
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700589 config.map.getValueStrings("Network", "DNS"));
Ratan Gupta6dec3902017-08-20 15:28:12 +0530590}
591
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600592ServerList EthernetInterface::getNTPServerFromTimeSyncd()
593{
594 ServerList servers; // Variable to capture the NTP Server IPs
Patrick Williamsad205022024-08-16 15:20:07 -0400595 auto method =
596 bus.get().new_method_call(TIMESYNCD_SERVICE, TIMESYNCD_SERVICE_PATH,
597 PROPERTY_INTERFACE, METHOD_GET);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600598
599 method.append(TIMESYNCD_INTERFACE, "LinkNTPServers");
600
601 try
602 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800603 auto reply = bus.get().call(method);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600604 std::variant<ServerList> response;
605 reply.read(response);
606 servers = std::get<ServerList>(response);
607 }
608 catch (const sdbusplus::exception::SdBusError& e)
609 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700610 lg2::error("Failed to get NTP server information from "
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700611 "systemd-timesyncd: {ERROR}",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700612 "ERROR", e);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600613 }
614
615 return servers;
616}
617
Ravi Teja4f8b9a02023-09-06 13:41:52 -0500618ServerList EthernetInterface::nameservers() const
619{
620 return getNameServerFromResolvd();
621}
622
623ServerList EthernetInterface::getNameServerFromResolvd() const
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530624{
625 ServerList servers;
William A. Kennington IIIcafc1512023-07-25 02:22:32 -0700626 auto OBJ_PATH = std::format("{}{}", RESOLVED_SERVICE_PATH, ifIdx);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530627
628 /*
629 The DNS property under org.freedesktop.resolve1.Link interface contains
630 an array containing all DNS servers currently used by resolved. It
631 contains similar information as the DNS server data written to
632 /run/systemd/resolve/resolv.conf.
633
634 Each structure in the array consists of a numeric network interface index,
635 an address family, and a byte array containing the DNS server address
636 (either 4 bytes in length for IPv4 or 16 bytes in lengths for IPv6).
637 The array contains DNS servers configured system-wide, including those
638 possibly read from a foreign /etc/resolv.conf or the DNS= setting in
639 /etc/systemd/resolved.conf, as well as per-interface DNS server
640 information either retrieved from systemd-networkd or configured by
641 external software via SetLinkDNS().
642 */
643
644 using type = std::vector<std::tuple<int32_t, std::vector<uint8_t>>>;
645 std::variant<type> name; // Variable to capture the DNS property
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800646 auto method = bus.get().new_method_call(RESOLVED_SERVICE, OBJ_PATH.c_str(),
647 PROPERTY_INTERFACE, METHOD_GET);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530648
649 method.append(RESOLVED_INTERFACE, "DNS");
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530650
651 try
652 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800653 auto reply = bus.get().call(method);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530654 reply.read(name);
655 }
Patrick Williamsc38b0712022-07-22 19:26:54 -0500656 catch (const sdbusplus::exception_t& e)
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530657 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700658 lg2::error(
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700659 "Failed to get DNS information from systemd-resolved: {ERROR}",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700660 "ERROR", e);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530661 }
662 auto tupleVector = std::get_if<type>(&name);
663 for (auto i = tupleVector->begin(); i != tupleVector->end(); ++i)
664 {
Alexander Filippov983da552021-02-08 15:26:54 +0300665 int addressFamily = std::get<0>(*i);
666 std::vector<uint8_t>& ipaddress = std::get<1>(*i);
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700667 servers.push_back(stdplus::toStr(
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700668 addrFromBuf(addressFamily, stdplus::raw::asView<char>(ipaddress))));
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530669 }
670 return servers;
671}
672
William A. Kennington IIId298f932022-10-17 14:31:38 -0700673ObjectPath EthernetInterface::createVLAN(uint16_t id)
Ratan Gupta5978dd12017-07-25 13:47:13 +0530674{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700675 auto idStr = stdplus::toStr(id);
William A. Kennington III86642522023-07-24 17:55:55 -0700676 auto intfName = stdplus::strCat(interfaceName(), "."sv, idStr);
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800677 if (manager.get().interfaces.find(intfName) !=
678 manager.get().interfaces.end())
Jiaqing Zhao33b4eaa2022-04-12 23:11:40 +0800679 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700680 lg2::error("VLAN {NET_VLAN} already exists", "NET_VLAN", id);
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700681 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VLANId"),
682 Argument::ARGUMENT_VALUE(idStr.c_str()));
Jiaqing Zhao33b4eaa2022-04-12 23:11:40 +0800683 }
684
William A. Kennington IIId298f932022-10-17 14:31:38 -0700685 auto objRoot = std::string_view(objPath).substr(0, objPath.rfind('/'));
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700686 auto macStr = MacAddressIntf::macAddress();
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700687 std::optional<stdplus::EtherAddr> mac;
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700688 if (!macStr.empty())
689 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700690 mac.emplace(stdplus::fromStr<stdplus::EtherAddr>(macStr));
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700691 }
William A. Kennington III13d665c2022-11-15 20:34:40 -0800692 auto info = AllIntfInfo{InterfaceInfo{
William A. Kennington III9c441fd2023-02-24 13:40:01 -0800693 .type = ARPHRD_ETHER,
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700694 .idx = 0, // TODO: Query the correct value after creation
695 .flags = 0,
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700696 .name = intfName,
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700697 .mac = std::move(mac),
698 .mtu = mtu(),
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700699 .parent_idx = ifIdx,
700 .vlan_id = id,
William A. Kennington III13d665c2022-11-15 20:34:40 -0800701 }};
Ratan Gupta5978dd12017-07-25 13:47:13 +0530702
Patrick Williams6aef7692021-05-01 06:39:41 -0500703 // Pass the parents nicEnabled property, so that the child
Manojkiran Edaca8b91b2020-05-28 09:28:42 +0530704 // VLAN interface can inherit.
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700705 auto vlanIntf = std::make_unique<EthernetInterface>(
William A. Kennington IIIb6452542022-11-15 18:09:12 -0800706 bus, manager, info, objRoot, config::Parser(), nicEnabled());
William A. Kennington IIId298f932022-10-17 14:31:38 -0700707 ObjectPath ret = vlanIntf->objPath;
Ratan Gupta5978dd12017-07-25 13:47:13 +0530708
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800709 manager.get().interfaces.emplace(intfName, std::move(vlanIntf));
Ratan Gupta5978dd12017-07-25 13:47:13 +0530710
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700711 // write the device file for the vlan interface.
712 config::Parser config;
713 auto& netdev = config.map["NetDev"].emplace_back();
714 netdev["Name"].emplace_back(intfName);
715 netdev["Kind"].emplace_back("vlan");
716 config.map["VLAN"].emplace_back()["Id"].emplace_back(std::move(idStr));
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800717 config.writeFile(
718 config::pathForIntfDev(manager.get().getConfDir(), intfName));
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700719
720 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800721 manager.get().reloadConfigs();
William A. Kennington IIIf4b4ff82019-04-09 19:06:52 -0700722
William A. Kennington III7b90bc82022-11-17 14:55:12 -0800723 return ret;
Ratan Gupta5978dd12017-07-25 13:47:13 +0530724}
Ratan Gupta2b106532017-07-25 16:05:02 +0530725
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600726ServerList EthernetInterface::staticNTPServers(ServerList value)
Ratan Gupta497c0c92017-08-22 19:15:59 +0530727{
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700728 value = EthernetInterfaceIntf::staticNTPServers(std::move(value));
Ratan Gupta497c0c92017-08-22 19:15:59 +0530729
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700730 writeConfigurationFile();
731 manager.get().reloadConfigs();
732
733 return value;
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600734}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700735
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600736ServerList EthernetInterface::ntpServers(ServerList /*servers*/)
737{
738 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property"));
Ratan Gupta497c0c92017-08-22 19:15:59 +0530739}
Ratan Gupta2b106532017-07-25 16:05:02 +0530740
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700741static constexpr std::string_view tfStr(bool value)
742{
743 return value ? "true"sv : "false"sv;
744}
745
William A. Kennington III945878a2024-04-17 01:05:27 -0700746static void writeUpdatedTime(const Manager& manager,
747 const std::filesystem::path& netFile)
748{
749 // JFFS2 doesn't have the time granularity to deal with sub-second
750 // updates. Since we can have multiple file updates within a second
751 // around a reload, we need a location which gives that precision for
752 // future networkd detected reloads. TMPFS gives us this property.
753 if (manager.getConfDir() == "/etc/systemd/network"sv)
754 {
755 auto dir = stdplus::strCat(netFile.native(), ".d");
756 dir.replace(1, 3, "run"); // Replace /etc with /run
757 auto file = dir + "/updated.conf";
758 try
759 {
760 std::filesystem::create_directories(dir);
761 using namespace stdplus::fd;
762 futimens(
763 open(file,
764 OpenFlags(OpenAccess::WriteOnly).set(OpenFlag::Create),
765 0644)
766 .get(),
767 nullptr);
768 }
769 catch (const std::exception& e)
770 {
771 lg2::error("Failed to write time updated file {FILE}: {ERROR}",
772 "FILE", file, "ERROR", e.what());
773 }
774 }
775}
776
Ratan Gupta2b106532017-07-25 16:05:02 +0530777void EthernetInterface::writeConfigurationFile()
778{
William A. Kennington III95a49a22022-08-18 17:50:05 -0700779 config::Parser config;
780 config.map["Match"].emplace_back()["Name"].emplace_back(interfaceName());
Ratan Gupta2b106532017-07-25 16:05:02 +0530781 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700782 auto& link = config.map["Link"].emplace_back();
Johnathan Mantey609c12d2022-02-03 09:23:09 -0800783#ifdef PERSIST_MAC
William A. Kennington III95a49a22022-08-18 17:50:05 -0700784 auto mac = MacAddressIntf::macAddress();
785 if (!mac.empty())
786 {
787 link["MACAddress"].emplace_back(mac);
788 }
Johnathan Mantey609c12d2022-02-03 09:23:09 -0800789#endif
William A. Kennington III95a49a22022-08-18 17:50:05 -0700790 if (!EthernetInterfaceIntf::nicEnabled())
791 {
Johnathan Mantey8e3c1fb2024-03-12 13:07:50 -0700792 link["ActivationPolicy"].emplace_back("down");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700793 }
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700794 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700795 {
796 auto& network = config.map["Network"].emplace_back();
797 auto& lla = network["LinkLocalAddressing"];
Oskar Senftad21fc22018-07-26 16:32:23 -0400798#ifdef LINK_LOCAL_AUTOCONFIGURATION
William A. Kennington III95a49a22022-08-18 17:50:05 -0700799 lla.emplace_back("yes");
Oskar Senftad21fc22018-07-26 16:32:23 -0400800#else
William A. Kennington III95a49a22022-08-18 17:50:05 -0700801 lla.emplace_back("no");
Oskar Senftad21fc22018-07-26 16:32:23 -0400802#endif
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700803 network["IPv6AcceptRA"].emplace_back(ipv6AcceptRA() ? "true" : "false");
804 network["DHCP"].emplace_back(dhcp4() ? (dhcp6() ? "true" : "ipv4")
805 : (dhcp6() ? "ipv6" : "false"));
Nagaraju Goruganti210420a2018-03-07 09:22:28 -0600806 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700807 auto& vlans = network["VLAN"];
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800808 for (const auto& [_, intf] : manager.get().interfaces)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700809 {
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700810 if (intf->vlan && intf->vlan->parentIdx == ifIdx)
811 {
812 vlans.emplace_back(intf->interfaceName());
813 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700814 }
815 }
816 {
817 auto& ntps = network["NTP"];
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600818 for (const auto& ntp : EthernetInterfaceIntf::staticNTPServers())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700819 {
820 ntps.emplace_back(ntp);
821 }
822 }
823 {
824 auto& dnss = network["DNS"];
825 for (const auto& dns : EthernetInterfaceIntf::staticNameServers())
826 {
827 dnss.emplace_back(dns);
828 }
829 }
830 {
831 auto& address = network["Address"];
William A. Kennington III59e5b912022-11-02 02:49:46 -0700832 for (const auto& addr : addrs)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700833 {
Johnathan Mantey3865db22023-09-27 12:39:16 -0700834 if (addr.second->origin() == IP::AddressOrigin::Static)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700835 {
William A. Kennington IIIcafc1512023-07-25 02:22:32 -0700836 address.emplace_back(stdplus::toStr(addr.first));
William A. Kennington III95a49a22022-08-18 17:50:05 -0700837 }
838 }
839 }
840 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700841 if (!dhcp4())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700842 {
Ravi Teja91f60562024-04-17 06:26:43 -0500843 auto gateway4 = EthernetInterfaceIntf::defaultGateway();
844 if (!gateway4.empty())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700845 {
Ravi Teja91f60562024-04-17 06:26:43 -0500846 auto& gateway4route = config.map["Route"].emplace_back();
847 gateway4route["Gateway"].emplace_back(gateway4);
848 gateway4route["GatewayOnLink"].emplace_back("true");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700849 }
850 }
Ratan Gupta2b106532017-07-25 16:05:02 +0530851
William A. Kennington III05cbc5b2023-07-20 19:37:30 -0700852 if (!ipv6AcceptRA())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700853 {
854 auto gateway6 = EthernetInterfaceIntf::defaultGateway6();
855 if (!gateway6.empty())
856 {
Ravi Teja91f60562024-04-17 06:26:43 -0500857 auto& gateway6route = config.map["Route"].emplace_back();
858 gateway6route["Gateway"].emplace_back(gateway6);
859 gateway6route["GatewayOnLink"].emplace_back("true");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700860 }
861 }
Nagaraju Goruganti210420a2018-03-07 09:22:28 -0600862 }
Johnathan Mantey817012a2020-01-30 15:07:39 -0800863 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700864 config.map["IPv6AcceptRA"].emplace_back()["DHCPv6Client"].emplace_back(
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700865 dhcp6() ? "true" : "false");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500866 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700867 auto& neighbors = config.map["Neighbor"];
868 for (const auto& sneighbor : staticNeighbors)
Lei YUcb2d4082021-08-12 15:26:49 +0800869 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700870 auto& neighbor = neighbors.emplace_back();
871 neighbor["Address"].emplace_back(sneighbor.second->ipAddress());
872 neighbor["MACAddress"].emplace_back(sneighbor.second->macAddress());
Lei YUcb2d4082021-08-12 15:26:49 +0800873 }
Ravi Tejaa5a09442020-07-17 00:57:33 -0500874 }
Ravi Tejaa5a09442020-07-17 00:57:33 -0500875 {
Jishnu CM57dfea92023-05-05 06:07:26 -0500876 auto& dhcp4 = config.map["DHCPv4"].emplace_back();
877 dhcp4["ClientIdentifier"].emplace_back("mac");
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700878 dhcp4["UseDNS"].emplace_back(tfStr(dhcp4Conf->dnsEnabled()));
879 dhcp4["UseDomains"].emplace_back(tfStr(dhcp4Conf->domainEnabled()));
880 dhcp4["UseNTP"].emplace_back(tfStr(dhcp4Conf->ntpEnabled()));
881 dhcp4["UseHostname"].emplace_back(tfStr(dhcp4Conf->hostNameEnabled()));
Jishnu CM57dfea92023-05-05 06:07:26 -0500882 dhcp4["SendHostname"].emplace_back(
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700883 tfStr(dhcp4Conf->sendHostNameEnabled()));
Jishnu CM57dfea92023-05-05 06:07:26 -0500884 }
885 {
886 auto& dhcp6 = config.map["DHCPv6"].emplace_back();
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700887 dhcp6["UseDNS"].emplace_back(tfStr(dhcp6Conf->dnsEnabled()));
888 dhcp6["UseDomains"].emplace_back(tfStr(dhcp6Conf->domainEnabled()));
889 dhcp6["UseNTP"].emplace_back(tfStr(dhcp6Conf->ntpEnabled()));
890 dhcp6["UseHostname"].emplace_back(tfStr(dhcp6Conf->hostNameEnabled()));
William A. Kennington III44937b12024-04-17 00:28:20 -0700891 dhcp6["SendHostname"].emplace_back(
892 tfStr(dhcp6Conf->sendHostNameEnabled()));
Ravi Tejaa5a09442020-07-17 00:57:33 -0500893 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500894
895 {
896 auto& sroutes = config.map["Route"];
897 for (const auto& temp : staticGateways)
898 {
899 auto& staticGateway = sroutes.emplace_back();
900 staticGateway["Gateway"].emplace_back(temp.second->gateway());
901 staticGateway["GatewayOnLink"].emplace_back("true");
902 }
903 }
904
Patrick Williamsad205022024-08-16 15:20:07 -0400905 auto path =
906 config::pathForIntfConf(manager.get().getConfDir(), interfaceName());
William A. Kennington III95a49a22022-08-18 17:50:05 -0700907 config.writeFile(path);
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700908 lg2::info("Wrote networkd file: {CFG_FILE}", "CFG_FILE", path);
William A. Kennington III945878a2024-04-17 01:05:27 -0700909 writeUpdatedTime(manager, path);
Ratan Gupta2b106532017-07-25 16:05:02 +0530910}
911
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800912std::string EthernetInterface::macAddress([[maybe_unused]] std::string value)
Ratan Guptabd303b12017-08-18 17:10:07 +0530913{
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700914 if (vlan)
915 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700916 lg2::error("Tried to set MAC address on VLAN");
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700917 elog<InternalFailure>();
918 }
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800919#ifdef PERSIST_MAC
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700920 stdplus::EtherAddr newMAC;
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600921 try
922 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700923 newMAC = stdplus::fromStr<stdplus::EtherAddr>(value);
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600924 }
kokilavf51a2c62024-12-12 02:18:34 -0600925 catch (const std::exception& e)
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600926 {
Milton D. Miller IIe0349902025-04-12 23:23:04 +0000927 lg2::error("Invalid MAC address {NET_MAC}: {ERROR}", "NET_MAC", value,
kokilavf51a2c62024-12-12 02:18:34 -0600928 "ERROR", e);
929 elog<InvalidArgument>(Argument::ARGUMENT_NAME("netmac"),
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600930 Argument::ARGUMENT_VALUE(value.c_str()));
931 }
kokilavf51a2c62024-12-12 02:18:34 -0600932
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700933 if (!newMAC.isUnicast())
Ratan Guptabd303b12017-08-18 17:10:07 +0530934 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700935 lg2::error("MAC Address {NET_MAC} is not valid", "NET_MAC", value);
Gunnar Mills90480c42018-06-19 16:02:17 -0500936 elog<InvalidArgument>(Argument::ARGUMENT_NAME("MACAddress"),
937 Argument::ARGUMENT_VALUE(value.c_str()));
Ratan Guptabd303b12017-08-18 17:10:07 +0530938 }
939
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300940 auto interface = interfaceName();
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700941 auto validMAC = stdplus::toStr(newMAC);
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300942
William A. Kennington III1137a972019-04-20 20:49:58 -0700943 // We don't need to update the system if the address is unchanged
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700944 auto oldMAC =
945 stdplus::fromStr<stdplus::EtherAddr>(MacAddressIntf::macAddress());
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700946 if (newMAC != oldMAC)
Ratan Guptabd303b12017-08-18 17:10:07 +0530947 {
William A. Kennington III1137a972019-04-20 20:49:58 -0700948 // Update everything that depends on the MAC value
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800949 for (const auto& [_, intf] : manager.get().interfaces)
Ratan Guptabd303b12017-08-18 17:10:07 +0530950 {
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700951 if (intf->vlan && intf->vlan->parentIdx == ifIdx)
952 {
953 intf->MacAddressIntf::macAddress(validMAC);
954 }
Ratan Guptabd303b12017-08-18 17:10:07 +0530955 }
Patrick Williams6aef7692021-05-01 06:39:41 -0500956 MacAddressIntf::macAddress(validMAC);
Ratan Guptabd303b12017-08-18 17:10:07 +0530957
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700958 writeConfigurationFile();
William A. Kennington III945878a2024-04-17 01:05:27 -0700959 manager.get().addReloadPreHook([interface, manager = manager]() {
William A. Kennington III6bfdf3e2021-11-09 17:15:12 -0800960 // The MAC and LLADDRs will only update if the NIC is already down
William A. Kennington III2e09d272022-10-14 17:15:00 -0700961 system::setNICUp(interface, false);
William A. Kennington III945878a2024-04-17 01:05:27 -0700962 writeUpdatedTime(
963 manager,
964 config::pathForIntfConf(manager.get().getConfDir(), interface));
William A. Kennington III6bfdf3e2021-11-09 17:15:12 -0800965 });
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800966 manager.get().reloadConfigs();
Ratan Gupta677ae122017-09-18 16:28:50 +0530967 }
William A. Kennington III1137a972019-04-20 20:49:58 -0700968
William A. Kennington III64f61262022-11-06 16:59:41 -0800969 std::error_code ec;
970 const auto fw_setenv = std::filesystem::path("/sbin/fw_setenv");
971 if (std::filesystem::exists(fw_setenv, ec))
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300972 {
William A. Kennington III64f61262022-11-06 16:59:41 -0800973 // Ensure that the valid address is stored in the u-boot-env
974 auto envVar = interfaceToUbootEthAddr(interface);
975 if (envVar)
976 {
977 execute(fw_setenv.native(), "fw_setenv", envVar->c_str(),
978 validMAC.c_str());
979 }
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300980 }
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300981
William A. Kennington III1137a972019-04-20 20:49:58 -0700982 return value;
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800983#else
984 elog<NotAllowed>(
985 NotAllowedArgument::REASON("Writing MAC address is not allowed"));
986#endif // PERSIST_MAC
Ratan Guptabd303b12017-08-18 17:10:07 +0530987}
988
Ratan Guptae9c9b812017-09-22 17:15:37 +0530989void EthernetInterface::deleteAll()
990{
Ratan Guptae9c9b812017-09-22 17:15:37 +0530991 // clear all the ip on the interface
992 addrs.clear();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700993
994 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800995 manager.get().reloadConfigs();
Ratan Guptae9c9b812017-09-22 17:15:37 +0530996}
997
William A. Kennington IIId4ff7312023-02-03 14:19:17 -0800998template <typename Addr>
999static void normalizeGateway(std::string& gw)
Ravi Tejaa5a09442020-07-17 00:57:33 -05001000{
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001001 if (gw.empty())
1002 {
1003 return;
1004 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001005 try
Ravi Tejaa5a09442020-07-17 00:57:33 -05001006 {
William A. Kennington III9ca5c8e2022-12-14 14:40:52 -08001007 auto ip = stdplus::fromStr<Addr>(gw);
1008 if (ip == Addr{})
1009 {
1010 gw.clear();
1011 return;
1012 }
William A. Kennington IIIbbf5e9e2023-02-01 14:58:38 -08001013 if (!validIntfIP(ip))
1014 {
1015 throw std::invalid_argument("Invalid unicast");
1016 }
William A. Kennington III9ca5c8e2022-12-14 14:40:52 -08001017 gw = stdplus::toStr(ip);
Ravi Tejaa5a09442020-07-17 00:57:33 -05001018 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001019 catch (const std::exception& e)
Ravi Tejaa5a09442020-07-17 00:57:33 -05001020 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001021 lg2::error("Invalid GW `{NET_GW}`: {ERROR}", "NET_GW", gw, "ERROR", e);
Ravi Tejaa5a09442020-07-17 00:57:33 -05001022 elog<InvalidArgument>(Argument::ARGUMENT_NAME("GATEWAY"),
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001023 Argument::ARGUMENT_VALUE(gw.c_str()));
Ravi Tejaa5a09442020-07-17 00:57:33 -05001024 }
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001025}
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001026
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001027std::string EthernetInterface::defaultGateway(std::string gateway)
1028{
1029 normalizeGateway<stdplus::In4Addr>(gateway);
1030 if (gateway != defaultGateway())
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001031 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001032 gateway = EthernetInterfaceIntf::defaultGateway(std::move(gateway));
Yuxiao Zhangaf38fe92023-10-12 13:50:50 -07001033 writeConfigurationFile();
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001034 manager.get().reloadConfigs();
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001035 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001036 return gateway;
Ravi Tejaa5a09442020-07-17 00:57:33 -05001037}
1038
1039std::string EthernetInterface::defaultGateway6(std::string gateway)
1040{
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001041 normalizeGateway<stdplus::In6Addr>(gateway);
1042 if (gateway != defaultGateway6())
Ravi Tejaa5a09442020-07-17 00:57:33 -05001043 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001044 gateway = EthernetInterfaceIntf::defaultGateway6(std::move(gateway));
Yuxiao Zhangaf38fe92023-10-12 13:50:50 -07001045 writeConfigurationFile();
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001046 manager.get().reloadConfigs();
Ravi Tejaa5a09442020-07-17 00:57:33 -05001047 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001048 return gateway;
Ravi Tejaa5a09442020-07-17 00:57:33 -05001049}
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001050
1051EthernetInterface::VlanProperties::VlanProperties(
1052 sdbusplus::bus_t& bus, stdplus::const_zstring objPath,
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001053 const InterfaceInfo& info, stdplus::PinnedRef<EthernetInterface> eth) :
William A. Kennington IIIb6452542022-11-15 18:09:12 -08001054 VlanIfaces(bus, objPath.c_str(), VlanIfaces::action::defer_emit),
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001055 parentIdx(*info.parent_idx), eth(eth)
1056{
William A. Kennington IIId99e6db2022-11-15 20:39:45 -08001057 VlanIntf::id(*info.vlan_id, true);
1058 emit_object_added();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001059}
1060
1061void EthernetInterface::VlanProperties::delete_()
1062{
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001063 auto intf = eth.get().interfaceName();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001064
1065 // Remove all configs for the current interface
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001066 const auto& confDir = eth.get().manager.get().getConfDir();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001067 std::error_code ec;
1068 std::filesystem::remove(config::pathForIntfConf(confDir, intf), ec);
1069 std::filesystem::remove(config::pathForIntfDev(confDir, intf), ec);
1070
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001071 if (eth.get().ifIdx > 0)
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001072 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001073 eth.get().manager.get().interfacesByIdx.erase(eth.get().ifIdx);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001074 }
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001075 auto it = eth.get().manager.get().interfaces.find(intf);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001076 auto obj = std::move(it->second);
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001077 eth.get().manager.get().interfaces.erase(it);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001078
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001079 // Write an updated parent interface since it has a VLAN entry
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001080 for (const auto& [_, intf] : eth.get().manager.get().interfaces)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001081 {
1082 if (intf->ifIdx == parentIdx)
1083 {
1084 intf->writeConfigurationFile();
1085 }
1086 }
1087
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001088 if (eth.get().ifIdx > 0)
William A. Kennington III67b09da2022-10-31 14:09:53 -07001089 {
William A. Kennington III6d217512022-11-17 16:18:01 -08001090 // We need to forcibly delete the interface as systemd does not
Patrick Williamsad205022024-08-16 15:20:07 -04001091 eth.get().manager.get().addReloadPostHook([idx = eth.get().ifIdx]() {
1092 system::deleteIntf(idx);
1093 });
William A. Kennington III6d217512022-11-17 16:18:01 -08001094
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001095 // Ignore the interface so the reload doesn't re-query it
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001096 eth.get().manager.get().ignoredIntf.emplace(eth.get().ifIdx);
William A. Kennington III67b09da2022-10-31 14:09:53 -07001097 }
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001098
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001099 eth.get().manager.get().reloadConfigs();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001100}
1101
Ravi Tejaf7116de2024-12-08 22:48:21 -06001102bool EthernetInterface::emitLLDP(bool value)
1103{
1104 if (emitLLDP() != EthernetInterfaceIntf::emitLLDP(value))
1105 {
1106 manager.get().writeLLDPDConfigurationFile();
1107 manager.get().reloadLLDPService();
1108 }
1109 return value;
1110}
1111
Jishnu CM57dfea92023-05-05 06:07:26 -05001112void EthernetInterface::reloadConfigs()
1113{
1114 manager.get().reloadConfigs();
1115}
1116
Gunnar Mills57d9c502018-09-14 14:42:34 -05001117} // namespace network
1118} // namespace phosphor