blob: 9919ceb03955bc7522c105596612bbd3afc08095 [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);
Ravi Teja970c7b62026-01-05 11:53:40 -0600168 EthernetInterfaceIntf::fullDuplex(ethInfo.fullDuplex, skipSignal);
William A. Kennington III21539662022-11-15 14:53:11 -0800169 }
William A. Kennington IIId298f932022-10-17 14:31:38 -0700170}
171
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800172void EthernetInterface::addAddr(const AddressInfo& info)
173{
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800174 IP::AddressOrigin origin = IP::AddressOrigin::Static;
Ravi Teja86c4f442023-07-19 22:26:39 -0500175 if (dhcpIsEnabled(info.ifaddr.getAddr()))
176 {
177 origin = IP::AddressOrigin::DHCP;
178 }
179
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800180#ifdef LINK_LOCAL_AUTOCONFIGURATION
181 if (info.scope == RT_SCOPE_LINK)
182 {
183 origin = IP::AddressOrigin::LinkLocal;
184 }
185#endif
186
Ravi Tejac6201202023-03-28 21:29:58 -0500187 if ((info.scope == RT_SCOPE_UNIVERSE) && (info.flags & IFA_F_PERMANENT))
188 {
189 origin = IP::AddressOrigin::Static;
190 }
191 if ((info.scope == RT_SCOPE_UNIVERSE) &&
192 ((info.flags & IFA_F_NOPREFIXROUTE) &&
193 (info.flags & IFA_F_MANAGETEMPADDR)))
194 {
195 origin = IP::AddressOrigin::SLAAC;
196 }
197 else if ((info.scope == RT_SCOPE_UNIVERSE) &&
198 ((info.flags & IFA_F_NOPREFIXROUTE)))
199 {
200 origin = IP::AddressOrigin::DHCP;
201 }
202
William A. Kennington III77747f62022-11-07 23:11:15 -0800203 auto it = addrs.find(info.ifaddr);
204 if (it == addrs.end())
205 {
206 addrs.emplace(info.ifaddr, std::make_unique<IPAddress>(
207 bus, std::string_view(objPath), *this,
208 info.ifaddr, origin));
209 }
210 else
211 {
212 it->second->IPIfaces::origin(origin);
213 }
William A. Kennington IIId6f53402022-11-07 14:48:53 -0800214}
215
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800216void EthernetInterface::addStaticNeigh(const NeighborInfo& info)
217{
William A. Kennington IIId3615142022-11-12 01:28:33 -0800218 if (!info.mac || !info.addr)
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800219 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700220 lg2::error("Missing neighbor mac on {NET_INTF}", "NET_INTF",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700221 interfaceName());
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800222 return;
223 }
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800224
225 if (auto it = staticNeighbors.find(*info.addr); it != staticNeighbors.end())
226 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700227 it->second->NeighborObj::macAddress(stdplus::toStr(*info.mac));
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800228 }
229 else
230 {
Patrick Williamsad205022024-08-16 15:20:07 -0400231 staticNeighbors.emplace(
232 *info.addr, std::make_unique<Neighbor>(
233 bus, std::string_view(objPath), *this, *info.addr,
234 *info.mac, Neighbor::State::Permanent));
William A. Kennington III4e75acc2022-11-14 19:13:31 -0800235 }
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -0800236}
237
Ravi Tejaab27a812023-05-02 10:01:53 -0500238void EthernetInterface::addStaticGateway(const StaticGatewayInfo& info)
239{
240 if (!info.gateway)
241 {
242 lg2::error("Missing static gateway on {NET_INTF}", "NET_INTF",
243 interfaceName());
244 return;
245 }
246
247 IP::Protocol protocolType;
248 if (*info.protocol == "IPv4")
249 {
250 protocolType = IP::Protocol::IPv4;
251 }
252 else if (*info.protocol == "IPv6")
253 {
254 protocolType = IP::Protocol::IPv6;
255 }
256
257 if (auto it = staticGateways.find(*info.gateway);
258 it != staticGateways.end())
259 {
260 it->second->StaticGatewayObj::gateway(*info.gateway);
261 }
262 else
263 {
264 staticGateways.emplace(*info.gateway,
265 std::make_unique<StaticGateway>(
266 bus, std::string_view(objPath), *this,
267 *info.gateway, protocolType));
268 }
269}
270
Patrick Williams6aef7692021-05-01 06:39:41 -0500271ObjectPath EthernetInterface::ip(IP::Protocol protType, std::string ipaddress,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -0700272 uint8_t prefixLength, std::string)
Ratan Gupta82549cc2017-04-21 08:45:23 +0530273{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700274 std::optional<stdplus::InAnyAddr> addr;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700275 try
Ratan Guptafc2c7242017-05-29 08:46:06 +0530276 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700277 switch (protType)
278 {
279 case IP::Protocol::IPv4:
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700280 addr.emplace(stdplus::fromStr<stdplus::In4Addr>(ipaddress));
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700281 break;
282 case IP::Protocol::IPv6:
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700283 addr.emplace(stdplus::fromStr<stdplus::In6Addr>(ipaddress));
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700284 break;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700285 default:
286 throw std::logic_error("Exhausted protocols");
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700287 }
William A. Kennington III30f3ba22023-06-28 15:50:12 -0700288 if (!std::visit([](auto ip) { return validIntfIP(ip); }, *addr))
289 {
290 throw std::invalid_argument("not unicast");
291 }
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500292 }
William A. Kennington III59e5b912022-11-02 02:49:46 -0700293 catch (const std::exception& e)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500294 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700295 lg2::error("Invalid IP {NET_IP}: {ERROR}", "NET_IP", ipaddress, "ERROR",
296 e);
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500297 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"),
298 Argument::ARGUMENT_VALUE(ipaddress.c_str()));
299 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700300 std::optional<stdplus::SubnetAny> ifaddr;
William A. Kennington III59e5b912022-11-02 02:49:46 -0700301 try
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500302 {
William A. Kennington III30f3ba22023-06-28 15:50:12 -0700303 if (prefixLength == 0)
304 {
305 throw std::invalid_argument("default route");
306 }
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700307 ifaddr.emplace(*addr, prefixLength);
William A. Kennington III59e5b912022-11-02 02:49:46 -0700308 }
309 catch (const std::exception& e)
310 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700311 lg2::error("Invalid prefix length {NET_PFX}: {ERROR}", "NET_PFX",
312 prefixLength, "ERROR", e);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500313 elog<InvalidArgument>(
314 Argument::ARGUMENT_NAME("prefixLength"),
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700315 Argument::ARGUMENT_VALUE(stdplus::toStr(prefixLength).c_str()));
Ratan Guptafc2c7242017-05-29 08:46:06 +0530316 }
317
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700318 auto it = addrs.find(*ifaddr);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800319 if (it == addrs.end())
320 {
321 it = std::get<0>(addrs.emplace(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700322 *ifaddr,
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800323 std::make_unique<IPAddress>(bus, std::string_view(objPath), *this,
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700324 *ifaddr, IP::AddressOrigin::Static)));
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800325 }
326 else
327 {
William A. Kennington IIIadd08712022-11-17 16:31:19 -0800328 if (it->second->origin() == IP::AddressOrigin::Static)
329 {
330 return it->second->getObjPath();
331 }
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800332 it->second->IPIfaces::origin(IP::AddressOrigin::Static);
333 }
Ratan Gupta4f1c18b2017-05-25 12:59:35 +0530334
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700335 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800336 manager.get().reloadConfigs();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700337
William A. Kennington III434a9432022-11-04 18:38:46 -0700338 return it->second->getObjPath();
Ratan Gupta82549cc2017-04-21 08:45:23 +0530339}
340
Patrick Williams6aef7692021-05-01 06:39:41 -0500341ObjectPath EthernetInterface::neighbor(std::string ipAddress,
342 std::string macAddress)
William A. Kennington III08505792019-01-30 16:00:04 -0800343{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700344 std::optional<stdplus::InAnyAddr> addr;
William A. Kennington III434a9432022-11-04 18:38:46 -0700345 try
William A. Kennington III08505792019-01-30 16:00:04 -0800346 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700347 addr.emplace(stdplus::fromStr<stdplus::InAnyAddr>(ipAddress));
William A. Kennington III434a9432022-11-04 18:38:46 -0700348 }
349 catch (const std::exception& e)
350 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700351 lg2::error("Not a valid IP address {NET_IP}: {ERROR}", "NET_IP",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700352 ipAddress, "ERROR", e);
Patrick Williams6aef7692021-05-01 06:39:41 -0500353 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipAddress"),
354 Argument::ARGUMENT_VALUE(ipAddress.c_str()));
William A. Kennington III08505792019-01-30 16:00:04 -0800355 }
William A. Kennington III434a9432022-11-04 18:38:46 -0700356
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700357 std::optional<stdplus::EtherAddr> lladdr;
William A. Kennington III434a9432022-11-04 18:38:46 -0700358 try
William A. Kennington III08505792019-01-30 16:00:04 -0800359 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700360 lladdr.emplace(stdplus::fromStr<stdplus::EtherAddr>(macAddress));
William A. Kennington III434a9432022-11-04 18:38:46 -0700361 }
362 catch (const std::exception& e)
363 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700364 lg2::error("Not a valid MAC address {NET_MAC}: {ERROR}", "NET_MAC",
365 macAddress, "ERROR", e);
Patrick Williams6aef7692021-05-01 06:39:41 -0500366 elog<InvalidArgument>(Argument::ARGUMENT_NAME("macAddress"),
367 Argument::ARGUMENT_VALUE(macAddress.c_str()));
William A. Kennington III08505792019-01-30 16:00:04 -0800368 }
369
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700370 auto it = staticNeighbors.find(*addr);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800371 if (it == staticNeighbors.end())
372 {
373 it = std::get<0>(staticNeighbors.emplace(
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700374 *addr, std::make_unique<Neighbor>(bus, std::string_view(objPath),
375 *this, *addr, *lladdr,
376 Neighbor::State::Permanent)));
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800377 }
378 else
379 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700380 auto str = stdplus::toStr(*lladdr);
William A. Kennington IIIadd08712022-11-17 16:31:19 -0800381 if (it->second->macAddress() == str)
382 {
383 return it->second->getObjPath();
384 }
385 it->second->NeighborObj::macAddress(str);
William A. Kennington IIIa429c9d2022-11-15 18:00:45 -0800386 }
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700387
388 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800389 manager.get().reloadConfigs();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700390
William A. Kennington III434a9432022-11-04 18:38:46 -0700391 return it->second->getObjPath();
William A. Kennington III08505792019-01-30 16:00:04 -0800392}
393
Ravi Tejaab27a812023-05-02 10:01:53 -0500394ObjectPath EthernetInterface::staticGateway(std::string gateway,
395 IP::Protocol protocolType)
396{
397 std::optional<stdplus::InAnyAddr> addr;
398 std::string route;
399 try
400 {
kokilav0779db72025-01-07 10:21:51 -0600401 switch (protocolType)
402 {
403 case IP::Protocol::IPv4:
404 addr.emplace(stdplus::fromStr<stdplus::In4Addr>(gateway));
405 break;
406 case IP::Protocol::IPv6:
407 addr.emplace(stdplus::fromStr<stdplus::In6Addr>(gateway));
408 break;
409 default:
410 throw std::logic_error("Exhausted protocols");
411 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500412 route = gateway;
413 }
414 catch (const std::exception& e)
415 {
416 lg2::error("Not a valid IP address {GATEWAY}: {ERROR}", "GATEWAY",
417 gateway, "ERROR", e);
418 elog<InvalidArgument>(Argument::ARGUMENT_NAME("gateway"),
419 Argument::ARGUMENT_VALUE(gateway.c_str()));
420 }
421
422 auto it = staticGateways.find(route);
423 if (it == staticGateways.end())
424 {
425 it = std::get<0>(staticGateways.emplace(
426 route,
427 std::make_unique<StaticGateway>(bus, std::string_view(objPath),
428 *this, gateway, protocolType)));
429 }
430 else
431 {
432 it->second->StaticGatewayObj::gateway(gateway);
433 }
434
435 writeConfigurationFile();
436 manager.get().reloadConfigs();
437
438 return it->second->getObjPath();
439}
440
Patrick Williams6aef7692021-05-01 06:39:41 -0500441bool EthernetInterface::ipv6AcceptRA(bool value)
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700442{
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700443 if (ipv6AcceptRA() != EthernetInterfaceIntf::ipv6AcceptRA(value))
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700444 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700445 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800446 manager.get().reloadConfigs();
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700447 }
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700448 return value;
449}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700450
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700451bool EthernetInterface::dhcp4(bool value)
452{
453 if (dhcp4() != EthernetInterfaceIntf::dhcp4(value))
454 {
455 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800456 manager.get().reloadConfigs();
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700457 }
458 return value;
459}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700460
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700461bool EthernetInterface::dhcp6(bool value)
462{
463 if (dhcp6() != EthernetInterfaceIntf::dhcp6(value))
464 {
465 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800466 manager.get().reloadConfigs();
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700467 }
Johnathan Mantey5b023f52019-06-24 16:06:37 -0700468 return value;
469}
470
Patrick Williams6aef7692021-05-01 06:39:41 -0500471EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled(DHCPConf value)
Ratan Gupta87c13982017-06-15 09:27:27 +0530472{
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700473 auto old4 = EthernetInterfaceIntf::dhcp4();
Patrick Williamsad205022024-08-16 15:20:07 -0400474 auto new4 = EthernetInterfaceIntf::dhcp4(
475 value == DHCPConf::v4 || value == DHCPConf::v4v6stateless ||
476 value == DHCPConf::both);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700477 auto old6 = EthernetInterfaceIntf::dhcp6();
Patrick Williamsad205022024-08-16 15:20:07 -0400478 auto new6 = EthernetInterfaceIntf::dhcp6(
479 value == DHCPConf::v6 || value == DHCPConf::both);
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700480 auto oldra = EthernetInterfaceIntf::ipv6AcceptRA();
481 auto newra = EthernetInterfaceIntf::ipv6AcceptRA(
482 value == DHCPConf::v6stateless || value == DHCPConf::v4v6stateless ||
483 value == DHCPConf::v6 || value == DHCPConf::both);
484
485 if (old4 != new4 || old6 != new6 || oldra != newra)
Ratan Gupta5978dd12017-07-25 13:47:13 +0530486 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700487 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800488 manager.get().reloadConfigs();
Ratan Gupta5978dd12017-07-25 13:47:13 +0530489 }
Ratan Gupta87c13982017-06-15 09:27:27 +0530490 return value;
491}
492
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700493EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled() const
494{
495 if (dhcp6())
496 {
497 return dhcp4() ? DHCPConf::both : DHCPConf::v6;
498 }
499 else if (dhcp4())
500 {
501 return ipv6AcceptRA() ? DHCPConf::v4v6stateless : DHCPConf::v4;
502 }
503 return ipv6AcceptRA() ? DHCPConf::v6stateless : DHCPConf::none;
504}
505
Tejas Patil2c0fc562021-08-03 19:13:46 +0530506size_t EthernetInterface::mtu(size_t value)
507{
William A. Kennington III2e09d272022-10-14 17:15:00 -0700508 const size_t old = EthernetInterfaceIntf::mtu();
509 if (value == old)
Tejas Patil2c0fc562021-08-03 19:13:46 +0530510 {
511 return value;
512 }
William A. Kennington III2e09d272022-10-14 17:15:00 -0700513 const auto ifname = interfaceName();
William A. Kennington III3e471c52022-10-27 19:46:07 -0700514 return EthernetInterfaceIntf::mtu(ignoreError("SetMTU", ifname, old, [&] {
William A. Kennington III2e09d272022-10-14 17:15:00 -0700515 system::setMTU(ifname, value);
516 return value;
517 }));
Tejas Patil2c0fc562021-08-03 19:13:46 +0530518}
519
Patrick Williams6aef7692021-05-01 06:39:41 -0500520bool EthernetInterface::nicEnabled(bool value)
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700521{
Patrick Williams6aef7692021-05-01 06:39:41 -0500522 if (value == EthernetInterfaceIntf::nicEnabled())
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700523 {
524 return value;
525 }
526
William A. Kennington IIIc922d5e2022-01-21 01:08:31 -0800527 EthernetInterfaceIntf::nicEnabled(value);
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700528 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800529 manager.get().reloadConfigs();
Johnathan Manteyfaa72e52020-01-08 10:38:58 -0800530
531 return value;
532}
533
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530534ServerList EthernetInterface::staticNameServers(ServerList value)
535{
nitinkotania581cb0b2023-03-21 00:28:55 -0500536 std::vector<std::string> dnsUniqueValues;
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700537 for (auto& ip : value)
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530538 {
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700539 try
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530540 {
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700541 ip = stdplus::toStr(stdplus::fromStr<stdplus::InAnyAddr>(ip));
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700542 }
543 catch (const std::exception& e)
544 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700545 lg2::error("Not a valid IP address {NET_IP}: {ERROR}", "NET_IP", ip,
546 "ERROR", e);
William A. Kennington IIIc9f672e2022-11-04 14:35:53 -0700547 elog<InvalidArgument>(Argument::ARGUMENT_NAME("StaticNameserver"),
548 Argument::ARGUMENT_VALUE(ip.c_str()));
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530549 }
nitinkotania581cb0b2023-03-21 00:28:55 -0500550 if (std::find(dnsUniqueValues.begin(), dnsUniqueValues.end(), ip) ==
551 dnsUniqueValues.end())
552 {
553 dnsUniqueValues.push_back(ip);
554 }
Manojkiran Eda5fb6c332019-08-21 16:37:29 +0530555 }
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700556
nitinkotania581cb0b2023-03-21 00:28:55 -0500557 value =
558 EthernetInterfaceIntf::staticNameServers(std::move(dnsUniqueValues));
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700559
560 writeConfigurationFile();
561 manager.get().reloadConfigs();
562
563 return value;
Ratan Gupta6dec3902017-08-20 15:28:12 +0530564}
565
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600566void EthernetInterface::loadNTPServers(const config::Parser& config)
567{
Jishnu CM4fe86132024-09-15 12:02:56 -0500568 ServerList ntpServerList = getNTPServerFromTimeSyncd();
569 ServerList staticNTPServers = config.map.getValueStrings("Network", "NTP");
570
571 std::unordered_set<std::string> staticNTPServersSet(
572 staticNTPServers.begin(), staticNTPServers.end());
573 ServerList networkSuppliedServers;
574
575 std::copy_if(ntpServerList.begin(), ntpServerList.end(),
576 std::back_inserter(networkSuppliedServers),
577 [&staticNTPServersSet](const std::string& server) {
578 return staticNTPServersSet.find(server) ==
579 staticNTPServersSet.end();
580 });
581
582 EthernetInterfaceIntf::ntpServers(networkSuppliedServers);
583 EthernetInterfaceIntf::staticNTPServers(staticNTPServers);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600584}
585
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700586void EthernetInterface::loadNameServers(const config::Parser& config)
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530587{
588 EthernetInterfaceIntf::nameservers(getNameServerFromResolvd());
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700589 EthernetInterfaceIntf::staticNameServers(
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700590 config.map.getValueStrings("Network", "DNS"));
Ratan Gupta6dec3902017-08-20 15:28:12 +0530591}
592
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600593ServerList EthernetInterface::getNTPServerFromTimeSyncd()
594{
595 ServerList servers; // Variable to capture the NTP Server IPs
Patrick Williamsad205022024-08-16 15:20:07 -0400596 auto method =
597 bus.get().new_method_call(TIMESYNCD_SERVICE, TIMESYNCD_SERVICE_PATH,
598 PROPERTY_INTERFACE, METHOD_GET);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600599
600 method.append(TIMESYNCD_INTERFACE, "LinkNTPServers");
601
602 try
603 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800604 auto reply = bus.get().call(method);
Patrick Williams137d9442025-11-05 00:17:55 -0500605 auto response = reply.unpack<std::variant<ServerList>>();
606
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600607 servers = std::get<ServerList>(response);
608 }
609 catch (const sdbusplus::exception::SdBusError& e)
610 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700611 lg2::error("Failed to get NTP server information from "
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700612 "systemd-timesyncd: {ERROR}",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700613 "ERROR", e);
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600614 }
615
616 return servers;
617}
618
Ravi Teja4f8b9a02023-09-06 13:41:52 -0500619ServerList EthernetInterface::nameservers() const
620{
621 return getNameServerFromResolvd();
622}
623
624ServerList EthernetInterface::getNameServerFromResolvd() const
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530625{
626 ServerList servers;
William A. Kennington IIIcafc1512023-07-25 02:22:32 -0700627 auto OBJ_PATH = std::format("{}{}", RESOLVED_SERVICE_PATH, ifIdx);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530628
629 /*
630 The DNS property under org.freedesktop.resolve1.Link interface contains
631 an array containing all DNS servers currently used by resolved. It
632 contains similar information as the DNS server data written to
633 /run/systemd/resolve/resolv.conf.
634
635 Each structure in the array consists of a numeric network interface index,
636 an address family, and a byte array containing the DNS server address
637 (either 4 bytes in length for IPv4 or 16 bytes in lengths for IPv6).
638 The array contains DNS servers configured system-wide, including those
639 possibly read from a foreign /etc/resolv.conf or the DNS= setting in
640 /etc/systemd/resolved.conf, as well as per-interface DNS server
641 information either retrieved from systemd-networkd or configured by
642 external software via SetLinkDNS().
643 */
644
645 using type = std::vector<std::tuple<int32_t, std::vector<uint8_t>>>;
646 std::variant<type> name; // Variable to capture the DNS property
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800647 auto method = bus.get().new_method_call(RESOLVED_SERVICE, OBJ_PATH.c_str(),
648 PROPERTY_INTERFACE, METHOD_GET);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530649
650 method.append(RESOLVED_INTERFACE, "DNS");
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530651
652 try
653 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800654 auto reply = bus.get().call(method);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530655 reply.read(name);
656 }
Patrick Williamsc38b0712022-07-22 19:26:54 -0500657 catch (const sdbusplus::exception_t& e)
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530658 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700659 lg2::error(
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700660 "Failed to get DNS information from systemd-resolved: {ERROR}",
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700661 "ERROR", e);
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530662 }
663 auto tupleVector = std::get_if<type>(&name);
664 for (auto i = tupleVector->begin(); i != tupleVector->end(); ++i)
665 {
Alexander Filippov983da552021-02-08 15:26:54 +0300666 int addressFamily = std::get<0>(*i);
667 std::vector<uint8_t>& ipaddress = std::get<1>(*i);
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700668 servers.push_back(stdplus::toStr(
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700669 addrFromBuf(addressFamily, stdplus::raw::asView<char>(ipaddress))));
Manojkiran Edaacd6dd52019-10-15 15:00:51 +0530670 }
671 return servers;
672}
673
William A. Kennington IIId298f932022-10-17 14:31:38 -0700674ObjectPath EthernetInterface::createVLAN(uint16_t id)
Ratan Gupta5978dd12017-07-25 13:47:13 +0530675{
William A. Kennington III9b2a20d2023-06-17 14:05:48 -0700676 auto idStr = stdplus::toStr(id);
William A. Kennington III86642522023-07-24 17:55:55 -0700677 auto intfName = stdplus::strCat(interfaceName(), "."sv, idStr);
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800678 if (manager.get().interfaces.find(intfName) !=
679 manager.get().interfaces.end())
Jiaqing Zhao33b4eaa2022-04-12 23:11:40 +0800680 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700681 lg2::error("VLAN {NET_VLAN} already exists", "NET_VLAN", id);
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700682 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VLANId"),
683 Argument::ARGUMENT_VALUE(idStr.c_str()));
Jiaqing Zhao33b4eaa2022-04-12 23:11:40 +0800684 }
685
William A. Kennington IIId298f932022-10-17 14:31:38 -0700686 auto objRoot = std::string_view(objPath).substr(0, objPath.rfind('/'));
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700687 auto macStr = MacAddressIntf::macAddress();
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700688 std::optional<stdplus::EtherAddr> mac;
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700689 if (!macStr.empty())
690 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700691 mac.emplace(stdplus::fromStr<stdplus::EtherAddr>(macStr));
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700692 }
William A. Kennington III13d665c2022-11-15 20:34:40 -0800693 auto info = AllIntfInfo{InterfaceInfo{
William A. Kennington III9c441fd2023-02-24 13:40:01 -0800694 .type = ARPHRD_ETHER,
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700695 .idx = 0, // TODO: Query the correct value after creation
696 .flags = 0,
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700697 .name = intfName,
William A. Kennington IIIfd862be2022-10-09 18:40:55 -0700698 .mac = std::move(mac),
699 .mtu = mtu(),
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700700 .parent_idx = ifIdx,
701 .vlan_id = id,
William A. Kennington III13d665c2022-11-15 20:34:40 -0800702 }};
Ratan Gupta5978dd12017-07-25 13:47:13 +0530703
Patrick Williams6aef7692021-05-01 06:39:41 -0500704 // Pass the parents nicEnabled property, so that the child
Manojkiran Edaca8b91b2020-05-28 09:28:42 +0530705 // VLAN interface can inherit.
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700706 auto vlanIntf = std::make_unique<EthernetInterface>(
William A. Kennington IIIb6452542022-11-15 18:09:12 -0800707 bus, manager, info, objRoot, config::Parser(), nicEnabled());
William A. Kennington IIId298f932022-10-17 14:31:38 -0700708 ObjectPath ret = vlanIntf->objPath;
Ratan Gupta5978dd12017-07-25 13:47:13 +0530709
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800710 manager.get().interfaces.emplace(intfName, std::move(vlanIntf));
Ratan Gupta5978dd12017-07-25 13:47:13 +0530711
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700712 // write the device file for the vlan interface.
713 config::Parser config;
714 auto& netdev = config.map["NetDev"].emplace_back();
715 netdev["Name"].emplace_back(intfName);
716 netdev["Kind"].emplace_back("vlan");
717 config.map["VLAN"].emplace_back()["Id"].emplace_back(std::move(idStr));
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800718 config.writeFile(
719 config::pathForIntfDev(manager.get().getConfDir(), intfName));
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700720
721 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800722 manager.get().reloadConfigs();
William A. Kennington IIIf4b4ff82019-04-09 19:06:52 -0700723
William A. Kennington III7b90bc82022-11-17 14:55:12 -0800724 return ret;
Ratan Gupta5978dd12017-07-25 13:47:13 +0530725}
Ratan Gupta2b106532017-07-25 16:05:02 +0530726
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600727ServerList EthernetInterface::staticNTPServers(ServerList value)
Ratan Gupta497c0c92017-08-22 19:15:59 +0530728{
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700729 value = EthernetInterfaceIntf::staticNTPServers(std::move(value));
Ratan Gupta497c0c92017-08-22 19:15:59 +0530730
William A. Kennington IIIa7485302023-05-30 16:57:57 -0700731 writeConfigurationFile();
732 manager.get().reloadConfigs();
733
734 return value;
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600735}
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700736
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600737ServerList EthernetInterface::ntpServers(ServerList /*servers*/)
738{
739 elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property"));
Ratan Gupta497c0c92017-08-22 19:15:59 +0530740}
Ratan Gupta2b106532017-07-25 16:05:02 +0530741
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700742static constexpr std::string_view tfStr(bool value)
743{
744 return value ? "true"sv : "false"sv;
745}
746
William A. Kennington III945878a2024-04-17 01:05:27 -0700747static void writeUpdatedTime(const Manager& manager,
748 const std::filesystem::path& netFile)
749{
750 // JFFS2 doesn't have the time granularity to deal with sub-second
751 // updates. Since we can have multiple file updates within a second
752 // around a reload, we need a location which gives that precision for
753 // future networkd detected reloads. TMPFS gives us this property.
754 if (manager.getConfDir() == "/etc/systemd/network"sv)
755 {
756 auto dir = stdplus::strCat(netFile.native(), ".d");
757 dir.replace(1, 3, "run"); // Replace /etc with /run
758 auto file = dir + "/updated.conf";
759 try
760 {
761 std::filesystem::create_directories(dir);
762 using namespace stdplus::fd;
763 futimens(
764 open(file,
765 OpenFlags(OpenAccess::WriteOnly).set(OpenFlag::Create),
766 0644)
767 .get(),
768 nullptr);
769 }
770 catch (const std::exception& e)
771 {
772 lg2::error("Failed to write time updated file {FILE}: {ERROR}",
773 "FILE", file, "ERROR", e.what());
774 }
775 }
776}
777
Ratan Gupta2b106532017-07-25 16:05:02 +0530778void EthernetInterface::writeConfigurationFile()
779{
William A. Kennington III95a49a22022-08-18 17:50:05 -0700780 config::Parser config;
781 config.map["Match"].emplace_back()["Name"].emplace_back(interfaceName());
Ratan Gupta2b106532017-07-25 16:05:02 +0530782 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700783 auto& link = config.map["Link"].emplace_back();
Johnathan Mantey609c12d2022-02-03 09:23:09 -0800784#ifdef PERSIST_MAC
William A. Kennington III95a49a22022-08-18 17:50:05 -0700785 auto mac = MacAddressIntf::macAddress();
786 if (!mac.empty())
787 {
788 link["MACAddress"].emplace_back(mac);
789 }
Johnathan Mantey609c12d2022-02-03 09:23:09 -0800790#endif
William A. Kennington III95a49a22022-08-18 17:50:05 -0700791 if (!EthernetInterfaceIntf::nicEnabled())
792 {
Johnathan Mantey8e3c1fb2024-03-12 13:07:50 -0700793 link["ActivationPolicy"].emplace_back("down");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700794 }
Johnathan Manteyd0679f92019-10-29 16:20:28 -0700795 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700796 {
797 auto& network = config.map["Network"].emplace_back();
798 auto& lla = network["LinkLocalAddressing"];
Oskar Senftad21fc22018-07-26 16:32:23 -0400799#ifdef LINK_LOCAL_AUTOCONFIGURATION
William A. Kennington III95a49a22022-08-18 17:50:05 -0700800 lla.emplace_back("yes");
Oskar Senftad21fc22018-07-26 16:32:23 -0400801#else
William A. Kennington III95a49a22022-08-18 17:50:05 -0700802 lla.emplace_back("no");
Oskar Senftad21fc22018-07-26 16:32:23 -0400803#endif
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700804 network["IPv6AcceptRA"].emplace_back(ipv6AcceptRA() ? "true" : "false");
805 network["DHCP"].emplace_back(dhcp4() ? (dhcp6() ? "true" : "ipv4")
806 : (dhcp6() ? "ipv6" : "false"));
Nagaraju Goruganti210420a2018-03-07 09:22:28 -0600807 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700808 auto& vlans = network["VLAN"];
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800809 for (const auto& [_, intf] : manager.get().interfaces)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700810 {
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700811 if (intf->vlan && intf->vlan->parentIdx == ifIdx)
812 {
813 vlans.emplace_back(intf->interfaceName());
814 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700815 }
816 }
817 {
818 auto& ntps = network["NTP"];
Asmitha Karunanithi003b8b72022-01-06 04:17:59 -0600819 for (const auto& ntp : EthernetInterfaceIntf::staticNTPServers())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700820 {
821 ntps.emplace_back(ntp);
822 }
823 }
824 {
825 auto& dnss = network["DNS"];
826 for (const auto& dns : EthernetInterfaceIntf::staticNameServers())
827 {
828 dnss.emplace_back(dns);
829 }
830 }
831 {
832 auto& address = network["Address"];
William A. Kennington III59e5b912022-11-02 02:49:46 -0700833 for (const auto& addr : addrs)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700834 {
Johnathan Mantey3865db22023-09-27 12:39:16 -0700835 if (addr.second->origin() == IP::AddressOrigin::Static)
William A. Kennington III95a49a22022-08-18 17:50:05 -0700836 {
William A. Kennington IIIcafc1512023-07-25 02:22:32 -0700837 address.emplace_back(stdplus::toStr(addr.first));
William A. Kennington III95a49a22022-08-18 17:50:05 -0700838 }
839 }
840 }
841 {
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700842 if (!dhcp4())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700843 {
Ravi Teja91f60562024-04-17 06:26:43 -0500844 auto gateway4 = EthernetInterfaceIntf::defaultGateway();
845 if (!gateway4.empty())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700846 {
Ravi Teja91f60562024-04-17 06:26:43 -0500847 auto& gateway4route = config.map["Route"].emplace_back();
848 gateway4route["Gateway"].emplace_back(gateway4);
849 gateway4route["GatewayOnLink"].emplace_back("true");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700850 }
851 }
Ratan Gupta2b106532017-07-25 16:05:02 +0530852
William A. Kennington III05cbc5b2023-07-20 19:37:30 -0700853 if (!ipv6AcceptRA())
William A. Kennington III95a49a22022-08-18 17:50:05 -0700854 {
855 auto gateway6 = EthernetInterfaceIntf::defaultGateway6();
856 if (!gateway6.empty())
857 {
Ravi Teja91f60562024-04-17 06:26:43 -0500858 auto& gateway6route = config.map["Route"].emplace_back();
859 gateway6route["Gateway"].emplace_back(gateway6);
860 gateway6route["GatewayOnLink"].emplace_back("true");
William A. Kennington III95a49a22022-08-18 17:50:05 -0700861 }
862 }
Nagaraju Goruganti210420a2018-03-07 09:22:28 -0600863 }
Johnathan Mantey817012a2020-01-30 15:07:39 -0800864 }
William A. Kennington III95a49a22022-08-18 17:50:05 -0700865 config.map["IPv6AcceptRA"].emplace_back()["DHCPv6Client"].emplace_back(
William A. Kennington III8060c0d2022-08-18 19:19:34 -0700866 dhcp6() ? "true" : "false");
Ravi Tejaa5a09442020-07-17 00:57:33 -0500867 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700868 auto& neighbors = config.map["Neighbor"];
869 for (const auto& sneighbor : staticNeighbors)
Lei YUcb2d4082021-08-12 15:26:49 +0800870 {
William A. Kennington III95a49a22022-08-18 17:50:05 -0700871 auto& neighbor = neighbors.emplace_back();
872 neighbor["Address"].emplace_back(sneighbor.second->ipAddress());
873 neighbor["MACAddress"].emplace_back(sneighbor.second->macAddress());
Lei YUcb2d4082021-08-12 15:26:49 +0800874 }
Ravi Tejaa5a09442020-07-17 00:57:33 -0500875 }
Ravi Tejaa5a09442020-07-17 00:57:33 -0500876 {
Jishnu CM57dfea92023-05-05 06:07:26 -0500877 auto& dhcp4 = config.map["DHCPv4"].emplace_back();
878 dhcp4["ClientIdentifier"].emplace_back("mac");
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700879 dhcp4["UseDNS"].emplace_back(tfStr(dhcp4Conf->dnsEnabled()));
880 dhcp4["UseDomains"].emplace_back(tfStr(dhcp4Conf->domainEnabled()));
881 dhcp4["UseNTP"].emplace_back(tfStr(dhcp4Conf->ntpEnabled()));
882 dhcp4["UseHostname"].emplace_back(tfStr(dhcp4Conf->hostNameEnabled()));
Jishnu CM57dfea92023-05-05 06:07:26 -0500883 dhcp4["SendHostname"].emplace_back(
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700884 tfStr(dhcp4Conf->sendHostNameEnabled()));
Jishnu CM57dfea92023-05-05 06:07:26 -0500885 }
886 {
887 auto& dhcp6 = config.map["DHCPv6"].emplace_back();
William A. Kennington IIIf179e702024-04-17 00:50:28 -0700888 dhcp6["UseDNS"].emplace_back(tfStr(dhcp6Conf->dnsEnabled()));
889 dhcp6["UseDomains"].emplace_back(tfStr(dhcp6Conf->domainEnabled()));
890 dhcp6["UseNTP"].emplace_back(tfStr(dhcp6Conf->ntpEnabled()));
891 dhcp6["UseHostname"].emplace_back(tfStr(dhcp6Conf->hostNameEnabled()));
William A. Kennington III44937b12024-04-17 00:28:20 -0700892 dhcp6["SendHostname"].emplace_back(
893 tfStr(dhcp6Conf->sendHostNameEnabled()));
Ravi Tejaa5a09442020-07-17 00:57:33 -0500894 }
Ravi Tejaab27a812023-05-02 10:01:53 -0500895
896 {
897 auto& sroutes = config.map["Route"];
898 for (const auto& temp : staticGateways)
899 {
900 auto& staticGateway = sroutes.emplace_back();
901 staticGateway["Gateway"].emplace_back(temp.second->gateway());
902 staticGateway["GatewayOnLink"].emplace_back("true");
903 }
904 }
905
Patrick Williamsad205022024-08-16 15:20:07 -0400906 auto path =
907 config::pathForIntfConf(manager.get().getConfDir(), interfaceName());
William A. Kennington III95a49a22022-08-18 17:50:05 -0700908 config.writeFile(path);
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700909 lg2::info("Wrote networkd file: {CFG_FILE}", "CFG_FILE", path);
William A. Kennington III945878a2024-04-17 01:05:27 -0700910 writeUpdatedTime(manager, path);
Ratan Gupta2b106532017-07-25 16:05:02 +0530911}
912
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800913std::string EthernetInterface::macAddress([[maybe_unused]] std::string value)
Ratan Guptabd303b12017-08-18 17:10:07 +0530914{
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700915 if (vlan)
916 {
Jagpal Singh Gillf78a4152023-04-17 21:17:56 -0700917 lg2::error("Tried to set MAC address on VLAN");
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700918 elog<InternalFailure>();
919 }
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800920#ifdef PERSIST_MAC
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700921 stdplus::EtherAddr newMAC;
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600922 try
923 {
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700924 newMAC = stdplus::fromStr<stdplus::EtherAddr>(value);
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600925 }
kokilavf51a2c62024-12-12 02:18:34 -0600926 catch (const std::exception& e)
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600927 {
Milton D. Miller IIe0349902025-04-12 23:23:04 +0000928 lg2::error("Invalid MAC address {NET_MAC}: {ERROR}", "NET_MAC", value,
kokilavf51a2c62024-12-12 02:18:34 -0600929 "ERROR", e);
930 elog<InvalidArgument>(Argument::ARGUMENT_NAME("netmac"),
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600931 Argument::ARGUMENT_VALUE(value.c_str()));
932 }
kokilavf51a2c62024-12-12 02:18:34 -0600933
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700934 if (!newMAC.isUnicast())
Ratan Guptabd303b12017-08-18 17:10:07 +0530935 {
William A. Kennington III1d25ca42023-05-30 16:55:28 -0700936 lg2::error("MAC Address {NET_MAC} is not valid", "NET_MAC", value);
Gunnar Mills90480c42018-06-19 16:02:17 -0500937 elog<InvalidArgument>(Argument::ARGUMENT_NAME("MACAddress"),
938 Argument::ARGUMENT_VALUE(value.c_str()));
Ratan Guptabd303b12017-08-18 17:10:07 +0530939 }
940
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300941 auto interface = interfaceName();
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700942 auto validMAC = stdplus::toStr(newMAC);
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300943
William A. Kennington III1137a972019-04-20 20:49:58 -0700944 // We don't need to update the system if the address is unchanged
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700945 auto oldMAC =
946 stdplus::fromStr<stdplus::EtherAddr>(MacAddressIntf::macAddress());
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700947 if (newMAC != oldMAC)
Ratan Guptabd303b12017-08-18 17:10:07 +0530948 {
William A. Kennington III1137a972019-04-20 20:49:58 -0700949 // Update everything that depends on the MAC value
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800950 for (const auto& [_, intf] : manager.get().interfaces)
Ratan Guptabd303b12017-08-18 17:10:07 +0530951 {
William A. Kennington III09f3a4a2022-10-25 02:59:16 -0700952 if (intf->vlan && intf->vlan->parentIdx == ifIdx)
953 {
954 intf->MacAddressIntf::macAddress(validMAC);
955 }
Ratan Guptabd303b12017-08-18 17:10:07 +0530956 }
Patrick Williams6aef7692021-05-01 06:39:41 -0500957 MacAddressIntf::macAddress(validMAC);
Ratan Guptabd303b12017-08-18 17:10:07 +0530958
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700959 writeConfigurationFile();
William A. Kennington III945878a2024-04-17 01:05:27 -0700960 manager.get().addReloadPreHook([interface, manager = manager]() {
William A. Kennington III6bfdf3e2021-11-09 17:15:12 -0800961 // The MAC and LLADDRs will only update if the NIC is already down
William A. Kennington III2e09d272022-10-14 17:15:00 -0700962 system::setNICUp(interface, false);
William A. Kennington III945878a2024-04-17 01:05:27 -0700963 writeUpdatedTime(
964 manager,
965 config::pathForIntfConf(manager.get().getConfDir(), interface));
William A. Kennington III6bfdf3e2021-11-09 17:15:12 -0800966 });
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800967 manager.get().reloadConfigs();
Ratan Gupta677ae122017-09-18 16:28:50 +0530968 }
William A. Kennington III1137a972019-04-20 20:49:58 -0700969
William A. Kennington III64f61262022-11-06 16:59:41 -0800970 std::error_code ec;
971 const auto fw_setenv = std::filesystem::path("/sbin/fw_setenv");
972 if (std::filesystem::exists(fw_setenv, ec))
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300973 {
William A. Kennington III64f61262022-11-06 16:59:41 -0800974 // Ensure that the valid address is stored in the u-boot-env
975 auto envVar = interfaceToUbootEthAddr(interface);
976 if (envVar)
977 {
978 execute(fw_setenv.native(), "fw_setenv", envVar->c_str(),
979 validMAC.c_str());
980 }
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300981 }
Alexander Filippov76b2aa32020-07-10 13:28:55 +0300982
William A. Kennington III1137a972019-04-20 20:49:58 -0700983 return value;
Jiaqing Zhao69cfa312022-02-18 16:52:55 +0800984#else
985 elog<NotAllowed>(
986 NotAllowedArgument::REASON("Writing MAC address is not allowed"));
987#endif // PERSIST_MAC
Ratan Guptabd303b12017-08-18 17:10:07 +0530988}
989
Ratan Guptae9c9b812017-09-22 17:15:37 +0530990void EthernetInterface::deleteAll()
991{
Ratan Guptae9c9b812017-09-22 17:15:37 +0530992 // clear all the ip on the interface
993 addrs.clear();
William A. Kennington IIIbd649af2021-10-08 17:55:13 -0700994
995 writeConfigurationFile();
William A. Kennington III9ede1b72022-11-21 01:59:28 -0800996 manager.get().reloadConfigs();
Ratan Guptae9c9b812017-09-22 17:15:37 +0530997}
998
William A. Kennington IIId4ff7312023-02-03 14:19:17 -0800999template <typename Addr>
1000static void normalizeGateway(std::string& gw)
Ravi Tejaa5a09442020-07-17 00:57:33 -05001001{
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001002 if (gw.empty())
1003 {
1004 return;
1005 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001006 try
Ravi Tejaa5a09442020-07-17 00:57:33 -05001007 {
William A. Kennington III9ca5c8e2022-12-14 14:40:52 -08001008 auto ip = stdplus::fromStr<Addr>(gw);
1009 if (ip == Addr{})
1010 {
1011 gw.clear();
1012 return;
1013 }
William A. Kennington IIIbbf5e9e2023-02-01 14:58:38 -08001014 if (!validIntfIP(ip))
1015 {
1016 throw std::invalid_argument("Invalid unicast");
1017 }
William A. Kennington III9ca5c8e2022-12-14 14:40:52 -08001018 gw = stdplus::toStr(ip);
Ravi Tejaa5a09442020-07-17 00:57:33 -05001019 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001020 catch (const std::exception& e)
Ravi Tejaa5a09442020-07-17 00:57:33 -05001021 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001022 lg2::error("Invalid GW `{NET_GW}`: {ERROR}", "NET_GW", gw, "ERROR", e);
Ravi Tejaa5a09442020-07-17 00:57:33 -05001023 elog<InvalidArgument>(Argument::ARGUMENT_NAME("GATEWAY"),
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001024 Argument::ARGUMENT_VALUE(gw.c_str()));
Ravi Tejaa5a09442020-07-17 00:57:33 -05001025 }
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001026}
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001027
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001028std::string EthernetInterface::defaultGateway(std::string gateway)
1029{
1030 normalizeGateway<stdplus::In4Addr>(gateway);
1031 if (gateway != defaultGateway())
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001032 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001033 gateway = EthernetInterfaceIntf::defaultGateway(std::move(gateway));
Yuxiao Zhangaf38fe92023-10-12 13:50:50 -07001034 writeConfigurationFile();
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001035 manager.get().reloadConfigs();
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001036 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001037 return gateway;
Ravi Tejaa5a09442020-07-17 00:57:33 -05001038}
1039
1040std::string EthernetInterface::defaultGateway6(std::string gateway)
1041{
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001042 normalizeGateway<stdplus::In6Addr>(gateway);
1043 if (gateway != defaultGateway6())
Ravi Tejaa5a09442020-07-17 00:57:33 -05001044 {
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001045 gateway = EthernetInterfaceIntf::defaultGateway6(std::move(gateway));
Yuxiao Zhangaf38fe92023-10-12 13:50:50 -07001046 writeConfigurationFile();
William A. Kennington IIId4ff7312023-02-03 14:19:17 -08001047 manager.get().reloadConfigs();
Ravi Tejaa5a09442020-07-17 00:57:33 -05001048 }
William A. Kennington IIIf6f0cf32022-11-04 14:28:42 -07001049 return gateway;
Ravi Tejaa5a09442020-07-17 00:57:33 -05001050}
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001051
1052EthernetInterface::VlanProperties::VlanProperties(
1053 sdbusplus::bus_t& bus, stdplus::const_zstring objPath,
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001054 const InterfaceInfo& info, stdplus::PinnedRef<EthernetInterface> eth) :
William A. Kennington IIIb6452542022-11-15 18:09:12 -08001055 VlanIfaces(bus, objPath.c_str(), VlanIfaces::action::defer_emit),
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001056 parentIdx(*info.parent_idx), eth(eth)
1057{
William A. Kennington IIId99e6db2022-11-15 20:39:45 -08001058 VlanIntf::id(*info.vlan_id, true);
1059 emit_object_added();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001060}
1061
1062void EthernetInterface::VlanProperties::delete_()
1063{
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001064 auto intf = eth.get().interfaceName();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001065
1066 // Remove all configs for the current interface
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001067 const auto& confDir = eth.get().manager.get().getConfDir();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001068 std::error_code ec;
1069 std::filesystem::remove(config::pathForIntfConf(confDir, intf), ec);
1070 std::filesystem::remove(config::pathForIntfDev(confDir, intf), ec);
1071
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001072 if (eth.get().ifIdx > 0)
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001073 {
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001074 eth.get().manager.get().interfacesByIdx.erase(eth.get().ifIdx);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001075 }
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001076 auto it = eth.get().manager.get().interfaces.find(intf);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001077 auto obj = std::move(it->second);
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001078 eth.get().manager.get().interfaces.erase(it);
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001079
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001080 // Write an updated parent interface since it has a VLAN entry
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001081 for (const auto& [_, intf] : eth.get().manager.get().interfaces)
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001082 {
1083 if (intf->ifIdx == parentIdx)
1084 {
1085 intf->writeConfigurationFile();
1086 }
1087 }
1088
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001089 if (eth.get().ifIdx > 0)
William A. Kennington III67b09da2022-10-31 14:09:53 -07001090 {
William A. Kennington III6d217512022-11-17 16:18:01 -08001091 // We need to forcibly delete the interface as systemd does not
Patrick Williamsad205022024-08-16 15:20:07 -04001092 eth.get().manager.get().addReloadPostHook([idx = eth.get().ifIdx]() {
1093 system::deleteIntf(idx);
1094 });
William A. Kennington III6d217512022-11-17 16:18:01 -08001095
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001096 // Ignore the interface so the reload doesn't re-query it
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001097 eth.get().manager.get().ignoredIntf.emplace(eth.get().ifIdx);
William A. Kennington III67b09da2022-10-31 14:09:53 -07001098 }
William A. Kennington III93f5c6d2022-11-17 16:23:44 -08001099
William A. Kennington III9ede1b72022-11-21 01:59:28 -08001100 eth.get().manager.get().reloadConfigs();
William A. Kennington III09f3a4a2022-10-25 02:59:16 -07001101}
1102
Ravi Tejaf7116de2024-12-08 22:48:21 -06001103bool EthernetInterface::emitLLDP(bool value)
1104{
1105 if (emitLLDP() != EthernetInterfaceIntf::emitLLDP(value))
1106 {
1107 manager.get().writeLLDPDConfigurationFile();
1108 manager.get().reloadLLDPService();
1109 }
1110 return value;
1111}
1112
Jishnu CM57dfea92023-05-05 06:07:26 -05001113void EthernetInterface::reloadConfigs()
1114{
1115 manager.get().reloadConfigs();
1116}
1117
Gunnar Mills57d9c502018-09-14 14:42:34 -05001118} // namespace network
1119} // namespace phosphor