routing_table: Cleanup types to avoid unnecessary conversions

Change-Id: I36d430b91d606df0afdae70e2da18ae750b1df04
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index 537b7ad..9350ff7 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -100,31 +100,23 @@
     EthernetInterfaceIntf::dhcp6(dhcpVal.v6);
     EthernetInterfaceIntf::ipv6AcceptRA(getIPv6AcceptRA(config));
     EthernetInterfaceIntf::nicEnabled(enabled ? *enabled : queryNicEnabled());
-    const auto& gatewayList = manager.getRouteTable().getDefaultGateway();
-    const auto& gateway6List = manager.getRouteTable().getDefaultGateway6();
-    std::string defaultGateway;
-    std::string defaultGateway6;
-
-    for (const auto& gateway : gatewayList)
     {
-        if (gateway.first == *info.name)
+        const auto& gws = manager.getRouteTable().getDefaultGateway();
+        auto it = gws.find(ifIdx);
+        if (it != gws.end())
         {
-            defaultGateway = gateway.second;
-            break;
+            EthernetInterfaceIntf::defaultGateway(std::to_string(it->second));
+        }
+    }
+    {
+        const auto& gws = manager.getRouteTable().getDefaultGateway6();
+        auto it = gws.find(ifIdx);
+        if (it != gws.end())
+        {
+            EthernetInterfaceIntf::defaultGateway6(std::to_string(it->second));
         }
     }
 
-    for (const auto& gateway6 : gateway6List)
-    {
-        if (gateway6.first == *info.name)
-        {
-            defaultGateway6 = gateway6.second;
-            break;
-        }
-    }
-
-    EthernetInterfaceIntf::defaultGateway(defaultGateway);
-    EthernetInterfaceIntf::defaultGateway6(defaultGateway6);
     EthernetInterfaceIntf::ntpServers(
         config.map.getValueStrings("Network", "NTP"));
 
diff --git a/src/routing_table.cpp b/src/routing_table.cpp
index 39cdf2d..bed1f70 100644
--- a/src/routing_table.cpp
+++ b/src/routing_table.cpp
@@ -1,10 +1,6 @@
 #include "routing_table.hpp"
 
 #include "netlink.hpp"
-#include "types.hpp"
-#include "util.hpp"
-
-#include <net/if.h>
 
 #include <optional>
 #include <phosphor-logging/elog-errors.hpp>
@@ -24,16 +20,63 @@
 using namespace phosphor::logging;
 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
 
+template <typename Addr>
+static void parse(auto& gws, std::string_view msg)
+{
+    std::optional<unsigned> ifIdx;
+    std::optional<Addr> gw;
+    while (!msg.empty())
+    {
+        auto [hdr, data] = netlink::extractRtAttr(msg);
+        switch (hdr.rta_type)
+        {
+            case RTA_OIF:
+                ifIdx.emplace(stdplus::raw::copyFrom<int>(data));
+                break;
+            case RTA_GATEWAY:
+                gw.emplace(stdplus::raw::copyFrom<Addr>(data));
+                break;
+        }
+    }
+    if (ifIdx && gw)
+    {
+        gws.emplace(*ifIdx, *gw);
+    }
+}
+
+static void parseRoute(auto& gws4, auto& gws6, const nlmsghdr& hdr,
+                       std::string_view msg)
+{
+    if (hdr.nlmsg_type != RTM_NEWROUTE)
+    {
+        throw std::runtime_error("Not a route msg");
+    }
+    const auto& rtm = netlink::extractRtData<rtmsg>(msg);
+
+    if (rtm.rtm_table != RT_TABLE_MAIN || rtm.rtm_dst_len != 0)
+    {
+        return;
+    }
+
+    switch (rtm.rtm_family)
+    {
+        case AF_INET:
+            return parse<in_addr>(gws4, msg);
+        case AF_INET6:
+            return parse<in6_addr>(gws6, msg);
+    }
+}
+
 void Table::refresh()
 {
-    defaultGateway.clear();
-    defaultGateway6.clear();
+    gws4.clear();
+    gws6.clear();
     try
     {
         rtmsg msg{};
         netlink::performRequest(NETLINK_ROUTE, RTM_GETROUTE, NLM_F_DUMP, msg,
                                 [&](const nlmsghdr& hdr, std::string_view msg) {
-                                    this->parseRoutes(hdr, msg);
+                                    parseRoute(gws4, gws6, hdr, msg);
                                 });
     }
     catch (const std::exception& e)
@@ -42,56 +85,6 @@
         commit<InternalFailure>();
     }
 }
-
-void Table::parseRoutes(const nlmsghdr& hdr, std::string_view msg)
-{
-    std::optional<InAddrAny> dstAddr;
-    std::optional<InAddrAny> gateWayAddr;
-    char ifName[IF_NAMESIZE] = {};
-
-    if (hdr.nlmsg_type != RTM_NEWROUTE)
-    {
-        throw std::runtime_error("Not a route msg");
-    }
-    const auto& rtm = netlink::extractRtData<rtmsg>(msg);
-
-    if ((rtm.rtm_family != AF_INET && rtm.rtm_family != AF_INET6) ||
-        rtm.rtm_table != RT_TABLE_MAIN)
-    {
-        return;
-    }
-
-    while (!msg.empty())
-    {
-        auto [hdr, data] = netlink::extractRtAttr(msg);
-        switch (hdr.rta_type)
-        {
-            case RTA_OIF:
-                if_indextoname(stdplus::raw::copyFrom<int>(data), ifName);
-                break;
-            case RTA_GATEWAY:
-                gateWayAddr = addrFromBuf(rtm.rtm_family, data);
-                break;
-            case RTA_DST:
-                dstAddr = addrFromBuf(rtm.rtm_family, data);
-                break;
-        }
-    }
-
-    if (rtm.rtm_dst_len == 0 && gateWayAddr)
-    {
-        std::string ifNameStr(ifName);
-        if (rtm.rtm_family == AF_INET)
-        {
-            defaultGateway.emplace(ifNameStr, std::to_string(*gateWayAddr));
-        }
-        else if (rtm.rtm_family == AF_INET6)
-        {
-            defaultGateway6.emplace(ifNameStr, std::to_string(*gateWayAddr));
-        }
-    }
-}
-
 } // namespace route
 } // namespace network
 } // namespace phosphor
diff --git a/src/routing_table.hpp b/src/routing_table.hpp
index 45b6ec1..3650c80 100644
--- a/src/routing_table.hpp
+++ b/src/routing_table.hpp
@@ -1,9 +1,7 @@
 #pragma once
-#include <linux/netlink.h>
+#include "types.hpp"
 
-#include <map>
-#include <string>
-#include <string_view>
+#include <unordered_map>
 
 namespace phosphor
 {
@@ -24,7 +22,7 @@
      */
     inline const auto& getDefaultGateway() const
     {
-        return defaultGateway;
+        return gws4;
     }
 
     /**
@@ -34,19 +32,12 @@
      */
     inline const auto& getDefaultGateway6() const
     {
-        return defaultGateway6;
+        return gws6;
     };
 
   private:
-    /**
-     * @brief Parse the route and add it to the route list.
-     *
-     * @param[in] nlHdr - net link message header.
-     */
-    void parseRoutes(const struct nlmsghdr& nlHdr, std::string_view msg);
-
-    std::map<std::string, std::string> defaultGateway;  // default gateway list
-    std::map<std::string, std::string> defaultGateway6; // default gateway list
+    std::unordered_map<unsigned, in_addr> gws4;
+    std::unordered_map<unsigned, in6_addr> gws6;
 };
 
 } // namespace route
diff --git a/test/mock_syscall.cpp b/test/mock_syscall.cpp
index bf68d47..d16b668 100644
--- a/test/mock_syscall.cpp
+++ b/test/mock_syscall.cpp
@@ -30,13 +30,11 @@
 using phosphor::network::system::InterfaceInfo;
 
 std::map<std::string, InterfaceInfo> mock_if;
-std::map<int, std::string> mock_if_indextoname;
 
 void phosphor::network::system::mock_clear()
 {
     mock_rtnetlinks.clear();
     mock_if.clear();
-    mock_if_indextoname.clear();
 }
 
 void phosphor::network::system::mock_addIF(const InterfaceInfo& info)
@@ -53,7 +51,6 @@
         }
     }
     mock_if.emplace(info.name.value(), info);
-    mock_if_indextoname.emplace(info.idx, info.name.value());
 }
 
 void validateMsgHdr(const struct msghdr* msg)
@@ -156,17 +153,6 @@
 
 extern "C" {
 
-char* if_indextoname(unsigned ifindex, char* ifname)
-{
-    auto it = mock_if_indextoname.find(ifindex);
-    if (it == mock_if_indextoname.end())
-    {
-        errno = ENXIO;
-        return NULL;
-    }
-    return std::strcpy(ifname, it->second.c_str());
-}
-
 int ioctl(int fd, unsigned long int request, ...)
 {
     va_list vl;