11bbe3d1eSWilliam A. Kennington III #include "config.h"
21bbe3d1eSWilliam A. Kennington III 
31bbe3d1eSWilliam A. Kennington III #include "network_manager.hpp"
41bbe3d1eSWilliam A. Kennington III #include "rtnetlink_server.hpp"
51bbe3d1eSWilliam A. Kennington III #include "types.hpp"
6*95530ec9SWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY
7*95530ec9SWilliam A. Kennington III #include "util.hpp"
8*95530ec9SWilliam A. Kennington III #endif
91bbe3d1eSWilliam A. Kennington III 
101bbe3d1eSWilliam A. Kennington III #include <linux/netlink.h>
111bbe3d1eSWilliam A. Kennington III 
121bbe3d1eSWilliam A. Kennington III #include <filesystem>
131bbe3d1eSWilliam A. Kennington III #include <fstream>
141bbe3d1eSWilliam A. Kennington III #include <functional>
151bbe3d1eSWilliam A. Kennington III #include <memory>
161bbe3d1eSWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY
171bbe3d1eSWilliam A. Kennington III #include <nlohmann/json.hpp>
181bbe3d1eSWilliam A. Kennington III #endif
191bbe3d1eSWilliam A. Kennington III #include <phosphor-logging/elog-errors.hpp>
201bbe3d1eSWilliam A. Kennington III #include <phosphor-logging/log.hpp>
211bbe3d1eSWilliam A. Kennington III #include <sdbusplus/bus.hpp>
221bbe3d1eSWilliam A. Kennington III #include <sdbusplus/bus/match.hpp>
231bbe3d1eSWilliam A. Kennington III #include <sdbusplus/server/manager.hpp>
241bbe3d1eSWilliam A. Kennington III #include <sdeventplus/event.hpp>
251bbe3d1eSWilliam A. Kennington III #include <xyz/openbmc_project/Common/error.hpp>
261bbe3d1eSWilliam A. Kennington III 
271bbe3d1eSWilliam A. Kennington III using phosphor::logging::elog;
281bbe3d1eSWilliam A. Kennington III using phosphor::logging::entry;
291bbe3d1eSWilliam A. Kennington III using phosphor::logging::level;
301bbe3d1eSWilliam A. Kennington III using phosphor::logging::log;
311bbe3d1eSWilliam A. Kennington III using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
321bbe3d1eSWilliam A. Kennington III using DbusObjectPath = std::string;
331bbe3d1eSWilliam A. Kennington III using DbusInterface = std::string;
341bbe3d1eSWilliam A. Kennington III using PropertyValue = std::string;
351bbe3d1eSWilliam A. Kennington III 
361bbe3d1eSWilliam A. Kennington III constexpr char NETWORK_CONF_DIR[] = "/etc/systemd/network";
371bbe3d1eSWilliam A. Kennington III 
381bbe3d1eSWilliam A. Kennington III constexpr char DEFAULT_OBJPATH[] = "/xyz/openbmc_project/network";
391bbe3d1eSWilliam A. Kennington III 
401bbe3d1eSWilliam A. Kennington III constexpr auto firstBootPath = "/var/lib/network/firstBoot_";
411bbe3d1eSWilliam A. Kennington III constexpr auto configFile = "/usr/share/network/config.json";
421bbe3d1eSWilliam A. Kennington III 
431bbe3d1eSWilliam A. Kennington III constexpr auto invNetworkIntf =
441bbe3d1eSWilliam A. Kennington III     "xyz.openbmc_project.Inventory.Item.NetworkInterface";
451bbe3d1eSWilliam A. Kennington III 
461bbe3d1eSWilliam A. Kennington III namespace phosphor
471bbe3d1eSWilliam A. Kennington III {
481bbe3d1eSWilliam A. Kennington III namespace network
491bbe3d1eSWilliam A. Kennington III {
501bbe3d1eSWilliam A. Kennington III 
511bbe3d1eSWilliam A. Kennington III std::unique_ptr<phosphor::network::Manager> manager = nullptr;
521bbe3d1eSWilliam A. Kennington III std::unique_ptr<Timer> refreshObjectTimer = nullptr;
53c7cf25f7SWilliam A. Kennington III std::unique_ptr<Timer> reloadTimer = nullptr;
541bbe3d1eSWilliam A. Kennington III 
551bbe3d1eSWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY
56c38b0710SPatrick Williams std::unique_ptr<sdbusplus::bus::match_t> EthInterfaceMatch = nullptr;
571bbe3d1eSWilliam A. Kennington III std::vector<std::string> first_boot_status;
581bbe3d1eSWilliam A. Kennington III 
59c38b0710SPatrick Williams bool setInventoryMACOnSystem(sdbusplus::bus_t& bus,
601bbe3d1eSWilliam A. Kennington III                              const nlohmann::json& configJson,
611bbe3d1eSWilliam A. Kennington III                              const std::string& intfname)
621bbe3d1eSWilliam A. Kennington III {
631bbe3d1eSWilliam A. Kennington III     try
641bbe3d1eSWilliam A. Kennington III     {
651bbe3d1eSWilliam A. Kennington III         auto inventoryMAC = mac_address::getfromInventory(bus, intfname);
661bbe3d1eSWilliam A. Kennington III         if (!mac_address::toString(inventoryMAC).empty())
671bbe3d1eSWilliam A. Kennington III         {
681bbe3d1eSWilliam A. Kennington III             log<level::INFO>("Mac Address in Inventory on "),
691bbe3d1eSWilliam A. Kennington III                 entry("Interface : ", intfname.c_str()),
701bbe3d1eSWilliam A. Kennington III                 entry("MAC Address :",
711bbe3d1eSWilliam A. Kennington III                       (mac_address::toString(inventoryMAC)).c_str());
721bbe3d1eSWilliam A. Kennington III             manager->setFistBootMACOnInterface(std::make_pair(
731bbe3d1eSWilliam A. Kennington III                 intfname.c_str(), mac_address::toString(inventoryMAC)));
741bbe3d1eSWilliam A. Kennington III             first_boot_status.push_back(intfname.c_str());
751bbe3d1eSWilliam A. Kennington III             bool status = true;
761bbe3d1eSWilliam A. Kennington III             for (const auto& keys : configJson.items())
771bbe3d1eSWilliam A. Kennington III             {
781bbe3d1eSWilliam A. Kennington III                 if (!(std::find(first_boot_status.begin(),
791bbe3d1eSWilliam A. Kennington III                                 first_boot_status.end(),
801bbe3d1eSWilliam A. Kennington III                                 keys.key()) != first_boot_status.end()))
811bbe3d1eSWilliam A. Kennington III                 {
821bbe3d1eSWilliam A. Kennington III                     log<level::INFO>("Interface MAC is NOT set from VPD"),
831bbe3d1eSWilliam A. Kennington III                         entry("INTERFACE", keys.key().c_str());
841bbe3d1eSWilliam A. Kennington III                     status = false;
851bbe3d1eSWilliam A. Kennington III                 }
861bbe3d1eSWilliam A. Kennington III             }
871bbe3d1eSWilliam A. Kennington III             if (status)
881bbe3d1eSWilliam A. Kennington III             {
891bbe3d1eSWilliam A. Kennington III                 log<level::INFO>("Removing the match for ethernet interfaces");
901bbe3d1eSWilliam A. Kennington III                 phosphor::network::EthInterfaceMatch = nullptr;
911bbe3d1eSWilliam A. Kennington III             }
921bbe3d1eSWilliam A. Kennington III         }
931bbe3d1eSWilliam A. Kennington III         else
941bbe3d1eSWilliam A. Kennington III         {
951bbe3d1eSWilliam A. Kennington III             log<level::INFO>("Nothing is present in Inventory");
961bbe3d1eSWilliam A. Kennington III             return false;
971bbe3d1eSWilliam A. Kennington III         }
981bbe3d1eSWilliam A. Kennington III     }
991bbe3d1eSWilliam A. Kennington III     catch (const std::exception& e)
1001bbe3d1eSWilliam A. Kennington III     {
1011bbe3d1eSWilliam A. Kennington III         log<level::ERR>("Exception occurred during getting of MAC "
1021bbe3d1eSWilliam A. Kennington III                         "address from Inventory");
1031bbe3d1eSWilliam A. Kennington III         return false;
1041bbe3d1eSWilliam A. Kennington III     }
1051bbe3d1eSWilliam A. Kennington III     return true;
1061bbe3d1eSWilliam A. Kennington III }
1071bbe3d1eSWilliam A. Kennington III 
1081bbe3d1eSWilliam A. Kennington III // register the macthes to be monitored from inventory manager
109c38b0710SPatrick Williams void registerSignals(sdbusplus::bus_t& bus, const nlohmann::json& configJson)
1101bbe3d1eSWilliam A. Kennington III {
1111bbe3d1eSWilliam A. Kennington III     log<level::INFO>("Registering the Inventory Signals Matcher");
1121bbe3d1eSWilliam A. Kennington III 
113c38b0710SPatrick Williams     static std::unique_ptr<sdbusplus::bus::match_t> MacAddressMatch;
1141bbe3d1eSWilliam A. Kennington III 
115c38b0710SPatrick Williams     auto callback = [&](sdbusplus::message_t& m) {
1161bbe3d1eSWilliam A. Kennington III         std::map<DbusObjectPath,
1171bbe3d1eSWilliam A. Kennington III                  std::map<DbusInterface, std::variant<PropertyValue>>>
1181bbe3d1eSWilliam A. Kennington III             interfacesProperties;
1191bbe3d1eSWilliam A. Kennington III 
1201bbe3d1eSWilliam A. Kennington III         sdbusplus::message::object_path objPath;
1211bbe3d1eSWilliam A. Kennington III         std::pair<std::string, std::string> ethPair;
1221bbe3d1eSWilliam A. Kennington III         m.read(objPath, interfacesProperties);
1231bbe3d1eSWilliam A. Kennington III 
1241bbe3d1eSWilliam A. Kennington III         for (const auto& pattern : configJson.items())
1251bbe3d1eSWilliam A. Kennington III         {
1261bbe3d1eSWilliam A. Kennington III             if (objPath.str.find(pattern.value()) != std::string::npos)
1271bbe3d1eSWilliam A. Kennington III             {
1281bbe3d1eSWilliam A. Kennington III                 for (auto& interface : interfacesProperties)
1291bbe3d1eSWilliam A. Kennington III                 {
1301bbe3d1eSWilliam A. Kennington III                     if (interface.first == invNetworkIntf)
1311bbe3d1eSWilliam A. Kennington III                     {
1321bbe3d1eSWilliam A. Kennington III                         for (const auto& property : interface.second)
1331bbe3d1eSWilliam A. Kennington III                         {
1341bbe3d1eSWilliam A. Kennington III                             if (property.first == "MACAddress")
1351bbe3d1eSWilliam A. Kennington III                             {
1361bbe3d1eSWilliam A. Kennington III                                 ethPair = std::make_pair(
1371bbe3d1eSWilliam A. Kennington III                                     pattern.key(),
1381bbe3d1eSWilliam A. Kennington III                                     std::get<std::string>(property.second));
1391bbe3d1eSWilliam A. Kennington III                                 break;
1401bbe3d1eSWilliam A. Kennington III                             }
1411bbe3d1eSWilliam A. Kennington III                         }
1421bbe3d1eSWilliam A. Kennington III                         break;
1431bbe3d1eSWilliam A. Kennington III                     }
1441bbe3d1eSWilliam A. Kennington III                 }
1451bbe3d1eSWilliam A. Kennington III                 if (!(ethPair.first.empty() || ethPair.second.empty()))
1461bbe3d1eSWilliam A. Kennington III                 {
1471bbe3d1eSWilliam A. Kennington III                     manager->setFistBootMACOnInterface(ethPair);
1481bbe3d1eSWilliam A. Kennington III                 }
1491bbe3d1eSWilliam A. Kennington III             }
1501bbe3d1eSWilliam A. Kennington III         }
1511bbe3d1eSWilliam A. Kennington III     };
1521bbe3d1eSWilliam A. Kennington III 
153c38b0710SPatrick Williams     MacAddressMatch = std::make_unique<sdbusplus::bus::match_t>(
1541bbe3d1eSWilliam A. Kennington III         bus,
1551bbe3d1eSWilliam A. Kennington III         "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
1561bbe3d1eSWilliam A. Kennington III         "member='InterfacesAdded',path='/xyz/openbmc_project/"
1571bbe3d1eSWilliam A. Kennington III         "inventory'",
1581bbe3d1eSWilliam A. Kennington III         callback);
1591bbe3d1eSWilliam A. Kennington III }
1601bbe3d1eSWilliam A. Kennington III 
161c38b0710SPatrick Williams void watchEthernetInterface(sdbusplus::bus_t& bus,
1621bbe3d1eSWilliam A. Kennington III                             const nlohmann::json& configJson)
1631bbe3d1eSWilliam A. Kennington III {
164c38b0710SPatrick Williams     auto mycallback = [&](sdbusplus::message_t& m) {
1651bbe3d1eSWilliam A. Kennington III         std::map<DbusObjectPath,
1661bbe3d1eSWilliam A. Kennington III                  std::map<DbusInterface, std::variant<PropertyValue>>>
1671bbe3d1eSWilliam A. Kennington III             interfacesProperties;
1681bbe3d1eSWilliam A. Kennington III 
1691bbe3d1eSWilliam A. Kennington III         sdbusplus::message::object_path objPath;
1701bbe3d1eSWilliam A. Kennington III         std::pair<std::string, std::string> ethPair;
1711bbe3d1eSWilliam A. Kennington III         m.read(objPath, interfacesProperties);
1721bbe3d1eSWilliam A. Kennington III         for (const auto& interfaces : interfacesProperties)
1731bbe3d1eSWilliam A. Kennington III         {
1741bbe3d1eSWilliam A. Kennington III             if (interfaces.first ==
1751bbe3d1eSWilliam A. Kennington III                 "xyz.openbmc_project.Network.EthernetInterface")
1761bbe3d1eSWilliam A. Kennington III             {
1771bbe3d1eSWilliam A. Kennington III                 for (const auto& property : interfaces.second)
1781bbe3d1eSWilliam A. Kennington III                 {
1791bbe3d1eSWilliam A. Kennington III                     if (property.first == "InterfaceName")
1801bbe3d1eSWilliam A. Kennington III                     {
1811bbe3d1eSWilliam A. Kennington III                         std::string infname =
1821bbe3d1eSWilliam A. Kennington III                             std::get<std::string>(property.second);
1831bbe3d1eSWilliam A. Kennington III 
1841bbe3d1eSWilliam A. Kennington III                         if (configJson.find(infname) == configJson.end())
1851bbe3d1eSWilliam A. Kennington III                         {
1861bbe3d1eSWilliam A. Kennington III                             // ethernet interface not found in configJSON
1871bbe3d1eSWilliam A. Kennington III                             // check if it is not sit0 interface, as it is
1881bbe3d1eSWilliam A. Kennington III                             // expected.
1891bbe3d1eSWilliam A. Kennington III                             if (infname != "sit0")
1901bbe3d1eSWilliam A. Kennington III                             {
1911bbe3d1eSWilliam A. Kennington III                                 log<level::ERR>(
1921bbe3d1eSWilliam A. Kennington III                                     "Wrong Interface Name in Config Json");
1931bbe3d1eSWilliam A. Kennington III                             }
1941bbe3d1eSWilliam A. Kennington III                         }
1951bbe3d1eSWilliam A. Kennington III                         else
1961bbe3d1eSWilliam A. Kennington III                         {
1971bbe3d1eSWilliam A. Kennington III                             if (!phosphor::network::setInventoryMACOnSystem(
1981bbe3d1eSWilliam A. Kennington III                                     bus, configJson, infname))
1991bbe3d1eSWilliam A. Kennington III                             {
2001bbe3d1eSWilliam A. Kennington III                                 phosphor::network::registerSignals(bus,
2011bbe3d1eSWilliam A. Kennington III                                                                    configJson);
2021bbe3d1eSWilliam A. Kennington III                                 phosphor::network::EthInterfaceMatch = nullptr;
2031bbe3d1eSWilliam A. Kennington III                             }
2041bbe3d1eSWilliam A. Kennington III                         }
2051bbe3d1eSWilliam A. Kennington III                         break;
2061bbe3d1eSWilliam A. Kennington III                     }
2071bbe3d1eSWilliam A. Kennington III                 }
2081bbe3d1eSWilliam A. Kennington III                 break;
2091bbe3d1eSWilliam A. Kennington III             }
2101bbe3d1eSWilliam A. Kennington III         }
2111bbe3d1eSWilliam A. Kennington III     };
2121bbe3d1eSWilliam A. Kennington III     // Incase if phosphor-inventory-manager started early and the VPD is already
2131bbe3d1eSWilliam A. Kennington III     // collected by the time network service has come up, better to check the
2141bbe3d1eSWilliam A. Kennington III     // VPD directly and set the MAC Address on the respective Interface.
2151bbe3d1eSWilliam A. Kennington III 
2161bbe3d1eSWilliam A. Kennington III     bool registeredSignals = false;
2171bbe3d1eSWilliam A. Kennington III     for (const auto& interfaceString : configJson.items())
2181bbe3d1eSWilliam A. Kennington III     {
2191bbe3d1eSWilliam A. Kennington III         if (!std::filesystem::exists(firstBootPath + interfaceString.key()) &&
2201bbe3d1eSWilliam A. Kennington III             !registeredSignals)
2211bbe3d1eSWilliam A. Kennington III         {
2221bbe3d1eSWilliam A. Kennington III 
2231bbe3d1eSWilliam A. Kennington III             log<level::INFO>(
2241bbe3d1eSWilliam A. Kennington III                 "First boot file is not present, check VPD for MAC");
2251bbe3d1eSWilliam A. Kennington III             phosphor::network::EthInterfaceMatch = std::make_unique<
226c38b0710SPatrick Williams                 sdbusplus::bus::match_t>(
2271bbe3d1eSWilliam A. Kennington III                 bus,
2281bbe3d1eSWilliam A. Kennington III                 "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
2291bbe3d1eSWilliam A. Kennington III                 "member='InterfacesAdded',path='/xyz/openbmc_project/network'",
2301bbe3d1eSWilliam A. Kennington III                 mycallback);
2311bbe3d1eSWilliam A. Kennington III             registeredSignals = true;
2321bbe3d1eSWilliam A. Kennington III         }
2331bbe3d1eSWilliam A. Kennington III     }
2341bbe3d1eSWilliam A. Kennington III }
2351bbe3d1eSWilliam A. Kennington III 
2361bbe3d1eSWilliam A. Kennington III #endif
2371bbe3d1eSWilliam A. Kennington III 
2381bbe3d1eSWilliam A. Kennington III /** @brief refresh the network objects. */
2391bbe3d1eSWilliam A. Kennington III void refreshObjects()
2401bbe3d1eSWilliam A. Kennington III {
2411bbe3d1eSWilliam A. Kennington III     if (manager)
2421bbe3d1eSWilliam A. Kennington III     {
2431bbe3d1eSWilliam A. Kennington III         log<level::INFO>("Refreshing the objects.");
2441bbe3d1eSWilliam A. Kennington III         manager->createChildObjects();
2451bbe3d1eSWilliam A. Kennington III         log<level::INFO>("Refreshing complete.");
2461bbe3d1eSWilliam A. Kennington III     }
2471bbe3d1eSWilliam A. Kennington III }
2481bbe3d1eSWilliam A. Kennington III 
249c7cf25f7SWilliam A. Kennington III void reloadNetworkd()
250c7cf25f7SWilliam A. Kennington III {
251c7cf25f7SWilliam A. Kennington III     if (manager)
252c7cf25f7SWilliam A. Kennington III     {
253c7cf25f7SWilliam A. Kennington III         log<level::INFO>("Sending networkd reload");
254c7cf25f7SWilliam A. Kennington III         manager->doReloadConfigs();
255c7cf25f7SWilliam A. Kennington III         log<level::INFO>("Done networkd reload");
256c7cf25f7SWilliam A. Kennington III     }
257c7cf25f7SWilliam A. Kennington III }
258c7cf25f7SWilliam A. Kennington III 
2591bbe3d1eSWilliam A. Kennington III void initializeTimers()
2601bbe3d1eSWilliam A. Kennington III {
2611bbe3d1eSWilliam A. Kennington III     auto event = sdeventplus::Event::get_default();
2621bbe3d1eSWilliam A. Kennington III     refreshObjectTimer =
2631bbe3d1eSWilliam A. Kennington III         std::make_unique<Timer>(event, std::bind(refreshObjects));
264c7cf25f7SWilliam A. Kennington III     reloadTimer = std::make_unique<Timer>(event, std::bind(reloadNetworkd));
2651bbe3d1eSWilliam A. Kennington III }
2661bbe3d1eSWilliam A. Kennington III 
2671bbe3d1eSWilliam A. Kennington III } // namespace network
2681bbe3d1eSWilliam A. Kennington III } // namespace phosphor
2691bbe3d1eSWilliam A. Kennington III 
2701bbe3d1eSWilliam A. Kennington III int main(int /*argc*/, char** /*argv*/)
2711bbe3d1eSWilliam A. Kennington III {
2721bbe3d1eSWilliam A. Kennington III     phosphor::network::initializeTimers();
2731bbe3d1eSWilliam A. Kennington III 
2741bbe3d1eSWilliam A. Kennington III     auto bus = sdbusplus::bus::new_default();
2751bbe3d1eSWilliam A. Kennington III 
2761bbe3d1eSWilliam A. Kennington III     // Need sd_event to watch for OCC device errors
2771bbe3d1eSWilliam A. Kennington III     sd_event* event = nullptr;
2781bbe3d1eSWilliam A. Kennington III     auto r = sd_event_default(&event);
2791bbe3d1eSWilliam A. Kennington III     if (r < 0)
2801bbe3d1eSWilliam A. Kennington III     {
2811bbe3d1eSWilliam A. Kennington III         log<level::ERR>("Error creating a default sd_event handler");
2821bbe3d1eSWilliam A. Kennington III         return r;
2831bbe3d1eSWilliam A. Kennington III     }
2841bbe3d1eSWilliam A. Kennington III 
2851bbe3d1eSWilliam A. Kennington III     phosphor::network::EventPtr eventPtr{event};
2861bbe3d1eSWilliam A. Kennington III     event = nullptr;
2871bbe3d1eSWilliam A. Kennington III 
2881bbe3d1eSWilliam A. Kennington III     // Attach the bus to sd_event to service user requests
2891bbe3d1eSWilliam A. Kennington III     bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
2901bbe3d1eSWilliam A. Kennington III 
2911bbe3d1eSWilliam A. Kennington III     // Add sdbusplus Object Manager for the 'root' path of the network manager.
292c38b0710SPatrick Williams     sdbusplus::server::manager_t objManager(bus, DEFAULT_OBJPATH);
2931bbe3d1eSWilliam A. Kennington III     bus.request_name(DEFAULT_BUSNAME);
2941bbe3d1eSWilliam A. Kennington III 
2951bbe3d1eSWilliam A. Kennington III     phosphor::network::manager = std::make_unique<phosphor::network::Manager>(
2961bbe3d1eSWilliam A. Kennington III         bus, DEFAULT_OBJPATH, NETWORK_CONF_DIR);
2971bbe3d1eSWilliam A. Kennington III 
2981bbe3d1eSWilliam A. Kennington III     // create the default network files if the network file
2991bbe3d1eSWilliam A. Kennington III     // is not there for any interface.
3009a1d9afaSWilliam A. Kennington III     if (phosphor::network::manager->createDefaultNetworkFiles())
3011bbe3d1eSWilliam A. Kennington III     {
302bd649af9SWilliam A. Kennington III         phosphor::network::manager->reloadConfigs();
3031bbe3d1eSWilliam A. Kennington III     }
3041bbe3d1eSWilliam A. Kennington III 
3051bbe3d1eSWilliam A. Kennington III     // RTNETLINK event handler
30632eef716SWilliam A. Kennington III     phosphor::network::rtnetlink::Server svr(eventPtr);
3071bbe3d1eSWilliam A. Kennington III 
3081bbe3d1eSWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY
3091bbe3d1eSWilliam A. Kennington III     std::ifstream in(configFile);
3101bbe3d1eSWilliam A. Kennington III     nlohmann::json configJson;
3111bbe3d1eSWilliam A. Kennington III     in >> configJson;
3121bbe3d1eSWilliam A. Kennington III     phosphor::network::watchEthernetInterface(bus, configJson);
3131bbe3d1eSWilliam A. Kennington III #endif
314bd649af9SWilliam A. Kennington III 
315bd649af9SWilliam A. Kennington III     // Trigger the initial object scan
31626c40a43SWilliam A. Kennington III     // This is intentionally deferred, to ensure that systemd-networkd is
31726c40a43SWilliam A. Kennington III     // fully configured.
31826c40a43SWilliam A. Kennington III     phosphor::network::refreshObjectTimer->restartOnce(
31926c40a43SWilliam A. Kennington III         phosphor::network::refreshTimeout);
320bd649af9SWilliam A. Kennington III 
3211bbe3d1eSWilliam A. Kennington III     sd_event_loop(eventPtr.get());
3221bbe3d1eSWilliam A. Kennington III }
323