ethernet_interface: Reduce error logspam

Change-Id: I53c78556c576f60a6fc1ae74e90d50873f042c35
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index a29bced..e4ab5b5 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -109,9 +109,9 @@
     EthernetInterfaceIntf::defaultGateway6(defaultGateway6);
     // Don't get the mac address from the system as the mac address
     // would be same as parent interface.
-    if (intfName.find(".") == std::string::npos)
+    if (intfName.find(".") == std::string::npos && ifIdx > 0)
     {
-        auto mac = ignoreError("getMAC", intfName, std::nullopt,
+        auto mac = ignoreError("GetMAC", intfName, std::nullopt,
                                [&] { return system::getMAC(intfName); });
         if (mac)
         {
@@ -124,10 +124,14 @@
     EthernetInterfaceIntf::linkUp(linkUp());
     EthernetInterfaceIntf::mtu(mtu());
 
-    auto ethInfo = ignoreError("GetEthInfo", intfName, {},
-                               [&] { return system::getEthInfo(intfName); });
-    EthernetInterfaceIntf::autoNeg(ethInfo.autoneg);
-    EthernetInterfaceIntf::speed(ethInfo.speed);
+    if (ifIdx > 0)
+    {
+        auto ethInfo = ignoreError("GetEthInfo", intfName, {}, [&] {
+            return system::getEthInfo(intfName);
+        });
+        EthernetInterfaceIntf::autoNeg(ethInfo.autoneg);
+        EthernetInterfaceIntf::speed(ethInfo.speed);
+    }
 
     // Emit deferred signal.
     if (emitSignal)
@@ -487,13 +491,21 @@
 
 bool EthernetInterface::linkUp() const
 {
+    if (ifIdx == 0)
+    {
+        return EthernetInterfaceIntf::linkUp();
+    }
     return system::intfIsRunning(interfaceName());
 }
 
 size_t EthernetInterface::mtu() const
 {
+    if (ifIdx == 0)
+    {
+        return EthernetInterfaceIntf::mtu();
+    }
     const auto ifname = interfaceName();
-    return ignoreError("getMTU", ifname, std::nullopt,
+    return ignoreError("GetMTU", ifname, std::nullopt,
                        [&] { return system::getMTU(ifname); })
         .value_or(EthernetInterfaceIntf::mtu());
 }
@@ -506,7 +518,7 @@
         return value;
     }
     const auto ifname = interfaceName();
-    return EthernetInterfaceIntf::mtu(ignoreError("setMTU", ifname, old, [&] {
+    return EthernetInterfaceIntf::mtu(ignoreError("SetMTU", ifname, old, [&] {
         system::setMTU(ifname, value);
         return value;
     }));
diff --git a/src/system_queries.cpp b/src/system_queries.cpp
index f02d568..0aa245e 100644
--- a/src/system_queries.cpp
+++ b/src/system_queries.cpp
@@ -57,6 +57,9 @@
 {
     ifreq ifr;
     std::optional<decltype(complete(ifr))> ret;
+    auto ukey = std::make_tuple(std::string(ifname), cmd);
+    static std::unordered_set<std::tuple<std::string, unsigned long long>>
+        unsupported;
     try
     {
         ifr = executeIFReq(ifname, cmd, data);
@@ -65,13 +68,19 @@
     {
         if (e.code() == std::errc::operation_not_supported)
         {
-            auto msg = fmt::format("{} not supported on {}", cmdname, ifname);
-            log<level::INFO>(msg.c_str(),
-                             entry("INTERFACE=%s", ifname.c_str()));
+            if (unsupported.find(ukey) == unsupported.end())
+            {
+                unsupported.emplace(std::move(ukey));
+                auto msg =
+                    fmt::format("{} not supported on {}", cmdname, ifname);
+                log<level::INFO>(msg.c_str(),
+                                 entry("INTERFACE=%s", ifname.c_str()));
+            }
             return ret;
         }
         throw;
     }
+    unsupported.erase(ukey);
     ret.emplace(complete(ifr));
     return ret;
 }
diff --git a/src/types.hpp b/src/types.hpp
index 7d77ffc..a78253c 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -50,13 +50,13 @@
 using string_uset =
     std::unordered_set<std::string, string_hash, std::equal_to<>>;
 
-constexpr std::size_t hash_multi()
+constexpr std::size_t hash_multi() noexcept
 {
     return 0;
 }
 
 template <typename T, typename... Args>
-constexpr std::size_t hash_multi(const T& v, Args... args)
+constexpr std::size_t hash_multi(const T& v, Args... args) noexcept
 {
     const std::size_t seed = hash_multi(args...);
     return seed ^ (std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
@@ -64,3 +64,12 @@
 
 } // namespace network
 } // namespace phosphor
+
+template <typename... Ts>
+struct std::hash<std::tuple<Ts...>>
+{
+    constexpr auto operator()(const std::tuple<Ts...>& t) const noexcept
+    {
+        return std::apply(phosphor::network::hash_multi<Ts...>, t);
+    }
+};