Implement the ipaddress origin and gateway property

Resolves openbmc/openbmc#1590

Change-Id: I76328e596336f8b8f1394b1927d48ce52f819a66
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index 0ec3f67..c824919 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -2,6 +2,7 @@
 #include "ipaddress.hpp"
 #include "ethernet_interface.hpp"
 #include "network_manager.hpp"
+#include "routing_table.hpp"
 
 #include <phosphor-logging/log.hpp>
 
@@ -52,18 +53,28 @@
 
     IP::Protocol addressType = IP::Protocol::IPv4;
     IP::AddressOrigin origin = IP::AddressOrigin::Static;
-
+    route::Table routingTable;
     for (auto addr : addrs)
     {
         if (addr.addrType == AF_INET6)
         {
             addressType = IP::Protocol::IPv6;
         }
+        if (dHCPEnabled())
+        {
+            origin = IP::AddressOrigin::DHCP;
+        }
+        else if (isLinkLocal(addr.ipaddress))
+        {
+            origin = IP::AddressOrigin::LinkLocal;
+        }
+        gateway = routingTable.getGateway(addr.addrType, addr.ipaddress, addr.prefix);
 
         std::string ipAddressObjectPath = generateObjectPath(addressType,
                                                              addr.ipaddress,
                                                              addr.prefix,
                                                              gateway);
+
         this->addrs.emplace(
                 std::make_pair(
                     addr.ipaddress,
@@ -77,6 +88,12 @@
                         addr.prefix,
                         gateway)));
     }
+
+    // TODO:- will move the default gateway to conf object
+    // once we implement that.
+
+    // TODO: openbmc/openbmc#1295
+    manager.defaultGateway = routingTable.getDefaultGateway();
 }
 
 void EthernetInterface::iP(IP::Protocol protType,
@@ -84,6 +101,12 @@
                            uint8_t prefixLength,
                            std::string gateway)
 {
+
+    if (dHCPEnabled())
+    {
+        return;
+    }
+
     IP::AddressOrigin origin = IP::AddressOrigin::Static;
 
     std::string objectPath = generateObjectPath(protType,
@@ -224,17 +247,17 @@
 
     // Only want 8 hex digits.
     hexId << std::hex << ((std::hash<std::string> {}(
-                              hashString)) & 0xFFFFFFFF);
+                               hashString)) & 0xFFFFFFFF);
     return hexId.str();
 }
 
 void EthernetInterface::deleteObject(const std::string& ipaddress)
 {
     auto it = addrs.find(ipaddress);
-    if( it == addrs.end())
+    if (it == addrs.end())
     {
-         log<level::ERR>("DeleteObject:Unable to find the object.");
-         return;
+        log<level::ERR>("DeleteObject:Unable to find the object.");
+        return;
     }
     this->addrs.erase(it);
     manager.writeToConfigurationFile();
diff --git a/network_manager.cpp b/network_manager.cpp
index a5ff5e3..a635952 100644
--- a/network_manager.cpp
+++ b/network_manager.cpp
@@ -242,6 +242,30 @@
 
             }
         }
+
+        stream << "Gateway=" << this->defaultGateway << "\n";
+        stream << "[" << "Route" << "]\n";
+        for(const auto& addr : addrs)
+        {
+            if (addr.second->origin() == AddressOrigin::Static)
+            {
+                int addressFamily = addr.second->type() == IP::Protocol::IPv4 ? AF_INET : AF_INET6;
+                std::string destination = getNetworkID(
+                                            addressFamily,
+                                            addr.second->address(),
+                                            addr.second->prefixLength());
+
+                if (addr.second->gateway() != "0.0.0.0" ||
+                    addr.second->gateway() != "")
+                {
+
+                    stream << "Gateway=" << addr.second->gateway() << "\n";
+                    stream << "Destination=" << destination << "\n";
+                }
+
+            }
+        }
+
         stream.close();
     }
     restartSystemdNetworkd();
diff --git a/network_manager.hpp b/network_manager.hpp
index bdee889..b19ec72 100644
--- a/network_manager.hpp
+++ b/network_manager.hpp
@@ -86,7 +86,11 @@
          */
         void createInterfaces();
 
-
+        /** TODO: would remove it once we implement the system
+         *  conf dbus object.
+         *  openbmc/openbmc#1295
+         */
+        std::string defaultGateway; // default gateway
     private:
         /** @brief Get all the interfaces from the system.
          *  @returns list of interface names.
diff --git a/test/Makefile.am b/test/Makefile.am
index 1fd0f33..9736ccd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -11,6 +11,7 @@
 	test_ethernet_interface.cpp
 
 test_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS)
+
 test_CXXFLAGS = $(PTHREAD_CFLAGS) \
 				$(SYSTEMD_CFLAGS) \
 				$(SDBUSPLUS_CFLAGS) \
@@ -28,6 +29,7 @@
 			$(top_builddir)/network_manager.cpp \
 			$(top_builddir)/network_config.cpp \
 			$(top_builddir)/ipaddress.cpp \
+			$(top_builddir)/routing_table.cpp \
 			$(top_builddir)/util.cpp \
 			$(top_builddir)/xyz/openbmc_project/Network/VLAN/Create/phosphor_network_manager-server.o \
 			$(top_builddir)/xyz/openbmc_project/Network/IP/Create/phosphor_network_manager-server.o