ipaddress: Parse from netlink

This improves on the old code for enumerating IP addresses by allowing
the application of filtering rules prior to listing out the IPs. The
netlink interface provides the information in a more direct form with
less superfluous enumeration of data about the address.

This will be required to determine deprecated / dynamic addresses from
static ones with IPv6.

Change-Id: I8ff2408b58921a82fd556d8ed08c203171c88035
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index 8700d05..a1d9b83 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -3,8 +3,10 @@
 #include "ethernet_interface.hpp"
 
 #include "config_parser.hpp"
+#include "ipaddress.hpp"
 #include "neighbor.hpp"
 #include "network_manager.hpp"
+#include "types.hpp"
 #include "vlan_interface.hpp"
 
 #include <arpa/inet.h>
@@ -125,17 +127,18 @@
     }
 }
 
-static IP::Protocol convertFamily(int family)
+static IP::Protocol getProtocol(const InAddrAny& addr)
 {
-    switch (family)
+    if (std::holds_alternative<in_addr>(addr))
     {
-        case AF_INET:
-            return IP::Protocol::IPv4;
-        case AF_INET6:
-            return IP::Protocol::IPv6;
+        return IP::Protocol::IPv4;
+    }
+    else if (std::holds_alternative<in6_addr>(addr))
+    {
+        return IP::Protocol::IPv6;
     }
 
-    throw std::invalid_argument("Bad address family");
+    throw std::runtime_error("Invalid addr type");
 }
 
 void EthernetInterface::disableDHCP(IP::Protocol protocol)
@@ -191,17 +194,19 @@
 {
     addrs.clear();
 
-    auto addrs = getInterfaceAddrs()[interfaceName()];
-
-    for (auto& addr : addrs)
+    AddressFilter filter;
+    filter.interface = ifIndex();
+    auto currentAddrs = getCurrentAddresses(filter);
+    for (const auto& addr : currentAddrs)
     {
-        IP::Protocol addressType = convertFamily(addr.addrType);
+        auto address = toString(addr.address);
+        IP::Protocol addressType = getProtocol(addr.address);
         IP::AddressOrigin origin = IP::AddressOrigin::Static;
         if (dhcpIsEnabled(addressType))
         {
             origin = IP::AddressOrigin::DHCP;
         }
-        if (isLinkLocalIP(addr.ipaddress))
+        if (addr.scope == RT_SCOPE_LINK)
         {
             origin = IP::AddressOrigin::LinkLocal;
         }
@@ -209,13 +214,12 @@
         std::string gateway = "";
 
         std::string ipAddressObjectPath = generateObjectPath(
-            addressType, addr.ipaddress, addr.prefix, gateway, origin);
+            addressType, address, addr.prefix, gateway, origin);
 
         this->addrs.insert_or_assign(
-            addr.ipaddress,
-            std::make_shared<phosphor::network::IPAddress>(
-                bus, ipAddressObjectPath.c_str(), *this, addressType,
-                addr.ipaddress, origin, addr.prefix, gateway));
+            address, std::make_shared<phosphor::network::IPAddress>(
+                         bus, ipAddressObjectPath.c_str(), *this, addressType,
+                         address, origin, addr.prefix, gateway));
     }
 }