system_queries: Migrate system queries into a single place

This provides better separation of the DBus interface and the underlying
system interactions.

Change-Id: I8bf7a44c679ab065f959af19a00c29897c1d5c48
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/dhcp_configuration.cpp b/src/dhcp_configuration.cpp
index 5914277..33b2cbd 100644
--- a/src/dhcp_configuration.cpp
+++ b/src/dhcp_configuration.cpp
@@ -2,6 +2,7 @@
 
 #include "config_parser.hpp"
 #include "network_manager.hpp"
+#include "system_queries.hpp"
 #include "util.hpp"
 
 #include <phosphor-logging/elog-errors.hpp>
@@ -26,7 +27,7 @@
 {
     config::Parser conf;
     {
-        auto interfaceStrList = getSystemInterfaces();
+        auto interfaceStrList = system::getInterfaces();
         if (!interfaceStrList.empty())
         {
             conf.setFile(config::pathForIntfConf(manager.getConfDir(),
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index ff5a21b..a29bced 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -4,22 +4,20 @@
 
 #include "config_parser.hpp"
 #include "network_manager.hpp"
+#include "system_queries.hpp"
 #include "util.hpp"
 
-#include <arpa/inet.h>
 #include <fmt/compile.h>
 #include <fmt/format.h>
-#include <linux/ethtool.h>
+#include <linux/if_addr.h>
+#include <linux/neighbour.h>
 #include <linux/rtnetlink.h>
-#include <linux/sockios.h>
-#include <net/if.h>
 
 #include <algorithm>
 #include <filesystem>
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus/match.hpp>
-#include <stdplus/fd/create.hpp>
 #include <stdplus/raw.hpp>
 #include <stdplus/zstring.hpp>
 #include <string>
@@ -49,56 +47,22 @@
 
 constexpr auto METHOD_GET = "Get";
 
-static stdplus::Fd& getIFSock()
+template <typename Func>
+inline decltype(std::declval<Func>()())
+    ignoreError(std::string_view msg, stdplus::zstring_view intf,
+                decltype(std::declval<Func>()()) fallback, Func&& func) noexcept
 {
-    using namespace stdplus::fd;
-    static auto fd =
-        socket(SocketDomain::INet, SocketType::Datagram, SocketProto::IP);
-    return fd;
-}
-
-struct LinkInfo
-{
-    bool autoneg;
-    uint16_t speed;
-};
-
-static LinkInfo getLinkInfo(stdplus::zstring_view ifname)
-{
-    LinkInfo ret;
     try
     {
-        ethtool_cmd edata = {};
-        edata.cmd = ETHTOOL_GSET;
-
-        ifreq ifr = {};
-        const auto copied = std::min<std::size_t>(ifname.size(), IFNAMSIZ - 1);
-        std::copy_n(ifname.begin(), copied, ifr.ifr_name);
-        ifr.ifr_data = reinterpret_cast<char*>(&edata);
-
-        getIFSock().ioctl(SIOCETHTOOL, &ifr);
-
-        ret.speed = edata.speed;
-        ret.autoneg = edata.autoneg;
+        return func();
     }
-    catch (const std::system_error& e)
+    catch (const std::exception& e)
     {
-        if (e.code() == std::errc::operation_not_supported)
-        {
-            auto msg = fmt::format("ETHTOOL not supported on {}", ifname);
-            log<level::NOTICE>(msg.c_str(),
-                               entry("INTERFACE=%s", ifname.c_str()));
-        }
-        else
-        {
-            auto msg =
-                fmt::format("ETHTOOL failed on {}: {}", ifname, e.what());
-            log<level::ERR>(msg.c_str(), entry("INTERFACE=%s", ifname.c_str()));
-        }
+        auto err = fmt::format("{} failed on {}: {}", msg, intf, e.what());
+        log<level::ERR>(err.c_str(), entry("INTERFACE=%s", intf.c_str()));
     }
-    return ret;
+    return fallback;
 }
-
 EthernetInterface::EthernetInterface(sdbusplus::bus_t& bus,
                                      stdplus::zstring_view objPath,
                                      const config::Parser& config,
@@ -107,11 +71,12 @@
     Ifaces(bus, objPath.c_str(),
            emitSignal ? Ifaces::action::defer_emit
                       : Ifaces::action::emit_no_signals),
-    bus(bus), manager(parent), objPath(objPath.c_str())
+    bus(bus), manager(parent), objPath(objPath)
 {
     auto intfName = std::string(objPath.substr(objPath.rfind('/') + 1));
     std::replace(intfName.begin(), intfName.end(), '_', '.');
     interfaceName(intfName);
+    ifIdx = system::intfIndex(intfName);
     auto dhcpVal = getDHCPValue(config);
     EthernetInterfaceIntf::dhcp4(dhcpVal.v4);
     EthernetInterfaceIntf::dhcp6(dhcpVal.v6);
@@ -146,16 +111,11 @@
     // would be same as parent interface.
     if (intfName.find(".") == std::string::npos)
     {
-        try
+        auto mac = ignoreError("getMAC", intfName, std::nullopt,
+                               [&] { return system::getMAC(intfName); });
+        if (mac)
         {
-            MacAddressIntf::macAddress(getMACAddress(intfName));
-        }
-        catch (const std::exception& e)
-        {
-            auto msg =
-                fmt::format("Failed to get MAC for {}: {}", intfName, e.what());
-            log<level::ERR>(msg.c_str(),
-                            entry("INTERFACE=%s", intfName.c_str()));
+            MacAddressIntf::macAddress(mac_address::toString(*mac));
         }
     }
     EthernetInterfaceIntf::ntpServers(
@@ -164,9 +124,10 @@
     EthernetInterfaceIntf::linkUp(linkUp());
     EthernetInterfaceIntf::mtu(mtu());
 
-    auto info = getLinkInfo(intfName);
-    EthernetInterfaceIntf::autoNeg(info.autoneg);
-    EthernetInterfaceIntf::speed(info.speed);
+    auto ethInfo = ignoreError("GetEthInfo", intfName, {},
+                               [&] { return system::getEthInfo(intfName); });
+    EthernetInterfaceIntf::autoNeg(ethInfo.autoneg);
+    EthernetInterfaceIntf::speed(ethInfo.speed);
 
     // Emit deferred signal.
     if (emitSignal)
@@ -219,7 +180,7 @@
     addrs.clear();
 
     AddressFilter filter;
-    filter.interface = ifIndex();
+    filter.interface = ifIdx;
     auto currentAddrs = getCurrentAddresses(filter);
     for (const auto& addr : currentAddrs)
     {
@@ -256,7 +217,7 @@
     staticNeighbors.clear();
 
     NeighborFilter filter;
-    filter.interface = ifIndex();
+    filter.interface = ifIdx;
     filter.state = NUD_PERMANENT;
     auto neighbors = getCurrentNeighbors(filter);
     for (const auto& neighbor : neighbors)
@@ -274,17 +235,6 @@
     }
 }
 
-unsigned EthernetInterface::ifIndex() const
-{
-    unsigned idx = if_nametoindex(interfaceName().c_str());
-    if (idx == 0)
-    {
-        throw std::system_error(errno, std::generic_category(),
-                                "if_nametoindex");
-    }
-    return idx;
-}
-
 ObjectPath EthernetInterface::ip(IP::Protocol protType, std::string ipaddress,
                                  uint8_t prefixLength, std::string)
 {
@@ -370,31 +320,6 @@
     return objectPath;
 }
 
-/** @brief get the mac address of the interface.
- *  @return macaddress on success
- */
-
-std::string
-    EthernetInterface::getMACAddress(stdplus::const_zstring interfaceName) const
-{
-    std::string activeMACAddr = MacAddressIntf::macAddress();
-
-    ifreq ifr = {};
-    std::strncpy(ifr.ifr_name, interfaceName.c_str(), IFNAMSIZ - 1);
-    try
-    {
-        getIFSock().ioctl(SIOCGIFHWADDR, &ifr);
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>("ioctl failed for SIOCGIFHWADDR:",
-                        entry("ERROR=%s", e.what()));
-        elog<InternalFailure>();
-    }
-    return mac_address::toString(
-        stdplus::raw::refFrom<ether_addr>(ifr.ifr_hwaddr.sa_data));
-}
-
 void EthernetInterface::deleteObject(std::string_view ipaddress)
 {
     auto it = addrs.find(ipaddress);
@@ -562,70 +487,29 @@
 
 bool EthernetInterface::linkUp() const
 {
-    bool value = EthernetInterfaceIntf::linkUp();
-
-    ifreq ifr = {};
-    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
-    try
-    {
-        getIFSock().ioctl(SIOCGIFFLAGS, &ifr);
-        value = static_cast<bool>(ifr.ifr_flags & IFF_RUNNING);
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
-                        entry("ERROR=%s", e.what()));
-    }
-    return value;
+    return system::intfIsRunning(interfaceName());
 }
 
 size_t EthernetInterface::mtu() const
 {
-    size_t value = EthernetInterfaceIntf::mtu();
-
-    ifreq ifr = {};
-    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
-    try
-    {
-        getIFSock().ioctl(SIOCGIFMTU, &ifr);
-        value = ifr.ifr_mtu;
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>("ioctl failed for SIOCGIFMTU:",
-                        entry("ERROR=%s", e.what()));
-    }
-    return value;
+    const auto ifname = interfaceName();
+    return ignoreError("getMTU", ifname, std::nullopt,
+                       [&] { return system::getMTU(ifname); })
+        .value_or(EthernetInterfaceIntf::mtu());
 }
 
 size_t EthernetInterface::mtu(size_t value)
 {
-    if (value == EthernetInterfaceIntf::mtu())
+    const size_t old = EthernetInterfaceIntf::mtu();
+    if (value == old)
     {
         return value;
     }
-    else if (value == 0)
-    {
-        return EthernetInterfaceIntf::mtu();
-    }
-
-    ifreq ifr = {};
-    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
-    ifr.ifr_mtu = value;
-
-    try
-    {
-        getIFSock().ioctl(SIOCSIFMTU, &ifr);
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>("ioctl failed for SIOCSIFMTU:",
-                        entry("ERROR=%s", strerror(errno)));
-        return EthernetInterfaceIntf::mtu();
-    }
-
-    EthernetInterfaceIntf::mtu(value);
-    return value;
+    const auto ifname = interfaceName();
+    return EthernetInterfaceIntf::mtu(ignoreError("setMTU", ifname, old, [&] {
+        system::setMTU(ifname, value);
+        return value;
+    }));
 }
 
 bool EthernetInterface::queryNicEnabled() const
@@ -635,7 +519,7 @@
     constexpr auto prop = "AdministrativeState";
     char* rpath;
     sd_bus_path_encode("/org/freedesktop/network1/link",
-                       std::to_string(ifIndex()).c_str(), &rpath);
+                       std::to_string(ifIdx).c_str(), &rpath);
     std::string path(rpath);
     free(rpath);
 
@@ -713,17 +597,6 @@
     return *ret;
 }
 
-static void setNICAdminState(stdplus::const_zstring intf, bool up)
-{
-    ifreq ifr = {};
-    std::strncpy(ifr.ifr_name, intf.data(), IF_NAMESIZE - 1);
-    getIFSock().ioctl(SIOCGIFFLAGS, &ifr);
-
-    ifr.ifr_flags &= ~IFF_UP;
-    ifr.ifr_flags |= up ? IFF_UP : 0;
-    getIFSock().ioctl(SIOCSIFFLAGS, &ifr);
-}
-
 bool EthernetInterface::nicEnabled(bool value)
 {
     if (value == EthernetInterfaceIntf::nicEnabled())
@@ -738,7 +611,7 @@
         // We only need to bring down the interface, networkd will always bring
         // up managed interfaces
         manager.addReloadPreHook(
-            [ifname = interfaceName()]() { setNICAdminState(ifname, false); });
+            [ifname = interfaceName()]() { system::setNICUp(ifname, false); });
     }
     manager.reloadConfigs();
 
@@ -813,7 +686,7 @@
 ServerList EthernetInterface::getNameServerFromResolvd()
 {
     ServerList servers;
-    std::string OBJ_PATH = RESOLVED_SERVICE_PATH + std::to_string(ifIndex());
+    auto OBJ_PATH = fmt::format("{}{}", RESOLVED_SERVICE_PATH, ifIdx);
 
     /*
       The DNS property under org.freedesktop.resolve1.Link interface contains
@@ -1141,7 +1014,7 @@
         writeConfigurationFile();
         manager.addReloadPreHook([interface]() {
             // The MAC and LLADDRs will only update if the NIC is already down
-            setNICAdminState(interface, false);
+            system::setNICUp(interface, false);
         });
         manager.reloadConfigs();
     }
diff --git a/src/ethernet_interface.hpp b/src/ethernet_interface.hpp
index a4b127c..b8f73c5 100644
--- a/src/ethernet_interface.hpp
+++ b/src/ethernet_interface.hpp
@@ -128,10 +128,6 @@
      */
     void createStaticNeighborObjects();
 
-    /* @brief Gets the index of the interface on the system
-     */
-    unsigned ifIndex() const;
-
     /* @brief Gets all the ip addresses.
      * @returns the list of ipAddress.
      */
@@ -240,13 +236,6 @@
      */
     void deleteVLANFromSystem(stdplus::zstring_view interface);
 
-    /** @brief get the mac address of the interface.
-     *  @param[in] interfaceName - Network interface name.
-     *  @return macaddress on success
-     */
-
-    std::string getMACAddress(stdplus::const_zstring interfaceName) const;
-
     /** @brief construct the ip address dbus object path.
      *  @param[in] addressType - Type of ip address.
      *  @param[in] ipAddress - IP address.
@@ -292,6 +281,9 @@
     /** @brief Dbus object path */
     std::string objPath;
 
+    /** @brief Interface index */
+    unsigned ifIdx;
+
     friend class TestEthernetInterface;
 
   private:
diff --git a/src/meson.build b/src/meson.build
index 84c2f82..184eb4a 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -54,6 +54,7 @@
   'network_config.cpp',
   'network_manager.cpp',
   'system_configuration.cpp',
+  'system_queries.cpp',
   'util.cpp',
   'routing_table.cpp',
   'config_parser.cpp',
diff --git a/src/network_manager.cpp b/src/network_manager.cpp
index 25b9c05..df9bf9b 100644
--- a/src/network_manager.cpp
+++ b/src/network_manager.cpp
@@ -4,20 +4,14 @@
 
 #include "ipaddress.hpp"
 #include "network_config.hpp"
+#include "system_queries.hpp"
 #include "types.hpp"
-#include "util.hpp"
 
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <net/if.h>
-
-#include <algorithm>
 #include <charconv>
 #include <filesystem>
 #include <fstream>
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/log.hpp>
-#include <string>
 #include <xyz/openbmc_project/Common/error.hpp>
 
 constexpr char SYSTEMD_BUSNAME[] = "org.freedesktop.systemd1";
@@ -54,7 +48,7 @@
     auto isCreated = false;
     try
     {
-        auto interfaceStrList = getSystemInterfaces();
+        auto interfaceStrList = system::getInterfaces();
         for (const auto& interface : interfaceStrList)
         {
             // if the interface has '.' in the name, it means that this is a
@@ -104,9 +98,7 @@
 {
     // clear all the interfaces first
     interfaces.clear();
-
-    auto interfaceStrList = getSystemInterfaces();
-
+    auto interfaceStrList = system::getInterfaces();
     for (auto& interface : interfaceStrList)
     {
         fs::path objPath = objectPath;
diff --git a/src/system_queries.cpp b/src/system_queries.cpp
new file mode 100644
index 0000000..f02d568
--- /dev/null
+++ b/src/system_queries.cpp
@@ -0,0 +1,156 @@
+#include "system_queries.hpp"
+
+#include "util.hpp"
+
+#include <fmt/format.h>
+#include <ifaddrs.h>
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+#include <net/if.h>
+
+#include <algorithm>
+#include <optional>
+#include <phosphor-logging/log.hpp>
+#include <stdexcept>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/raw.hpp>
+#include <stdplus/util/cexec.hpp>
+#include <string_view>
+#include <system_error>
+
+namespace phosphor::network::system
+{
+
+using std::literals::string_view_literals::operator""sv;
+using phosphor::logging::entry;
+using phosphor::logging::level;
+using phosphor::logging::log;
+
+static stdplus::Fd& getIFSock()
+{
+    using namespace stdplus::fd;
+    static auto fd =
+        socket(SocketDomain::INet, SocketType::Datagram, SocketProto::IP);
+    return fd;
+}
+
+static ifreq makeIFReq(std::string_view ifname)
+{
+    ifreq ifr = {};
+    const auto copied = std::min<std::size_t>(ifname.size(), IFNAMSIZ - 1);
+    std::copy_n(ifname.begin(), copied, ifr.ifr_name);
+    return ifr;
+}
+
+static ifreq executeIFReq(std::string_view ifname, unsigned long cmd,
+                          void* data = nullptr)
+{
+    ifreq ifr = makeIFReq(ifname);
+    ifr.ifr_data = reinterpret_cast<char*>(data);
+    getIFSock().ioctl(cmd, &ifr);
+    return ifr;
+}
+
+inline auto optionalIFReq(stdplus::zstring_view ifname, unsigned long long cmd,
+                          std::string_view cmdname, auto&& complete,
+                          void* data = nullptr)
+{
+    ifreq ifr;
+    std::optional<decltype(complete(ifr))> ret;
+    try
+    {
+        ifr = executeIFReq(ifname, cmd, data);
+    }
+    catch (const std::system_error& e)
+    {
+        if (e.code() == std::errc::operation_not_supported)
+        {
+            auto msg = fmt::format("{} not supported on {}", cmdname, ifname);
+            log<level::INFO>(msg.c_str(),
+                             entry("INTERFACE=%s", ifname.c_str()));
+            return ret;
+        }
+        throw;
+    }
+    ret.emplace(complete(ifr));
+    return ret;
+}
+
+EthInfo getEthInfo(stdplus::zstring_view ifname)
+{
+    ethtool_cmd edata = {};
+    edata.cmd = ETHTOOL_GSET;
+    return optionalIFReq(
+               ifname, SIOCETHTOOL, "ETHTOOL"sv,
+               [&](const ifreq&) {
+                   return EthInfo{.autoneg = edata.autoneg != 0,
+                                  .speed = edata.speed};
+               },
+               &edata)
+        .value_or(EthInfo{});
+}
+
+bool intfIsRunning(std::string_view ifname)
+{
+    return executeIFReq(ifname, SIOCGIFFLAGS).ifr_flags & IFF_RUNNING;
+}
+
+unsigned intfIndex(stdplus::const_zstring ifname)
+{
+    unsigned idx = if_nametoindex(ifname.c_str());
+    if (idx == 0)
+    {
+        auto msg = fmt::format("if_nametoindex({})", ifname);
+        throw std::system_error(errno, std::generic_category(), msg);
+    }
+    return idx;
+}
+
+std::optional<ether_addr> getMAC(stdplus::zstring_view ifname)
+{
+    return optionalIFReq(
+        ifname, SIOCGIFHWADDR, "IFHWADDR", [](const ifreq& ifr) {
+            return stdplus::raw::refFrom<ether_addr>(ifr.ifr_hwaddr.sa_data);
+        });
+}
+
+std::optional<unsigned> getMTU(stdplus::zstring_view ifname)
+{
+    return optionalIFReq(ifname, SIOCGIFMTU, "GMTU",
+                         [](const ifreq& ifr) { return ifr.ifr_mtu; });
+}
+
+void setMTU(std::string_view ifname, unsigned mtu)
+{
+    auto ifr = makeIFReq(ifname);
+    ifr.ifr_mtu = mtu;
+    getIFSock().ioctl(SIOCSIFMTU, &ifr);
+}
+
+void setNICUp(std::string_view ifname, bool up)
+{
+    ifreq ifr = executeIFReq(ifname, SIOCGIFFLAGS);
+    ifr.ifr_flags &= ~IFF_UP;
+    ifr.ifr_flags |= up ? IFF_UP : 0;
+    getIFSock().ioctl(SIOCSIFFLAGS, &ifr);
+}
+
+string_uset getInterfaces()
+{
+    string_uset ret;
+    struct ifaddrs* root;
+    CHECK_ERRNO(getifaddrs(&root), "getifaddrs");
+    const auto& ignored = internal::getIgnoredInterfaces();
+    for (auto it = root; it != nullptr; it = it->ifa_next)
+    {
+        if (!(it->ifa_flags & IFF_LOOPBACK) &&
+            ignored.find(it->ifa_name) == ignored.end())
+        {
+            ret.emplace(it->ifa_name);
+        }
+    }
+    freeifaddrs(root);
+    return ret;
+}
+
+} // namespace phosphor::network::system
diff --git a/src/system_queries.hpp b/src/system_queries.hpp
new file mode 100644
index 0000000..3182cd6
--- /dev/null
+++ b/src/system_queries.hpp
@@ -0,0 +1,39 @@
+#pragma once
+#include "types.hpp"
+
+#include <netinet/ether.h>
+
+#include <cstdint>
+#include <optional>
+#include <stdplus/zstring.hpp>
+#include <stdplus/zstring_view.hpp>
+#include <string_view>
+
+namespace phosphor::network::system
+{
+
+struct EthInfo
+{
+    bool autoneg;
+    uint16_t speed;
+};
+EthInfo getEthInfo(stdplus::zstring_view ifname);
+
+bool intfIsRunning(std::string_view ifname);
+
+unsigned intfIndex(stdplus::const_zstring ifname);
+
+std::optional<ether_addr> getMAC(stdplus::zstring_view ifname);
+
+std::optional<unsigned> getMTU(stdplus::zstring_view ifname);
+
+void setMTU(std::string_view ifname, unsigned mtu);
+
+void setNICUp(std::string_view ifname, bool up);
+
+/** @brief Get all the interfaces from the system.
+ *  @returns list of interface names.
+ */
+string_uset getInterfaces();
+
+} // namespace phosphor::network::system
diff --git a/src/types.hpp b/src/types.hpp
index 9eeb3b7..7d77ffc 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -1,6 +1,4 @@
 #pragma once
-
-#include <ifaddrs.h>
 #include <netinet/in.h>
 #include <systemd/sd-event.h>
 
@@ -27,18 +25,6 @@
 // configuration takes 3-4 sec to reconfigure at most.
 constexpr auto refreshTimeout = 4s;
 
-using Addr_t = ifaddrs*;
-
-struct AddrDeleter
-{
-    void operator()(Addr_t ptr) const
-    {
-        freeifaddrs(ptr);
-    }
-};
-
-using AddrPtr = std::unique_ptr<ifaddrs, AddrDeleter>;
-
 /* Need a custom deleter for freeing up sd_event */
 struct EventDeleter
 {
diff --git a/src/util.cpp b/src/util.cpp
index 9d58bcb..186d0c2 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -6,19 +6,14 @@
 #include "types.hpp"
 
 #include <arpa/inet.h>
-#include <dirent.h>
 #include <fmt/compile.h>
 #include <fmt/format.h>
-#include <net/if.h>
 #include <sys/wait.h>
 
 #include <algorithm>
 #include <cctype>
 #include <charconv>
-#include <cstdlib>
-#include <cstring>
 #include <fstream>
-#include <list>
 #ifdef SYNC_MAC_FROM_INVENTORY
 #include <nlohmann/json.hpp>
 #endif
@@ -200,38 +195,6 @@
         [=]<int f>() noexcept { return isValidPrefix<f>(prefix); }, family);
 }
 
-string_uset getSystemInterfaces()
-{
-    string_uset interfaces;
-    struct ifaddrs* ifaddr = nullptr;
-
-    // attempt to fill struct with ifaddrs
-    if (getifaddrs(&ifaddr) == -1)
-    {
-        auto error = errno;
-        log<level::ERR>("Error occurred during the getifaddrs call",
-                        entry("ERRNO=%d", error));
-        elog<InternalFailure>();
-    }
-
-    AddrPtr ifaddrPtr(ifaddr);
-    ifaddr = nullptr;
-    const auto& ignoredInterfaces = internal::getIgnoredInterfaces();
-
-    for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
-    {
-        // walk interfaces
-        // if loopback ignore
-        if (ifa->ifa_flags & IFF_LOOPBACK ||
-            ignoredInterfaces.find(ifa->ifa_name) != ignoredInterfaces.end())
-        {
-            continue;
-        }
-        interfaces.emplace(ifa->ifa_name);
-    }
-    return interfaces;
-}
-
 void deleteInterface(stdplus::const_zstring intf)
 {
     pid_t pid = fork();
diff --git a/src/util.hpp b/src/util.hpp
index 96c8d25..f6b9796 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -142,11 +142,6 @@
 }
 bool isValidPrefix(int family, uint8_t prefixLength);
 
-/** @brief Get all the interfaces from the system.
- *  @returns list of interface names.
- */
-string_uset getSystemInterfaces();
-
 /** @brief Delete the given interface.
  *  @param[in] intf - interface name.
  */