network_manager: Standardize add/remove interface
This will make it possible to hook interface creation up to netlink
Change-Id: I4a66e4aa57bf05262f38d95f40aa71dfd88a1c37
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/network_manager.cpp b/src/network_manager.cpp
index 5f80154..2d7ce98 100644
--- a/src/network_manager.cpp
+++ b/src/network_manager.cpp
@@ -124,8 +124,9 @@
}
}
-void Manager::addInterface(InterfaceInfo& info, bool enabled)
+void Manager::createInterface(const InterfaceInfo& info, bool enabled)
{
+ removeInterface(info);
config::Parser config(config::pathForIntfConf(confDir, *info.name));
auto intf = std::make_unique<EthernetInterface>(
bus, *this, info, objectPath, config, true, enabled);
@@ -134,10 +135,63 @@
intf->loadNameServers(config);
intf->loadNTPServers(config);
auto ptr = intf.get();
- interfaces.emplace(std::move(*info.name), std::move(intf));
+ interfaces.emplace(*info.name, std::move(intf));
interfacesByIdx.emplace(info.idx, ptr);
}
+void Manager::addInterface(const InterfaceInfo& info)
+{
+ auto it = systemdNetworkdEnabled.find(info.idx);
+ if (it != systemdNetworkdEnabled.end())
+ {
+ createInterface(info, it->second);
+ }
+ else
+ {
+ undiscoveredIntfInfo.insert_or_assign(info.idx, std::move(info));
+ }
+}
+
+void Manager::removeInterface(const InterfaceInfo& info)
+{
+ auto iit = interfacesByIdx.find(info.idx);
+ auto nit = interfaces.end();
+ if (info.name)
+ {
+ nit = interfaces.find(*info.name);
+ if (nit != interfaces.end() && iit != interfacesByIdx.end() &&
+ nit->second.get() != iit->second)
+ {
+ fmt::print(stderr, "Removed interface desync detected\n");
+ fflush(stderr);
+ std::abort();
+ }
+ }
+ else if (iit != interfacesByIdx.end())
+ {
+ for (nit = interfaces.begin(); nit != interfaces.end(); ++nit)
+ {
+ if (nit->second.get() == iit->second)
+ {
+ break;
+ }
+ }
+ }
+
+ if (iit != interfacesByIdx.end())
+ {
+ interfacesByIdx.erase(iit);
+ }
+ else
+ {
+ undiscoveredIntfInfo.erase(info.idx);
+ }
+ if (nit != interfaces.end())
+ {
+ interfaces.erase(nit);
+ }
+}
+
inline void getIntfOrLog(const decltype(Manager::interfacesByIdx)& intfs,
unsigned idx, auto&& cb)
{
@@ -238,15 +292,7 @@
interfacesByIdx.clear();
for (auto& info : system::getInterfaces())
{
- auto it = systemdNetworkdEnabled.find(info.idx);
- if (it != systemdNetworkdEnabled.end())
- {
- addInterface(info, it->second);
- }
- else
- {
- undiscoveredIntfInfo.insert_or_assign(info.idx, std::move(info));
- }
+ addInterface(info);
}
}
@@ -410,7 +456,7 @@
{
auto info = std::move(it->second);
undiscoveredIntfInfo.erase(it);
- addInterface(info, managed);
+ createInterface(info, managed);
}
else if (auto it = interfacesByIdx.find(ifidx);
it != interfacesByIdx.end())
diff --git a/src/network_manager.hpp b/src/network_manager.hpp
index 1b61b3b..b357107 100644
--- a/src/network_manager.hpp
+++ b/src/network_manager.hpp
@@ -64,7 +64,8 @@
void writeToConfigurationFile();
/** @brief Adds a single interface to the interface map */
- void addInterface(InterfaceInfo& info, bool enabled);
+ void addInterface(const InterfaceInfo& info);
+ void removeInterface(const InterfaceInfo& info);
/** @brief Add / remove an address to the interface or queue */
void addAddress(const AddressInfo& info);
@@ -197,6 +198,9 @@
/** @brief Handles the recipt of an adminstrative state string */
void handleAdminState(std::string_view state, unsigned ifidx);
+
+ /** @brief Creates the interface in the maps */
+ void createInterface(const InterfaceInfo& info, bool enabled);
};
} // namespace network