1 #include "config.h" 2 3 #include "network_manager.hpp" 4 5 #include "config_parser.hpp" 6 #include "ipaddress.hpp" 7 #include "system_queries.hpp" 8 #include "types.hpp" 9 10 #include <filesystem> 11 #include <fstream> 12 #include <phosphor-logging/elog-errors.hpp> 13 #include <phosphor-logging/log.hpp> 14 #include <xyz/openbmc_project/Common/error.hpp> 15 16 constexpr char SYSTEMD_BUSNAME[] = "org.freedesktop.systemd1"; 17 constexpr char SYSTEMD_PATH[] = "/org/freedesktop/systemd1"; 18 constexpr char SYSTEMD_INTERFACE[] = "org.freedesktop.systemd1.Manager"; 19 constexpr auto FirstBootFile = "/var/lib/network/firstBoot_"; 20 21 constexpr char NETWORKD_BUSNAME[] = "org.freedesktop.network1"; 22 constexpr char NETWORKD_PATH[] = "/org/freedesktop/network1"; 23 constexpr char NETWORKD_INTERFACE[] = "org.freedesktop.network1.Manager"; 24 25 namespace phosphor 26 { 27 namespace network 28 { 29 30 extern std::unique_ptr<Timer> refreshObjectTimer; 31 extern std::unique_ptr<Timer> reloadTimer; 32 using namespace phosphor::logging; 33 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 34 using Argument = xyz::openbmc_project::Common::InvalidArgument; 35 36 Manager::Manager(sdbusplus::bus_t& bus, const char* objPath, 37 const fs::path& confDir) : 38 details::VLANCreateIface(bus, objPath, 39 details::VLANCreateIface::action::defer_emit), 40 bus(bus), objectPath(objPath) 41 { 42 setConfDir(confDir); 43 } 44 45 void Manager::setConfDir(const fs::path& dir) 46 { 47 confDir = dir; 48 49 if (!fs::exists(confDir)) 50 { 51 if (!fs::create_directories(confDir)) 52 { 53 log<level::ERR>("Unable to create the network conf dir", 54 entry("DIR=%s", confDir.c_str())); 55 elog<InternalFailure>(); 56 } 57 } 58 } 59 60 void Manager::createInterfaces() 61 { 62 // clear all the interfaces first 63 interfaces.clear(); 64 interfacesByIdx.clear(); 65 for (auto& interface : system::getInterfaces()) 66 { 67 config::Parser config( 68 config::pathForIntfConf(confDir, *interface.name)); 69 auto intf = std::make_unique<EthernetInterface>(bus, *this, interface, 70 objectPath, config); 71 intf->createIPAddressObjects(); 72 intf->createStaticNeighborObjects(); 73 intf->loadNameServers(config); 74 intf->loadNTPServers(config); 75 auto ptr = intf.get(); 76 interfaces.emplace(std::move(*interface.name), std::move(intf)); 77 interfacesByIdx.emplace(interface.idx, ptr); 78 } 79 } 80 81 void Manager::createChildObjects() 82 { 83 routeTable.refresh(); 84 85 // creates the ethernet interface dbus object. 86 createInterfaces(); 87 88 systemConf.reset(nullptr); 89 dhcpConf.reset(nullptr); 90 91 fs::path objPath = objectPath; 92 objPath /= "config"; 93 94 // create the system conf object. 95 systemConf = std::make_unique<phosphor::network::SystemConfiguration>( 96 bus, objPath.string()); 97 // create the dhcp conf object. 98 objPath /= "dhcp"; 99 dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>( 100 bus, objPath.string(), *this); 101 } 102 103 ObjectPath Manager::vlan(std::string interfaceName, uint32_t id) 104 { 105 if (id == 0 || id >= 4095) 106 { 107 log<level::ERR>("VLAN ID is not valid", entry("VLANID=%u", id)); 108 elog<InvalidArgument>( 109 Argument::ARGUMENT_NAME("VLANId"), 110 Argument::ARGUMENT_VALUE(std::to_string(id).c_str())); 111 } 112 113 auto it = interfaces.find(interfaceName); 114 if (it == interfaces.end()) 115 { 116 using ResourceErr = 117 phosphor::logging::xyz::openbmc_project::Common::ResourceNotFound; 118 elog<ResourceNotFound>(ResourceErr::RESOURCE(interfaceName.c_str())); 119 } 120 return it->second->createVLAN(id); 121 } 122 123 void Manager::reset() 124 { 125 if (fs::is_directory(confDir)) 126 { 127 for (const auto& file : fs::directory_iterator(confDir)) 128 { 129 fs::remove(file.path()); 130 } 131 } 132 log<level::INFO>("Network Factory Reset queued."); 133 } 134 135 // Need to merge the below function with the code which writes the 136 // config file during factory reset. 137 // TODO openbmc/openbmc#1751 138 void Manager::writeToConfigurationFile() 139 { 140 // write all the static ip address in the systemd-network conf file 141 for (const auto& intf : interfaces) 142 { 143 intf.second->writeConfigurationFile(); 144 } 145 } 146 147 #ifdef SYNC_MAC_FROM_INVENTORY 148 void Manager::setFistBootMACOnInterface( 149 const std::pair<std::string, std::string>& inventoryEthPair) 150 { 151 for (const auto& interface : interfaces) 152 { 153 if (interface.first == inventoryEthPair.first) 154 { 155 auto returnMAC = 156 interface.second->macAddress(inventoryEthPair.second); 157 if (returnMAC == inventoryEthPair.second) 158 { 159 log<level::INFO>("Set the MAC on "), 160 entry("interface : ", interface.first.c_str()), 161 entry("MAC : ", inventoryEthPair.second.c_str()); 162 std::error_code ec; 163 if (std::filesystem::is_directory("/var/lib/network", ec)) 164 { 165 std::ofstream persistentFile(FirstBootFile + 166 interface.first); 167 } 168 break; 169 } 170 else 171 { 172 log<level::INFO>("MAC is Not Set on ethernet Interface"); 173 } 174 } 175 } 176 } 177 178 #endif 179 180 void Manager::reloadConfigsNoRefresh() 181 { 182 reloadTimer->restartOnce(reloadTimeout); 183 } 184 185 void Manager::reloadConfigs() 186 { 187 reloadConfigsNoRefresh(); 188 // Ensure that the next refresh happens after reconfiguration 189 refreshObjectTimer->setRemaining(reloadTimeout + refreshTimeout); 190 } 191 192 void Manager::doReloadConfigs() 193 { 194 for (auto& hook : reloadPreHooks) 195 { 196 try 197 { 198 hook(); 199 } 200 catch (const std::exception& ex) 201 { 202 log<level::ERR>("Failed executing reload hook, ignoring", 203 entry("ERR=%s", ex.what())); 204 } 205 } 206 reloadPreHooks.clear(); 207 try 208 { 209 auto method = bus.new_method_call(NETWORKD_BUSNAME, NETWORKD_PATH, 210 NETWORKD_INTERFACE, "Reload"); 211 bus.call_noreply(method); 212 } 213 catch (const sdbusplus::exception_t& ex) 214 { 215 log<level::ERR>("Failed to reload configuration", 216 entry("ERR=%s", ex.what())); 217 elog<InternalFailure>(); 218 } 219 // Ensure reconfiguration has enough time 220 if (refreshObjectTimer->isEnabled()) 221 { 222 refreshObjectTimer->setRemaining(refreshTimeout); 223 } 224 } 225 226 } // namespace network 227 } // namespace phosphor 228