network_manager: Support queueing additional interface data

This allows us to queue up all the interface properties before
systemd-networkd returns that it has managed the interface. Otherwise,
we will lose information about the addrs / routes / neighs on the
interface while waiting.

Change-Id: I9301f8e129fa51cf5e8d5a80235bf889841b076e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/network_manager.cpp b/src/network_manager.cpp
index 2d7ce98..79a4e41 100644
--- a/src/network_manager.cpp
+++ b/src/network_manager.cpp
@@ -124,19 +124,19 @@
     }
 }
 
-void Manager::createInterface(const InterfaceInfo& info, bool enabled)
+void Manager::createInterface(const UndiscoveredInfo& info, bool enabled)
 {
-    removeInterface(info);
-    config::Parser config(config::pathForIntfConf(confDir, *info.name));
+    removeInterface(info.intf);
+    config::Parser config(config::pathForIntfConf(confDir, *info.intf.name));
     auto intf = std::make_unique<EthernetInterface>(
-        bus, *this, info, objectPath, config, true, enabled);
+        bus, *this, info.intf, objectPath, config, true, enabled);
     intf->createIPAddressObjects();
     intf->createStaticNeighborObjects();
     intf->loadNameServers(config);
     intf->loadNTPServers(config);
     auto ptr = intf.get();
-    interfaces.emplace(*info.name, std::move(intf));
-    interfacesByIdx.emplace(info.idx, ptr);
+    interfaces.insert_or_assign(*info.intf.name, std::move(intf));
+    interfacesByIdx.insert_or_assign(info.intf.idx, ptr);
 }
 
 void Manager::addInterface(const InterfaceInfo& info)
@@ -144,11 +144,12 @@
     auto it = systemdNetworkdEnabled.find(info.idx);
     if (it != systemdNetworkdEnabled.end())
     {
-        createInterface(info, it->second);
+        createInterface({info}, it->second);
     }
     else
     {
-        undiscoveredIntfInfo.insert_or_assign(info.idx, std::move(info));
+        undiscoveredIntfInfo.insert_or_assign(
+            info.idx, UndiscoveredInfo{std::move(info)});
     }
 }
 
diff --git a/src/network_manager.hpp b/src/network_manager.hpp
index b357107..3f0eaab 100644
--- a/src/network_manager.hpp
+++ b/src/network_manager.hpp
@@ -187,7 +187,15 @@
     route::Table routeTable;
 
     /** @brief Map of interface info for undiscovered interfaces */
-    std::unordered_map<unsigned, InterfaceInfo> undiscoveredIntfInfo;
+    struct UndiscoveredInfo
+    {
+        InterfaceInfo intf;
+        std::optional<in_addr> defgw4 = std::nullopt;
+        std::optional<in6_addr> defgw6 = std::nullopt;
+        std::unordered_map<IfAddr, AddressInfo> addrs = {};
+        std::unordered_map<InAddrAny, NeighborInfo> staticNeighs = {};
+    };
+    std::unordered_map<unsigned, UndiscoveredInfo> undiscoveredIntfInfo;
 
     /** @brief Map of enabled interfaces */
     std::unordered_map<unsigned, bool> systemdNetworkdEnabled;
@@ -200,7 +208,7 @@
     void handleAdminState(std::string_view state, unsigned ifidx);
 
     /** @brief Creates the interface in the maps */
-    void createInterface(const InterfaceInfo& info, bool enabled);
+    void createInterface(const UndiscoveredInfo& info, bool enabled);
 };
 
 } // namespace network