Get DHCP configuration values form n/w config file while creating
DHCP config object.

Each time when we update config file we recreate DHCP config object,
with existing code DHCP configuration values are getting initialized
to default values.
With these changes we get DHCP configuration values from n/w config.

Resolves openbmc/openbmc#2891

Change-Id: I95d50d52a8aa569493739a46b88e4a378e399698
Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
diff --git a/dhcp_configuration.cpp b/dhcp_configuration.cpp
index 9eeea1e..e933161 100644
--- a/dhcp_configuration.cpp
+++ b/dhcp_configuration.cpp
@@ -1,6 +1,9 @@
 #include "config.h"
 #include "dhcp_configuration.hpp"
 #include "network_manager.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
 
 namespace phosphor
 {
@@ -9,6 +12,9 @@
 namespace dhcp
 {
 
+using namespace phosphor::network;
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
 bool Configuration::sendHostNameEnabled(bool value)
 {
     if (value == sendHostNameEnabled())
@@ -66,6 +72,39 @@
     return dns;
 }
 
+bool Configuration::getDHCPPropFromConf(const std::string& prop)
+{
+    fs::path confPath = manager.getConfDir();
+    auto interfaceStrList = getInterfaces();
+    // get the first interface name, we need it to know config file name.
+    auto interface = *interfaceStrList.begin();
+    auto fileName = systemd::config::networkFilePrefix + interface +
+            systemd::config::networkFileSuffix;
+
+    confPath /= fileName;
+    // systemd default behaviour is all DHCP fields should be enabled by
+    // default.
+    auto propValue = true;
+    config::Parser parser(confPath);
+
+    auto rc = config::ReturnCode::SUCCESS;
+    config::ValueList values{};
+    std::tie(rc, values) = parser.getValues("DHCP", prop);
+
+    if (rc != config::ReturnCode::SUCCESS)
+    {
+        log<level::DEBUG>("Unable to get the value from section DHCP",
+                          entry("PROP=%s", prop.c_str()),
+                          entry("RC=%d", rc));
+        return propValue;
+    }
+
+    if (values[0] == "false")
+    {
+        propValue = false;
+    }
+    return propValue;
+}
 }// namespace dhcp
 }// namespace network
 }// namespace phosphor
diff --git a/dhcp_configuration.hpp b/dhcp_configuration.hpp
index a550077..5db88e9 100644
--- a/dhcp_configuration.hpp
+++ b/dhcp_configuration.hpp
@@ -3,6 +3,7 @@
 #include "xyz/openbmc_project/Network/DHCPConfiguration/server.hpp"
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/server/object.hpp>
+#include "config_parser.hpp"
 
 #include <string>
 
@@ -50,13 +51,10 @@
             bus(bus),
             manager(parent)
         {
-            // systemd default behaviour is following fields should be
-            // enabled by default.
-
-            ConfigIntf::dNSEnabled(true);
-            ConfigIntf::nTPEnabled(true);
-            ConfigIntf::hostNameEnabled(true);
-            ConfigIntf::sendHostNameEnabled(true);
+            ConfigIntf::dNSEnabled(getDHCPPropFromConf("UseDNS"));
+            ConfigIntf::nTPEnabled(getDHCPPropFromConf("UseNTP"));
+            ConfigIntf::hostNameEnabled(getDHCPPropFromConf("UseHostname"));
+            ConfigIntf::sendHostNameEnabled(getDHCPPropFromConf("SendHostname"));
             emit_object_added();
         }
 
@@ -90,6 +88,11 @@
          */
         bool sendHostNameEnabled(bool value) override;
 
+        /** @brief read the DHCP Prop value from the configuration file
+         *  @param[in] prop - DHCP Prop name.
+         */
+        bool getDHCPPropFromConf(const std::string& prop);
+
         /* @brief Network Manager needed the below function to know the
          *        value of the properties (ntpEnabled,dnsEnabled,hostnameEnabled
                   sendHostNameEnabled).
diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp
index 7d13c1c..74c30c5 100644
--- a/ethernet_interface.cpp
+++ b/ethernet_interface.cpp
@@ -564,77 +564,78 @@
         stream << "VLAN=" << intf.second->EthernetInterface::interfaceName()
             << "\n";
     }
-
-    // DHCP
-    if (dHCPEnabled() == true)
+    // When the interface configured as dhcp, we don't need below given entries
+    // in config file.
+    if (dHCPEnabled() == false)
     {
-        // write the dhcp section if interface is
-        // configured as dhcp.
-        writeDHCPSection(stream);
-        stream.close();
-        return;
-    }
-
-    //Add the NTP server
-    for(const auto& ntp: EthernetInterfaceIntf::nTPServers())
-    {
-         stream << "NTP=" << ntp << "\n";
-    }
-
-    //Add the DNS entry
-    for(const auto& dns: EthernetInterfaceIntf::nameservers())
-    {
-         stream << "DNS=" << dns << "\n";
-    }
-
-    // Static
-    for (const auto& addr : addrs)
-    {
-        if (addr.second->origin() == AddressOrigin::Static)
+        //Add the NTP server
+        for (const auto& ntp : EthernetInterfaceIntf::nTPServers())
         {
-            std::string address = addr.second->address() + "/" + std::to_string(
-                                      addr.second->prefixLength());
+            stream << "NTP=" << ntp << "\n";
+        }
 
-            stream << "Address=" << address << "\n";
-         }
-    }
-
-    if (manager.getSystemConf())
-    {
-        stream << "Gateway=" << manager.getSystemConf()->defaultGateway()
-            << "\n";
-    }
-    // write the route section
-    stream << "[" << "Route" << "]\n";
-    for(const auto& addr : addrs)
-    {
-        if (addr.second->origin() == AddressOrigin::Static)
+        //Add the DNS entry
+        for (const auto& dns : EthernetInterfaceIntf::nameservers())
         {
-            int addressFamily = addr.second->type() == IP::Protocol::IPv4 ? AF_INET : AF_INET6;
-            std::string destination = getNetworkID(
-                    addressFamily,
-                    addr.second->address(),
-                    addr.second->prefixLength());
+            stream << "DNS=" << dns << "\n";
+        }
 
-            if (addr.second->gateway() != "0.0.0.0" &&
-                addr.second->gateway() != "" &&
-                destination != "0.0.0.0" &&
-                destination != "")
+        // Static
+        for (const auto& addr : addrs)
+        {
+            if (addr.second->origin() == AddressOrigin::Static)
             {
-                stream << "Gateway=" << addr.second->gateway() << "\n";
-                stream << "Destination=" << destination << "\n";
-            }
+                std::string address = addr.second->address() + "/" +
+                                    std::to_string(addr.second->prefixLength());
 
+                stream << "Address=" << address << "\n";
+            }
+        }
+
+        if (manager.getSystemConf())
+        {
+            stream << "Gateway=" << manager.getSystemConf()->defaultGateway()
+                   << "\n";
+        }
+
+        // write the route section
+        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() != "" &&
+                    destination != "0.0.0.0" &&
+                    destination != "")
+                {
+                    stream << "Gateway=" << addr.second->gateway() << "\n";
+                    stream << "Destination=" << destination << "\n";
+                }
+            }
         }
     }
 
+    auto value = dHCPEnabled() ? "true"s : "false"s;
+    stream << "DHCP="s + value + "\n";
+
+    // Write the dhcp section irrespective of whether DHCP is enabled or not
+    writeDHCPSection(stream);
+
     stream.close();
 }
 
 void EthernetInterface::writeDHCPSection(std::fstream& stream)
 {
     using namespace std::string_literals;
-    stream << "DHCP=true\n";
     // write the dhcp section
     stream << "[DHCP]\n";