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" 695530ec9SWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY 795530ec9SWilliam A. Kennington III #include "util.hpp" 895530ec9SWilliam A. Kennington III #endif 91bbe3d1eSWilliam A. Kennington III 104fd52ae4SWilliam A. Kennington III #include <fmt/format.h> 111bbe3d1eSWilliam A. Kennington III #include <linux/netlink.h> 121bbe3d1eSWilliam A. Kennington III 131bbe3d1eSWilliam A. Kennington III #include <filesystem> 141bbe3d1eSWilliam A. Kennington III #include <fstream> 151bbe3d1eSWilliam A. Kennington III #include <functional> 161bbe3d1eSWilliam A. Kennington III #include <memory> 171bbe3d1eSWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY 181bbe3d1eSWilliam A. Kennington III #include <nlohmann/json.hpp> 191bbe3d1eSWilliam A. Kennington III #endif 201bbe3d1eSWilliam A. Kennington III #include <phosphor-logging/elog-errors.hpp> 211bbe3d1eSWilliam A. Kennington III #include <phosphor-logging/log.hpp> 221bbe3d1eSWilliam A. Kennington III #include <sdbusplus/bus.hpp> 231bbe3d1eSWilliam A. Kennington III #include <sdbusplus/bus/match.hpp> 241bbe3d1eSWilliam A. Kennington III #include <sdbusplus/server/manager.hpp> 251bbe3d1eSWilliam A. Kennington III #include <sdeventplus/event.hpp> 26*217bb3fdSWilliam A. Kennington III #include <sdeventplus/source/signal.hpp> 27*217bb3fdSWilliam A. Kennington III #include <stdplus/signal.hpp> 281bbe3d1eSWilliam A. Kennington III #include <xyz/openbmc_project/Common/error.hpp> 291bbe3d1eSWilliam A. Kennington III 301bbe3d1eSWilliam A. Kennington III using phosphor::logging::elog; 311bbe3d1eSWilliam A. Kennington III using phosphor::logging::entry; 321bbe3d1eSWilliam A. Kennington III using phosphor::logging::level; 331bbe3d1eSWilliam A. Kennington III using phosphor::logging::log; 341bbe3d1eSWilliam A. Kennington III using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 351bbe3d1eSWilliam A. Kennington III using DbusObjectPath = std::string; 361bbe3d1eSWilliam A. Kennington III using DbusInterface = std::string; 371bbe3d1eSWilliam A. Kennington III using PropertyValue = std::string; 381bbe3d1eSWilliam A. Kennington III 391bbe3d1eSWilliam A. Kennington III constexpr char NETWORK_CONF_DIR[] = "/etc/systemd/network"; 401bbe3d1eSWilliam A. Kennington III 411bbe3d1eSWilliam A. Kennington III constexpr char DEFAULT_OBJPATH[] = "/xyz/openbmc_project/network"; 421bbe3d1eSWilliam A. Kennington III 431bbe3d1eSWilliam A. Kennington III constexpr auto firstBootPath = "/var/lib/network/firstBoot_"; 441bbe3d1eSWilliam A. Kennington III constexpr auto configFile = "/usr/share/network/config.json"; 451bbe3d1eSWilliam A. Kennington III 461bbe3d1eSWilliam A. Kennington III constexpr auto invNetworkIntf = 471bbe3d1eSWilliam A. Kennington III "xyz.openbmc_project.Inventory.Item.NetworkInterface"; 481bbe3d1eSWilliam A. Kennington III 491bbe3d1eSWilliam A. Kennington III namespace phosphor 501bbe3d1eSWilliam A. Kennington III { 511bbe3d1eSWilliam A. Kennington III namespace network 521bbe3d1eSWilliam A. Kennington III { 531bbe3d1eSWilliam A. Kennington III 544fd52ae4SWilliam A. Kennington III std::unique_ptr<Manager> manager = nullptr; 551bbe3d1eSWilliam A. Kennington III std::unique_ptr<Timer> refreshObjectTimer = nullptr; 56c7cf25f7SWilliam A. Kennington III std::unique_ptr<Timer> reloadTimer = nullptr; 571bbe3d1eSWilliam A. Kennington III 581bbe3d1eSWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY 59c38b0710SPatrick Williams std::unique_ptr<sdbusplus::bus::match_t> EthInterfaceMatch = nullptr; 601bbe3d1eSWilliam A. Kennington III std::vector<std::string> first_boot_status; 611bbe3d1eSWilliam A. Kennington III 62c38b0710SPatrick Williams bool setInventoryMACOnSystem(sdbusplus::bus_t& bus, 631bbe3d1eSWilliam A. Kennington III const nlohmann::json& configJson, 641bbe3d1eSWilliam A. Kennington III const std::string& intfname) 651bbe3d1eSWilliam A. Kennington III { 661bbe3d1eSWilliam A. Kennington III try 671bbe3d1eSWilliam A. Kennington III { 681bbe3d1eSWilliam A. Kennington III auto inventoryMAC = mac_address::getfromInventory(bus, intfname); 69bb0eaccbSWilliam A. Kennington III if (inventoryMAC != ether_addr{}) 701bbe3d1eSWilliam A. Kennington III { 71bb0eaccbSWilliam A. Kennington III auto macStr = std::to_string(inventoryMAC); 72bb0eaccbSWilliam A. Kennington III log<level::INFO>("Mac Address in Inventory on ", 731bbe3d1eSWilliam A. Kennington III entry("Interface : ", intfname.c_str()), 74bb0eaccbSWilliam A. Kennington III entry("MAC Address :", macStr.c_str())); 75bb0eaccbSWilliam A. Kennington III manager->setFistBootMACOnInterface( 76bb0eaccbSWilliam A. Kennington III std::make_pair(intfname.c_str(), std::move(macStr))); 771bbe3d1eSWilliam A. Kennington III first_boot_status.push_back(intfname.c_str()); 781bbe3d1eSWilliam A. Kennington III bool status = true; 791bbe3d1eSWilliam A. Kennington III for (const auto& keys : configJson.items()) 801bbe3d1eSWilliam A. Kennington III { 811bbe3d1eSWilliam A. Kennington III if (!(std::find(first_boot_status.begin(), 821bbe3d1eSWilliam A. Kennington III first_boot_status.end(), 831bbe3d1eSWilliam A. Kennington III keys.key()) != first_boot_status.end())) 841bbe3d1eSWilliam A. Kennington III { 851bbe3d1eSWilliam A. Kennington III log<level::INFO>("Interface MAC is NOT set from VPD"), 861bbe3d1eSWilliam A. Kennington III entry("INTERFACE", keys.key().c_str()); 871bbe3d1eSWilliam A. Kennington III status = false; 881bbe3d1eSWilliam A. Kennington III } 891bbe3d1eSWilliam A. Kennington III } 901bbe3d1eSWilliam A. Kennington III if (status) 911bbe3d1eSWilliam A. Kennington III { 921bbe3d1eSWilliam A. Kennington III log<level::INFO>("Removing the match for ethernet interfaces"); 934fd52ae4SWilliam A. Kennington III EthInterfaceMatch = nullptr; 941bbe3d1eSWilliam A. Kennington III } 951bbe3d1eSWilliam A. Kennington III } 961bbe3d1eSWilliam A. Kennington III else 971bbe3d1eSWilliam A. Kennington III { 981bbe3d1eSWilliam A. Kennington III log<level::INFO>("Nothing is present in Inventory"); 991bbe3d1eSWilliam A. Kennington III return false; 1001bbe3d1eSWilliam A. Kennington III } 1011bbe3d1eSWilliam A. Kennington III } 1021bbe3d1eSWilliam A. Kennington III catch (const std::exception& e) 1031bbe3d1eSWilliam A. Kennington III { 1041bbe3d1eSWilliam A. Kennington III log<level::ERR>("Exception occurred during getting of MAC " 1051bbe3d1eSWilliam A. Kennington III "address from Inventory"); 1061bbe3d1eSWilliam A. Kennington III return false; 1071bbe3d1eSWilliam A. Kennington III } 1081bbe3d1eSWilliam A. Kennington III return true; 1091bbe3d1eSWilliam A. Kennington III } 1101bbe3d1eSWilliam A. Kennington III 1111bbe3d1eSWilliam A. Kennington III // register the macthes to be monitored from inventory manager 112c38b0710SPatrick Williams void registerSignals(sdbusplus::bus_t& bus, const nlohmann::json& configJson) 1131bbe3d1eSWilliam A. Kennington III { 1141bbe3d1eSWilliam A. Kennington III log<level::INFO>("Registering the Inventory Signals Matcher"); 1151bbe3d1eSWilliam A. Kennington III 116c38b0710SPatrick Williams static std::unique_ptr<sdbusplus::bus::match_t> MacAddressMatch; 1171bbe3d1eSWilliam A. Kennington III 118c38b0710SPatrick Williams auto callback = [&](sdbusplus::message_t& m) { 1191bbe3d1eSWilliam A. Kennington III std::map<DbusObjectPath, 1201bbe3d1eSWilliam A. Kennington III std::map<DbusInterface, std::variant<PropertyValue>>> 1211bbe3d1eSWilliam A. Kennington III interfacesProperties; 1221bbe3d1eSWilliam A. Kennington III 1231bbe3d1eSWilliam A. Kennington III sdbusplus::message::object_path objPath; 1241bbe3d1eSWilliam A. Kennington III std::pair<std::string, std::string> ethPair; 1251bbe3d1eSWilliam A. Kennington III m.read(objPath, interfacesProperties); 1261bbe3d1eSWilliam A. Kennington III 1271bbe3d1eSWilliam A. Kennington III for (const auto& pattern : configJson.items()) 1281bbe3d1eSWilliam A. Kennington III { 1291bbe3d1eSWilliam A. Kennington III if (objPath.str.find(pattern.value()) != std::string::npos) 1301bbe3d1eSWilliam A. Kennington III { 1311bbe3d1eSWilliam A. Kennington III for (auto& interface : interfacesProperties) 1321bbe3d1eSWilliam A. Kennington III { 1331bbe3d1eSWilliam A. Kennington III if (interface.first == invNetworkIntf) 1341bbe3d1eSWilliam A. Kennington III { 1351bbe3d1eSWilliam A. Kennington III for (const auto& property : interface.second) 1361bbe3d1eSWilliam A. Kennington III { 1371bbe3d1eSWilliam A. Kennington III if (property.first == "MACAddress") 1381bbe3d1eSWilliam A. Kennington III { 1391bbe3d1eSWilliam A. Kennington III ethPair = std::make_pair( 1401bbe3d1eSWilliam A. Kennington III pattern.key(), 1411bbe3d1eSWilliam A. Kennington III std::get<std::string>(property.second)); 1421bbe3d1eSWilliam A. Kennington III break; 1431bbe3d1eSWilliam A. Kennington III } 1441bbe3d1eSWilliam A. Kennington III } 1451bbe3d1eSWilliam A. Kennington III break; 1461bbe3d1eSWilliam A. Kennington III } 1471bbe3d1eSWilliam A. Kennington III } 1481bbe3d1eSWilliam A. Kennington III if (!(ethPair.first.empty() || ethPair.second.empty())) 1491bbe3d1eSWilliam A. Kennington III { 1501bbe3d1eSWilliam A. Kennington III manager->setFistBootMACOnInterface(ethPair); 1511bbe3d1eSWilliam A. Kennington III } 1521bbe3d1eSWilliam A. Kennington III } 1531bbe3d1eSWilliam A. Kennington III } 1541bbe3d1eSWilliam A. Kennington III }; 1551bbe3d1eSWilliam A. Kennington III 156c38b0710SPatrick Williams MacAddressMatch = std::make_unique<sdbusplus::bus::match_t>( 1571bbe3d1eSWilliam A. Kennington III bus, 1581bbe3d1eSWilliam A. Kennington III "interface='org.freedesktop.DBus.ObjectManager',type='signal'," 1591bbe3d1eSWilliam A. Kennington III "member='InterfacesAdded',path='/xyz/openbmc_project/" 1601bbe3d1eSWilliam A. Kennington III "inventory'", 1611bbe3d1eSWilliam A. Kennington III callback); 1621bbe3d1eSWilliam A. Kennington III } 1631bbe3d1eSWilliam A. Kennington III 164c38b0710SPatrick Williams void watchEthernetInterface(sdbusplus::bus_t& bus, 1651bbe3d1eSWilliam A. Kennington III const nlohmann::json& configJson) 1661bbe3d1eSWilliam A. Kennington III { 167c38b0710SPatrick Williams auto mycallback = [&](sdbusplus::message_t& m) { 1681bbe3d1eSWilliam A. Kennington III std::map<DbusObjectPath, 1691bbe3d1eSWilliam A. Kennington III std::map<DbusInterface, std::variant<PropertyValue>>> 1701bbe3d1eSWilliam A. Kennington III interfacesProperties; 1711bbe3d1eSWilliam A. Kennington III 1721bbe3d1eSWilliam A. Kennington III sdbusplus::message::object_path objPath; 1731bbe3d1eSWilliam A. Kennington III std::pair<std::string, std::string> ethPair; 1741bbe3d1eSWilliam A. Kennington III m.read(objPath, interfacesProperties); 1751bbe3d1eSWilliam A. Kennington III for (const auto& interfaces : interfacesProperties) 1761bbe3d1eSWilliam A. Kennington III { 1771bbe3d1eSWilliam A. Kennington III if (interfaces.first == 1781bbe3d1eSWilliam A. Kennington III "xyz.openbmc_project.Network.EthernetInterface") 1791bbe3d1eSWilliam A. Kennington III { 1801bbe3d1eSWilliam A. Kennington III for (const auto& property : interfaces.second) 1811bbe3d1eSWilliam A. Kennington III { 1821bbe3d1eSWilliam A. Kennington III if (property.first == "InterfaceName") 1831bbe3d1eSWilliam A. Kennington III { 1841bbe3d1eSWilliam A. Kennington III std::string infname = 1851bbe3d1eSWilliam A. Kennington III std::get<std::string>(property.second); 1861bbe3d1eSWilliam A. Kennington III 1871bbe3d1eSWilliam A. Kennington III if (configJson.find(infname) == configJson.end()) 1881bbe3d1eSWilliam A. Kennington III { 1891bbe3d1eSWilliam A. Kennington III // ethernet interface not found in configJSON 1901bbe3d1eSWilliam A. Kennington III // check if it is not sit0 interface, as it is 1911bbe3d1eSWilliam A. Kennington III // expected. 1921bbe3d1eSWilliam A. Kennington III if (infname != "sit0") 1931bbe3d1eSWilliam A. Kennington III { 1941bbe3d1eSWilliam A. Kennington III log<level::ERR>( 1951bbe3d1eSWilliam A. Kennington III "Wrong Interface Name in Config Json"); 1961bbe3d1eSWilliam A. Kennington III } 1971bbe3d1eSWilliam A. Kennington III } 1981bbe3d1eSWilliam A. Kennington III else 1991bbe3d1eSWilliam A. Kennington III { 2004fd52ae4SWilliam A. Kennington III if (!setInventoryMACOnSystem(bus, configJson, 2014fd52ae4SWilliam A. Kennington III infname)) 2021bbe3d1eSWilliam A. Kennington III { 2034fd52ae4SWilliam A. Kennington III registerSignals(bus, configJson); 2044fd52ae4SWilliam A. Kennington III EthInterfaceMatch = nullptr; 2051bbe3d1eSWilliam A. Kennington III } 2061bbe3d1eSWilliam A. Kennington III } 2071bbe3d1eSWilliam A. Kennington III break; 2081bbe3d1eSWilliam A. Kennington III } 2091bbe3d1eSWilliam A. Kennington III } 2101bbe3d1eSWilliam A. Kennington III break; 2111bbe3d1eSWilliam A. Kennington III } 2121bbe3d1eSWilliam A. Kennington III } 2131bbe3d1eSWilliam A. Kennington III }; 2141bbe3d1eSWilliam A. Kennington III // Incase if phosphor-inventory-manager started early and the VPD is already 2151bbe3d1eSWilliam A. Kennington III // collected by the time network service has come up, better to check the 2161bbe3d1eSWilliam A. Kennington III // VPD directly and set the MAC Address on the respective Interface. 2171bbe3d1eSWilliam A. Kennington III 2181bbe3d1eSWilliam A. Kennington III bool registeredSignals = false; 2191bbe3d1eSWilliam A. Kennington III for (const auto& interfaceString : configJson.items()) 2201bbe3d1eSWilliam A. Kennington III { 2211bbe3d1eSWilliam A. Kennington III if (!std::filesystem::exists(firstBootPath + interfaceString.key()) && 2221bbe3d1eSWilliam A. Kennington III !registeredSignals) 2231bbe3d1eSWilliam A. Kennington III { 2241bbe3d1eSWilliam A. Kennington III 2251bbe3d1eSWilliam A. Kennington III log<level::INFO>( 2261bbe3d1eSWilliam A. Kennington III "First boot file is not present, check VPD for MAC"); 2274fd52ae4SWilliam A. Kennington III EthInterfaceMatch = std::make_unique<sdbusplus::bus::match_t>( 2281bbe3d1eSWilliam A. Kennington III bus, 2291bbe3d1eSWilliam A. Kennington III "interface='org.freedesktop.DBus.ObjectManager',type='signal'," 2301bbe3d1eSWilliam A. Kennington III "member='InterfacesAdded',path='/xyz/openbmc_project/network'", 2311bbe3d1eSWilliam A. Kennington III mycallback); 2321bbe3d1eSWilliam A. Kennington III registeredSignals = true; 2331bbe3d1eSWilliam A. Kennington III } 2341bbe3d1eSWilliam A. Kennington III } 2351bbe3d1eSWilliam A. Kennington III } 2361bbe3d1eSWilliam A. Kennington III 2371bbe3d1eSWilliam A. Kennington III #endif 2381bbe3d1eSWilliam A. Kennington III 2391bbe3d1eSWilliam A. Kennington III /** @brief refresh the network objects. */ 2401bbe3d1eSWilliam A. Kennington III void refreshObjects() 2411bbe3d1eSWilliam A. Kennington III { 2421bbe3d1eSWilliam A. Kennington III if (manager) 2431bbe3d1eSWilliam A. Kennington III { 2441bbe3d1eSWilliam A. Kennington III log<level::INFO>("Refreshing the objects."); 2451bbe3d1eSWilliam A. Kennington III manager->createChildObjects(); 2461bbe3d1eSWilliam A. Kennington III log<level::INFO>("Refreshing complete."); 2471bbe3d1eSWilliam A. Kennington III } 2481bbe3d1eSWilliam A. Kennington III } 2491bbe3d1eSWilliam A. Kennington III 250c7cf25f7SWilliam A. Kennington III void reloadNetworkd() 251c7cf25f7SWilliam A. Kennington III { 252c7cf25f7SWilliam A. Kennington III if (manager) 253c7cf25f7SWilliam A. Kennington III { 254c7cf25f7SWilliam A. Kennington III log<level::INFO>("Sending networkd reload"); 255c7cf25f7SWilliam A. Kennington III manager->doReloadConfigs(); 256c7cf25f7SWilliam A. Kennington III log<level::INFO>("Done networkd reload"); 257c7cf25f7SWilliam A. Kennington III } 258c7cf25f7SWilliam A. Kennington III } 259c7cf25f7SWilliam A. Kennington III 260*217bb3fdSWilliam A. Kennington III void initializeTimers(sdeventplus::Event& event) 2611bbe3d1eSWilliam A. Kennington III { 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 267*217bb3fdSWilliam A. Kennington III void termCb(sdeventplus::source::Signal& signal, const struct signalfd_siginfo*) 2681bbe3d1eSWilliam A. Kennington III { 269*217bb3fdSWilliam A. Kennington III log<level::NOTICE>("Got TERM, exiting"); 270*217bb3fdSWilliam A. Kennington III signal.get_event().exit(0); 2711bbe3d1eSWilliam A. Kennington III } 2721bbe3d1eSWilliam A. Kennington III 273*217bb3fdSWilliam A. Kennington III int main() 274*217bb3fdSWilliam A. Kennington III { 275*217bb3fdSWilliam A. Kennington III auto event = sdeventplus::Event::get_default(); 276*217bb3fdSWilliam A. Kennington III stdplus::signal::block(SIGTERM); 277*217bb3fdSWilliam A. Kennington III sdeventplus::source::Signal(event, SIGTERM, termCb).set_floating(true); 2781bbe3d1eSWilliam A. Kennington III 279*217bb3fdSWilliam A. Kennington III initializeTimers(event); 280*217bb3fdSWilliam A. Kennington III 281*217bb3fdSWilliam A. Kennington III auto bus = sdbusplus::bus::new_default(); 2821bbe3d1eSWilliam A. Kennington III // Attach the bus to sd_event to service user requests 283*217bb3fdSWilliam A. Kennington III bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 2841bbe3d1eSWilliam A. Kennington III 2851bbe3d1eSWilliam A. Kennington III // Add sdbusplus Object Manager for the 'root' path of the network manager. 286c38b0710SPatrick Williams sdbusplus::server::manager_t objManager(bus, DEFAULT_OBJPATH); 2871bbe3d1eSWilliam A. Kennington III bus.request_name(DEFAULT_BUSNAME); 2881bbe3d1eSWilliam A. Kennington III 2894fd52ae4SWilliam A. Kennington III manager = std::make_unique<Manager>(bus, DEFAULT_OBJPATH, NETWORK_CONF_DIR); 2901bbe3d1eSWilliam A. Kennington III 2911bbe3d1eSWilliam A. Kennington III // create the default network files if the network file 2921bbe3d1eSWilliam A. Kennington III // is not there for any interface. 2934fd52ae4SWilliam A. Kennington III if (manager->createDefaultNetworkFiles()) 2941bbe3d1eSWilliam A. Kennington III { 2954fd52ae4SWilliam A. Kennington III manager->reloadConfigs(); 2961bbe3d1eSWilliam A. Kennington III } 2971bbe3d1eSWilliam A. Kennington III 2981bbe3d1eSWilliam A. Kennington III // RTNETLINK event handler 299*217bb3fdSWilliam A. Kennington III rtnetlink::Server svr(event); 3001bbe3d1eSWilliam A. Kennington III 3011bbe3d1eSWilliam A. Kennington III #ifdef SYNC_MAC_FROM_INVENTORY 3021bbe3d1eSWilliam A. Kennington III std::ifstream in(configFile); 3031bbe3d1eSWilliam A. Kennington III nlohmann::json configJson; 3041bbe3d1eSWilliam A. Kennington III in >> configJson; 3054fd52ae4SWilliam A. Kennington III watchEthernetInterface(bus, configJson); 3061bbe3d1eSWilliam A. Kennington III #endif 307bd649af9SWilliam A. Kennington III 308bd649af9SWilliam A. Kennington III // Trigger the initial object scan 30926c40a43SWilliam A. Kennington III // This is intentionally deferred, to ensure that systemd-networkd is 31026c40a43SWilliam A. Kennington III // fully configured. 3114fd52ae4SWilliam A. Kennington III refreshObjectTimer->restartOnce(refreshTimeout); 312bd649af9SWilliam A. Kennington III 313*217bb3fdSWilliam A. Kennington III return event.loop(); 3144fd52ae4SWilliam A. Kennington III } 3154fd52ae4SWilliam A. Kennington III 3164fd52ae4SWilliam A. Kennington III } // namespace network 3174fd52ae4SWilliam A. Kennington III } // namespace phosphor 3184fd52ae4SWilliam A. Kennington III 3194fd52ae4SWilliam A. Kennington III int main(int /*argc*/, char** /*argv*/) 3204fd52ae4SWilliam A. Kennington III { 3214fd52ae4SWilliam A. Kennington III try 3224fd52ae4SWilliam A. Kennington III { 3234fd52ae4SWilliam A. Kennington III return phosphor::network::main(); 3244fd52ae4SWilliam A. Kennington III } 3254fd52ae4SWilliam A. Kennington III catch (const std::exception& e) 3264fd52ae4SWilliam A. Kennington III { 3274fd52ae4SWilliam A. Kennington III auto msg = fmt::format("FAILED: {}", e.what()); 3284fd52ae4SWilliam A. Kennington III log<level::ERR>(msg.c_str(), entry("ERROR", e.what())); 3294fd52ae4SWilliam A. Kennington III return 1; 3304fd52ae4SWilliam A. Kennington III } 3311bbe3d1eSWilliam A. Kennington III } 332