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