diff --git a/src/argument.cpp b/src/argument.cpp
new file mode 100644
index 0000000..bcd5a13
--- /dev/null
+++ b/src/argument.cpp
@@ -0,0 +1,99 @@
+/**
+ * Copyright © 2018 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "argument.hpp"
+
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+
+namespace phosphor
+{
+namespace network
+{
+namespace ncsi
+{
+
+ArgumentParser::ArgumentParser(int argc, char** argv)
+{
+    int option = 0;
+    while (-1 != (option = getopt_long(argc, argv, optionStr, options, NULL)))
+    {
+        if ((option == '?') || (option == 'h'))
+        {
+            usage(argv);
+            exit(-1);
+        }
+
+        auto i = &options[0];
+        while ((i->val != option) && (i->val != 0))
+        {
+            ++i;
+        }
+
+        if (i->val)
+        {
+            arguments[i->name] = (i->has_arg ? optarg : trueString);
+        }
+    }
+}
+
+const std::string& ArgumentParser::operator[](const std::string& opt)
+{
+    auto i = arguments.find(opt);
+    if (i == arguments.end())
+    {
+        return emptyString;
+    }
+    else
+    {
+        return i->second;
+    }
+}
+
+void ArgumentParser::usage(char** argv)
+{
+    std::cerr << "Usage: " << argv[0] << " [options]\n";
+    std::cerr << "Options:\n";
+    std::cerr << "    --help            Print this menu.\n";
+    std::cerr << "    --info=<info>     Retrieve info about NCSI topology.\n";
+    std::cerr << "    --set=<set>       Set a specific package/channel.\n";
+    std::cerr
+        << "    --clear=<clear>   Clear all the settings on the interface.\n";
+    std::cerr << "    --package=<package>  Specify a package.\n";
+    std::cerr << "    --channel=<channel> Specify a channel.\n";
+    std::cerr << "    --index=<device index> Specify device ifindex.\n";
+    std::cerr << std::flush;
+}
+
+const option ArgumentParser::options[] = {
+    {"info", no_argument, NULL, 'i'},
+    {"set", no_argument, NULL, 's'},
+    {"clear", no_argument, NULL, 'r'},
+    {"package", required_argument, NULL, 'p'},
+    {"channel", required_argument, NULL, 'c'},
+    {"index", required_argument, NULL, 'x'},
+    {"help", no_argument, NULL, 'h'},
+    {0, 0, 0, 0},
+};
+
+const char* ArgumentParser::optionStr = "i:s:r:p:c:x:h?";
+
+const std::string ArgumentParser::trueString = "true";
+const std::string ArgumentParser::emptyString = "";
+
+} // namespace ncsi
+} // namespace network
+} // namespace phosphor
diff --git a/src/argument.hpp b/src/argument.hpp
new file mode 100644
index 0000000..28e5ce3
--- /dev/null
+++ b/src/argument.hpp
@@ -0,0 +1,68 @@
+#pragma once
+
+#include <getopt.h>
+
+#include <map>
+#include <string>
+
+namespace phosphor
+{
+namespace network
+{
+namespace ncsi
+{
+/** @brief Class - Encapsulates parsing command line options and
+ *                 populating arguments
+ */
+class ArgumentParser
+{
+  public:
+    ArgumentParser() = delete;
+    ~ArgumentParser() = default;
+    ArgumentParser(const ArgumentParser&) = delete;
+    ArgumentParser& operator=(const ArgumentParser&) = delete;
+    ArgumentParser(ArgumentParser&&) = default;
+    ArgumentParser& operator=(ArgumentParser&&) = default;
+
+    /** @brief Constructs Argument object
+     *
+     *  @param argc - the main function's argc passed as is
+     *  @param argv - the main function's argv passed as is
+     *  @return Object constructed
+     */
+    ArgumentParser(int argc, char** argv);
+
+    /** @brief Given an option, returns its argument(optarg)
+     *
+     *  @param opt - command line option string
+     *
+     *  @return argument which is a standard optarg
+     */
+    const std::string& operator[](const std::string& opt);
+
+    /** @brief Displays usage
+     *
+     *  @param argv - the main function's argv passed as is
+     */
+    static void usage(char** argv);
+
+    /** @brief Set to 'true' when an option is passed */
+    static const std::string trueString;
+
+    /** @brief Set to '' when an option is not passed */
+    static const std::string emptyString;
+
+  private:
+    /** @brief Option to argument mapping */
+    std::map<const std::string, std::string> arguments;
+
+    /** @brief Array of struct options as needed by getopt_long */
+    static const option options[];
+
+    /** @brief optstring as needed by getopt_long */
+    static const char* optionStr;
+};
+
+} // namespace ncsi
+} // namespace network
+} // namespace phosphor
diff --git a/src/config_parser.cpp b/src/config_parser.cpp
new file mode 100644
index 0000000..c4af404
--- /dev/null
+++ b/src/config_parser.cpp
@@ -0,0 +1,164 @@
+#include "config_parser.hpp"
+
+#include <algorithm>
+#include <fstream>
+#include <list>
+#include <phosphor-logging/log.hpp>
+#include <regex>
+#include <string>
+#include <unordered_map>
+
+namespace phosphor
+{
+namespace network
+{
+namespace config
+{
+
+using namespace phosphor::logging;
+
+Parser::Parser(const fs::path& filePath)
+{
+    setFile(filePath);
+}
+
+std::tuple<ReturnCode, KeyValueMap>
+    Parser::getSection(const std::string& section)
+{
+    auto it = sections.find(section);
+    if (it == sections.end())
+    {
+        KeyValueMap keyValues;
+        return std::make_tuple(ReturnCode::SECTION_NOT_FOUND,
+                               std::move(keyValues));
+    }
+
+    return std::make_tuple(ReturnCode::SUCCESS, it->second);
+}
+
+std::tuple<ReturnCode, ValueList> Parser::getValues(const std::string& section,
+                                                    const std::string& key)
+{
+    ValueList values;
+    KeyValueMap keyValues{};
+    auto rc = ReturnCode::SUCCESS;
+
+    std::tie(rc, keyValues) = getSection(section);
+    if (rc != ReturnCode::SUCCESS)
+    {
+        return std::make_tuple(rc, std::move(values));
+    }
+
+    auto it = keyValues.find(key);
+    if (it == keyValues.end())
+    {
+        return std::make_tuple(ReturnCode::KEY_NOT_FOUND, std::move(values));
+    }
+
+    for (; it != keyValues.end() && key == it->first; it++)
+    {
+        values.push_back(it->second);
+    }
+
+    return std::make_tuple(ReturnCode::SUCCESS, std::move(values));
+}
+
+bool Parser::isValueExist(const std::string& section, const std::string& key,
+                          const std::string& value)
+{
+    auto rc = ReturnCode::SUCCESS;
+    ValueList values;
+    std::tie(rc, values) = getValues(section, key);
+
+    if (rc != ReturnCode::SUCCESS)
+    {
+        return false;
+    }
+    auto it = std::find(values.begin(), values.end(), value);
+    return it != std::end(values) ? true : false;
+}
+
+void Parser::setValue(const std::string& section, const std::string& key,
+                      const std::string& value)
+{
+    KeyValueMap values;
+    auto it = sections.find(section);
+    if (it != sections.end())
+    {
+        values = std::move(it->second);
+    }
+    values.insert(std::make_pair(key, value));
+
+    if (it != sections.end())
+    {
+        it->second = std::move(values);
+    }
+    else
+    {
+        sections.insert(std::make_pair(section, std::move(values)));
+    }
+}
+
+#if 0
+void Parser::print()
+{
+    for (auto section : sections)
+    {
+        std::cout << "[" << section.first << "]\n\n";
+        for (auto keyValue : section.second)
+        {
+            std::cout << keyValue.first << "=" << keyValue.second << "\n";
+        }
+    }
+}
+#endif
+
+void Parser::setFile(const fs::path& filePath)
+{
+    this->filePath = filePath;
+    std::fstream stream;
+    stream.open(filePath.string(), std::fstream::in);
+
+    if (!stream.is_open())
+    {
+        return;
+    }
+    // clear all the section data.
+    sections.clear();
+    parse(stream);
+    stream.close();
+}
+
+void Parser::parse(std::istream& in)
+{
+    static const std::regex commentRegex{R"x(\s*[;#])x"};
+    static const std::regex sectionRegex{R"x(\s*\[([^\]]+)\])x"};
+    static const std::regex valueRegex{R"x(\s*(\S[^ \t=]*)\s*=\s*(\S+)\s*$)x"};
+    std::string section;
+    std::smatch pieces;
+    for (std::string line; std::getline(in, line);)
+    {
+        if (line.empty() || std::regex_match(line, pieces, commentRegex))
+        {
+            // skip comment lines and blank lines
+        }
+        else if (std::regex_match(line, pieces, sectionRegex))
+        {
+            if (pieces.size() == 2)
+            {
+                section = pieces[1].str();
+            }
+        }
+        else if (std::regex_match(line, pieces, valueRegex))
+        {
+            if (pieces.size() == 3)
+            {
+                setValue(section, pieces[1].str(), pieces[2].str());
+            }
+        }
+    }
+}
+
+} // namespace config
+} // namespace network
+} // namespace phosphor
diff --git a/src/config_parser.hpp b/src/config_parser.hpp
new file mode 100644
index 0000000..8af4a34
--- /dev/null
+++ b/src/config_parser.hpp
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <filesystem>
+#include <map>
+#include <string>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+namespace phosphor
+{
+namespace network
+{
+namespace config
+{
+
+using Section = std::string;
+using KeyValueMap = std::multimap<std::string, std::string>;
+using ValueList = std::vector<std::string>;
+
+namespace fs = std::filesystem;
+
+enum class ReturnCode
+{
+    SUCCESS = 0x0,
+    SECTION_NOT_FOUND = 0x1,
+    KEY_NOT_FOUND = 0x2,
+};
+
+class Parser
+{
+  public:
+    Parser() = default;
+
+    /** @brief Constructor
+     *  @param[in] fileName - Absolute path of the file which will be parsed.
+     */
+
+    Parser(const fs::path& fileName);
+
+    /** @brief Get the values of the given key and section.
+     *  @param[in] section - section name.
+     *  @param[in] key - key to look for.
+     *  @returns the tuple of return code and the
+     *           values associated with the key.
+     */
+
+    std::tuple<ReturnCode, ValueList> getValues(const std::string& section,
+                                                const std::string& key);
+
+    /** @brief Set the value of the given key and section.
+     *  @param[in] section - section name.
+     *  @param[in] key - key name.
+     *  @param[in] value - value.
+     */
+
+    void setValue(const std::string& section, const std::string& key,
+                  const std::string& value);
+
+    /** @brief Set the file name and parse it.
+     *  @param[in] fileName - Absolute path of the file.
+     */
+
+    void setFile(const fs::path& fileName);
+
+  private:
+    /** @brief Parses the given file and fills the data.
+     *  @param[in] stream - inputstream.
+     */
+
+    void parse(std::istream& stream);
+
+    /** @brief Get all the key values of the given section.
+     *  @param[in] section - section name.
+     *  @returns the tuple of return code and the map of (key,value).
+     */
+
+    std::tuple<ReturnCode, KeyValueMap> getSection(const std::string& section);
+
+    /** @brief checks that whether the value exist in the
+     *         given section.
+     *  @param[in] section - section name.
+     *  @param[in] key - key name.
+     *  @param[in] value - value.
+     *  @returns true if exist otherwise false.
+     */
+
+    bool isValueExist(const std::string& section, const std::string& key,
+                      const std::string& value);
+
+    std::unordered_map<Section, KeyValueMap> sections;
+    fs::path filePath;
+};
+
+} // namespace config
+} // namespace network
+} // namespace phosphor
diff --git a/src/dhcp_configuration.cpp b/src/dhcp_configuration.cpp
new file mode 100644
index 0000000..690ae47
--- /dev/null
+++ b/src/dhcp_configuration.cpp
@@ -0,0 +1,111 @@
+#include "config.h"
+
+#include "dhcp_configuration.hpp"
+
+#include "network_manager.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+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())
+    {
+        return value;
+    }
+
+    auto name = ConfigIntf::sendHostNameEnabled(value);
+    manager.writeToConfigurationFile();
+
+    return name;
+}
+
+bool Configuration::hostNameEnabled(bool value)
+{
+    if (value == hostNameEnabled())
+    {
+        return value;
+    }
+
+    auto name = ConfigIntf::hostNameEnabled(value);
+    manager.writeToConfigurationFile();
+    manager.restartSystemdUnit(phosphor::network::networkdService);
+
+    return name;
+}
+
+bool Configuration::ntpEnabled(bool value)
+{
+    if (value == ntpEnabled())
+    {
+        return value;
+    }
+
+    auto ntp = ConfigIntf::ntpEnabled(value);
+    manager.writeToConfigurationFile();
+    manager.restartSystemdUnit(phosphor::network::networkdService);
+    manager.restartSystemdUnit(phosphor::network::timeSynchdService);
+
+    return ntp;
+}
+
+bool Configuration::dnsEnabled(bool value)
+{
+    if (value == dnsEnabled())
+    {
+        return value;
+    }
+
+    auto dns = ConfigIntf::dnsEnabled(value);
+    manager.writeToConfigurationFile();
+    manager.restartSystemdUnit(phosphor::network::networkdService);
+
+    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/src/dhcp_configuration.hpp b/src/dhcp_configuration.hpp
new file mode 100644
index 0000000..441c7b2
--- /dev/null
+++ b/src/dhcp_configuration.hpp
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "config_parser.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <xyz/openbmc_project/Network/DHCPConfiguration/server.hpp>
+
+#ifndef SDBUSPP_NEW_CAMELCASE
+#define dnsEnabled dNSEnabled
+#define ntpEnabled nTPEnabled
+#endif
+
+namespace phosphor
+{
+namespace network
+{
+
+class Manager; // forward declaration of network manager.
+
+namespace dhcp
+{
+
+using ConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::DHCPConfiguration;
+
+using Iface = sdbusplus::server::object::object<ConfigIntf>;
+
+/** @class Configuration
+ *  @brief DHCP configuration.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.DHCP DBus interface.
+ */
+class Configuration : public Iface
+{
+  public:
+    Configuration() = default;
+    Configuration(const Configuration&) = delete;
+    Configuration& operator=(const Configuration&) = delete;
+    Configuration(Configuration&&) = delete;
+    Configuration& operator=(Configuration&&) = delete;
+    virtual ~Configuration() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] parent - Parent object.
+     */
+    Configuration(sdbusplus::bus::bus& bus, const std::string& objPath,
+                  Manager& parent) :
+        Iface(bus, objPath.c_str(), true),
+        bus(bus), manager(parent)
+    {
+        ConfigIntf::dnsEnabled(getDHCPPropFromConf("UseDNS"));
+        ConfigIntf::ntpEnabled(getDHCPPropFromConf("UseNTP"));
+        ConfigIntf::hostNameEnabled(getDHCPPropFromConf("UseHostname"));
+        ConfigIntf::sendHostNameEnabled(getDHCPPropFromConf("SendHostname"));
+        emit_object_added();
+    }
+
+    /** @brief If true then DNS servers received from the DHCP server
+     *         will be used and take precedence over any statically
+     *         configured ones.
+     *  @param[in] value - true if DNS server needed from DHCP server
+     *                     else false.
+     */
+    bool dnsEnabled(bool value) override;
+
+    /** @brief If true then NTP servers received from the DHCP server
+               will be used by systemd-timesyncd.
+     *  @param[in] value - true if NTP server needed from DHCP server
+     *                     else false.
+     */
+    bool ntpEnabled(bool value) override;
+
+    /** @brief If true then Hostname received from the DHCP server will
+     *         be set as the hostname of the system
+     *  @param[in] value - true if hostname needed from the DHCP server
+     *                     else false.
+     *
+     */
+    bool hostNameEnabled(bool value) override;
+
+    /** @brief if true then it will cause an Option 12 field, i.e machine's
+     *         hostname, will be included in the DHCP packet.
+     *  @param[in] value - true if machine's host name needs to be included
+     *         in the DHCP packet.
+     */
+    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).
+     *
+     */
+    using ConfigIntf::dnsEnabled;
+    using ConfigIntf::hostNameEnabled;
+    using ConfigIntf::ntpEnabled;
+    using ConfigIntf::sendHostNameEnabled;
+
+  private:
+    /** @brief sdbusplus DBus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** @brief Network Manager object. */
+    phosphor::network::Manager& manager;
+};
+
+} // namespace dhcp
+} // namespace network
+} // namespace phosphor
diff --git a/src/dns_updater.cpp b/src/dns_updater.cpp
new file mode 100644
index 0000000..bf29fff
--- /dev/null
+++ b/src/dns_updater.cpp
@@ -0,0 +1,58 @@
+#include "config.h"
+
+#include "dns_updater.hpp"
+
+#include <fstream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+namespace dns
+{
+namespace updater
+{
+
+void updateDNSEntries(const fs::path& inFile, const fs::path& outFile)
+{
+    using namespace phosphor::logging;
+    using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+    std::fstream outStream(outFile, std::fstream::out);
+    if (!outStream.is_open())
+    {
+        log<level::ERR>("Unable to open output file",
+                        entry("FILE=%s", outFile.c_str()));
+        elog<InternalFailure>();
+    }
+
+    std::fstream inStream(inFile, std::fstream::in);
+    if (!inStream.is_open())
+    {
+        log<level::ERR>("Unable to open the input file",
+                        entry("FILE=%s", inFile.c_str()));
+        elog<InternalFailure>();
+    }
+
+    outStream << "### Generated by phosphor-networkd ###\n";
+
+    for (std::string line; std::getline(inStream, line);)
+    {
+        auto index = line.find("DNS=");
+        if (index != std::string::npos)
+        {
+            auto dns = line.substr(index + 4);
+            outStream << "nameserver " << dns << "\n";
+        }
+    }
+    return;
+}
+
+} // namespace updater
+} // namespace dns
+} // namespace network
+} // namespace phosphor
diff --git a/src/dns_updater.hpp b/src/dns_updater.hpp
new file mode 100644
index 0000000..5d23b29
--- /dev/null
+++ b/src/dns_updater.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <filesystem>
+
+namespace phosphor
+{
+namespace network
+{
+namespace dns
+{
+namespace updater
+{
+
+namespace fs = std::filesystem;
+
+constexpr auto RESOLV_CONF = "/etc/resolv.conf";
+
+/** @brief Reads DNS entries supplied by DHCP and updates specified file
+ *
+ *  @param[in] inFile  - File having DNS entries supplied by DHCP
+ *  @param[in] outFile - File to write the nameserver entries to
+ */
+void updateDNSEntries(const fs::path& inFile, const fs::path& outFile);
+
+/** @brief User callback handler invoked by inotify watcher
+ *
+ *  Needed to enable production and test code so that the right
+ *  callback functions could be implemented
+ *
+ *  @param[in] inFile - File having DNS entries supplied by DHCP
+ */
+inline void processDNSEntries(const fs::path& inFile)
+{
+    return updateDNSEntries(inFile, RESOLV_CONF);
+}
+
+} // namespace updater
+} // namespace dns
+} // namespace network
+} // namespace phosphor
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
new file mode 100644
index 0000000..ce424ff
--- /dev/null
+++ b/src/ethernet_interface.cpp
@@ -0,0 +1,1179 @@
+#include "config.h"
+
+#include "ethernet_interface.hpp"
+
+#include "config_parser.hpp"
+#include "neighbor.hpp"
+#include "network_manager.hpp"
+#include "routing_table.hpp"
+#include "vlan_interface.hpp"
+
+#include <arpa/inet.h>
+#include <linux/ethtool.h>
+#include <linux/rtnetlink.h>
+#include <linux/sockios.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <filesystem>
+#include <fstream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sstream>
+#include <stdplus/raw.hpp>
+#include <string>
+#include <string_view>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
+using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
+using Argument = xyz::openbmc_project::Common::InvalidArgument;
+constexpr auto RESOLVED_SERVICE = "org.freedesktop.resolve1";
+constexpr auto RESOLVED_INTERFACE = "org.freedesktop.resolve1.Link";
+constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
+constexpr auto RESOLVED_SERVICE_PATH = "/org/freedesktop/resolve1/link/";
+constexpr auto METHOD_GET = "Get";
+
+struct EthernetIntfSocket
+{
+    EthernetIntfSocket(int domain, int type, int protocol)
+    {
+        if ((sock = socket(domain, type, protocol)) < 0)
+        {
+            log<level::ERR>("socket creation failed:",
+                            entry("ERROR=%s", strerror(errno)));
+        }
+    }
+
+    ~EthernetIntfSocket()
+    {
+        if (sock >= 0)
+        {
+            close(sock);
+        }
+    }
+
+    int sock{-1};
+};
+
+std::map<EthernetInterface::DHCPConf, std::string> mapDHCPToSystemd = {
+    {EthernetInterface::DHCPConf::both, "true"},
+    {EthernetInterface::DHCPConf::v4, "ipv4"},
+    {EthernetInterface::DHCPConf::v6, "ipv6"},
+    {EthernetInterface::DHCPConf::none, "false"}};
+
+EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus,
+                                     const std::string& objPath,
+                                     DHCPConf dhcpEnabled, Manager& parent,
+                                     bool emitSignal) :
+    Ifaces(bus, objPath.c_str(), true),
+    bus(bus), manager(parent), objPath(objPath)
+{
+    auto intfName = objPath.substr(objPath.rfind("/") + 1);
+    std::replace(intfName.begin(), intfName.end(), '_', '.');
+    interfaceName(intfName);
+    EthernetInterfaceIntf::dhcpEnabled(dhcpEnabled);
+    EthernetInterfaceIntf::ipv6AcceptRA(getIPv6AcceptRAFromConf());
+    route::Table routingTable;
+    auto gatewayList = routingTable.getDefaultGateway();
+    auto gateway6List = routingTable.getDefaultGateway6();
+    std::string defaultGateway;
+    std::string defaultGateway6;
+
+    for (auto& gateway : gatewayList)
+    {
+        if (gateway.first == intfName)
+        {
+            defaultGateway = gateway.second;
+            break;
+        }
+    }
+
+    for (auto& gateway6 : gateway6List)
+    {
+        if (gateway6.first == intfName)
+        {
+            defaultGateway6 = gateway6.second;
+            break;
+        }
+    }
+
+    EthernetInterfaceIntf::defaultGateway(defaultGateway);
+    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)
+    {
+        MacAddressIntf::macAddress(getMACAddress(intfName));
+    }
+    EthernetInterfaceIntf::ntpServers(getNTPServersFromConf());
+
+    EthernetInterfaceIntf::linkUp(linkUp());
+    EthernetInterfaceIntf::nicEnabled(nicEnabled());
+
+#ifdef NIC_SUPPORTS_ETHTOOL
+    InterfaceInfo ifInfo = EthernetInterface::getInterfaceInfo();
+
+    EthernetInterfaceIntf::autoNeg(std::get<2>(ifInfo));
+    EthernetInterfaceIntf::speed(std::get<0>(ifInfo));
+#endif
+
+    // Emit deferred signal.
+    if (emitSignal)
+    {
+        this->emit_object_added();
+    }
+}
+
+static IP::Protocol convertFamily(int family)
+{
+    switch (family)
+    {
+        case AF_INET:
+            return IP::Protocol::IPv4;
+        case AF_INET6:
+            return IP::Protocol::IPv6;
+    }
+
+    throw std::invalid_argument("Bad address family");
+}
+
+void EthernetInterface::disableDHCP(IP::Protocol protocol)
+{
+    DHCPConf dhcpState = EthernetInterfaceIntf::dhcpEnabled();
+    if (dhcpState == EthernetInterface::DHCPConf::both)
+    {
+        if (protocol == IP::Protocol::IPv4)
+        {
+            dhcpEnabled(EthernetInterface::DHCPConf::v6);
+        }
+        else if (protocol == IP::Protocol::IPv6)
+        {
+            dhcpEnabled(EthernetInterface::DHCPConf::v4);
+        }
+    }
+    else if ((dhcpState == EthernetInterface::DHCPConf::v4) &&
+             (protocol == IP::Protocol::IPv4))
+    {
+        dhcpEnabled(EthernetInterface::DHCPConf::none);
+    }
+    else if ((dhcpState == EthernetInterface::DHCPConf::v6) &&
+             (protocol == IP::Protocol::IPv6))
+    {
+        dhcpEnabled(EthernetInterface::DHCPConf::none);
+    }
+}
+
+bool EthernetInterface::dhcpIsEnabled(IP::Protocol family, bool ignoreProtocol)
+{
+    return ((EthernetInterfaceIntf::dhcpEnabled() ==
+             EthernetInterface::DHCPConf::both) ||
+            ((EthernetInterfaceIntf::dhcpEnabled() ==
+              EthernetInterface::DHCPConf::v6) &&
+             ((family == IP::Protocol::IPv6) || ignoreProtocol)) ||
+            ((EthernetInterfaceIntf::dhcpEnabled() ==
+              EthernetInterface::DHCPConf::v4) &&
+             ((family == IP::Protocol::IPv4) || ignoreProtocol)));
+}
+
+bool EthernetInterface::dhcpToBeEnabled(IP::Protocol family,
+                                        const std::string& nextDHCPState)
+{
+    return ((nextDHCPState == "true") ||
+            ((nextDHCPState == "ipv6") && (family == IP::Protocol::IPv6)) ||
+            ((nextDHCPState == "ipv4") && (family == IP::Protocol::IPv4)));
+}
+
+bool EthernetInterface::originIsManuallyAssigned(IP::AddressOrigin origin)
+{
+    return (
+#ifdef LINK_LOCAL_AUTOCONFIGURATION
+        (origin == IP::AddressOrigin::Static)
+#else
+        (origin == IP::AddressOrigin::Static ||
+         origin == IP::AddressOrigin::LinkLocal)
+#endif
+
+    );
+}
+
+void EthernetInterface::createIPAddressObjects()
+{
+    addrs.clear();
+
+    auto addrs = getInterfaceAddrs()[interfaceName()];
+
+    for (auto& addr : addrs)
+    {
+        IP::Protocol addressType = convertFamily(addr.addrType);
+        IP::AddressOrigin origin = IP::AddressOrigin::Static;
+        if (dhcpIsEnabled(addressType))
+        {
+            origin = IP::AddressOrigin::DHCP;
+        }
+        if (isLinkLocalIP(addr.ipaddress))
+        {
+            origin = IP::AddressOrigin::LinkLocal;
+        }
+        // Obsolete parameter
+        std::string gateway = "";
+
+        std::string ipAddressObjectPath = generateObjectPath(
+            addressType, addr.ipaddress, addr.prefix, gateway);
+
+        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));
+    }
+}
+
+void EthernetInterface::createStaticNeighborObjects()
+{
+    staticNeighbors.clear();
+
+    NeighborFilter filter;
+    filter.interface = ifIndex();
+    filter.state = NUD_PERMANENT;
+    auto neighbors = getCurrentNeighbors(filter);
+    for (const auto& neighbor : neighbors)
+    {
+        if (!neighbor.mac)
+        {
+            continue;
+        }
+        std::string ip = toString(neighbor.address);
+        std::string mac = mac_address::toString(*neighbor.mac);
+        std::string objectPath = generateStaticNeighborObjectPath(ip, mac);
+        staticNeighbors.emplace(ip,
+                                std::make_shared<phosphor::network::Neighbor>(
+                                    bus, objectPath.c_str(), *this, ip, mac,
+                                    Neighbor::State::Permanent));
+    }
+}
+
+unsigned EthernetInterface::ifIndex() const
+{
+    unsigned idx = if_nametoindex(interfaceName().c_str());
+    if (idx == 0)
+    {
+        throw std::system_error(errno, std::generic_category(),
+                                "if_nametoindex");
+    }
+    return idx;
+}
+
+ObjectPath EthernetInterface::ip(IP::Protocol protType, std::string ipaddress,
+                                 uint8_t prefixLength, std::string gateway)
+{
+    if (dhcpIsEnabled(protType))
+    {
+        log<level::INFO>("DHCP enabled on the interface"),
+            entry("INTERFACE=%s", interfaceName().c_str());
+        disableDHCP(protType);
+    }
+
+    IP::AddressOrigin origin = IP::AddressOrigin::Static;
+
+    int addressFamily = (protType == IP::Protocol::IPv4) ? AF_INET : AF_INET6;
+
+    if (!isValidIP(addressFamily, ipaddress))
+    {
+        log<level::ERR>("Not a valid IP address"),
+            entry("ADDRESS=%s", ipaddress.c_str());
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipaddress"),
+                              Argument::ARGUMENT_VALUE(ipaddress.c_str()));
+    }
+
+    // Gateway is an obsolete parameter
+    gateway = "";
+
+    if (!isValidPrefix(addressFamily, prefixLength))
+    {
+        log<level::ERR>("PrefixLength is not correct "),
+            entry("PREFIXLENGTH=%" PRIu8, prefixLength);
+        elog<InvalidArgument>(
+            Argument::ARGUMENT_NAME("prefixLength"),
+            Argument::ARGUMENT_VALUE(std::to_string(prefixLength).c_str()));
+    }
+
+    std::string objectPath =
+        generateObjectPath(protType, ipaddress, prefixLength, gateway);
+    this->addrs.insert_or_assign(ipaddress,
+                                 std::make_shared<phosphor::network::IPAddress>(
+                                     bus, objectPath.c_str(), *this, protType,
+                                     ipaddress, origin, prefixLength, gateway));
+
+    manager.writeToConfigurationFile();
+    return objectPath;
+}
+
+ObjectPath EthernetInterface::neighbor(std::string ipAddress,
+                                       std::string macAddress)
+{
+    if (!isValidIP(AF_INET, ipAddress) && !isValidIP(AF_INET6, ipAddress))
+    {
+        log<level::ERR>("Not a valid IP address",
+                        entry("ADDRESS=%s", ipAddress.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("ipAddress"),
+                              Argument::ARGUMENT_VALUE(ipAddress.c_str()));
+    }
+    if (!mac_address::isUnicast(mac_address::fromString(macAddress)))
+    {
+        log<level::ERR>("Not a valid MAC address",
+                        entry("MACADDRESS=%s", ipAddress.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("macAddress"),
+                              Argument::ARGUMENT_VALUE(macAddress.c_str()));
+    }
+
+    std::string objectPath =
+        generateStaticNeighborObjectPath(ipAddress, macAddress);
+    staticNeighbors.emplace(ipAddress,
+                            std::make_shared<phosphor::network::Neighbor>(
+                                bus, objectPath.c_str(), *this, ipAddress,
+                                macAddress, Neighbor::State::Permanent));
+    manager.writeToConfigurationFile();
+    return objectPath;
+}
+
+#ifdef NIC_SUPPORTS_ETHTOOL
+/*
+  Enable this code if your NIC driver supports the ETHTOOL features.
+  Do this by adding the following to your phosphor-network*.bbappend file.
+     EXTRA_OECONF_append = " --enable-nic-ethtool=yes"
+  The default compile mode is to omit getInterfaceInfo()
+*/
+InterfaceInfo EthernetInterface::getInterfaceInfo() const
+{
+    ifreq ifr = {};
+    ethtool_cmd edata = {};
+    LinkSpeed speed = {};
+    Autoneg autoneg = {};
+    DuplexMode duplex = {};
+    LinkUp linkState = {};
+    NICEnabled enabled = {};
+    EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+    if (eifSocket.sock < 0)
+    {
+        return std::make_tuple(speed, duplex, autoneg, linkState, enabled);
+    }
+
+    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IFNAMSIZ - 1);
+    ifr.ifr_data = reinterpret_cast<char*>(&edata);
+
+    edata.cmd = ETHTOOL_GSET;
+    if (ioctl(eifSocket.sock, SIOCETHTOOL, &ifr) >= 0)
+    {
+        speed = edata.speed;
+        duplex = edata.duplex;
+        autoneg = edata.autoneg;
+    }
+
+    enabled = nicEnabled();
+    linkState = linkUp();
+
+    return std::make_tuple(speed, duplex, autoneg, linkState, enabled);
+}
+#endif
+
+/** @brief get the mac address of the interface.
+ *  @return macaddress on success
+ */
+
+std::string
+    EthernetInterface::getMACAddress(const std::string& interfaceName) const
+{
+    std::string activeMACAddr = MacAddressIntf::macAddress();
+    EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+    if (eifSocket.sock < 0)
+    {
+        return activeMACAddr;
+    }
+
+    ifreq ifr = {};
+    std::strncpy(ifr.ifr_name, interfaceName.c_str(), IFNAMSIZ - 1);
+    if (ioctl(eifSocket.sock, SIOCGIFHWADDR, &ifr) != 0)
+    {
+        log<level::ERR>("ioctl failed for SIOCGIFHWADDR:",
+                        entry("ERROR=%s", strerror(errno)));
+        elog<InternalFailure>();
+    }
+
+    static_assert(sizeof(ifr.ifr_hwaddr.sa_data) >= sizeof(ether_addr));
+    std::string_view hwaddr(reinterpret_cast<char*>(ifr.ifr_hwaddr.sa_data),
+                            sizeof(ifr.ifr_hwaddr.sa_data));
+    return mac_address::toString(stdplus::raw::copyFrom<ether_addr>(hwaddr));
+}
+
+std::string EthernetInterface::generateId(const std::string& ipaddress,
+                                          uint8_t prefixLength,
+                                          const std::string& gateway)
+{
+    std::stringstream hexId;
+    std::string hashString = ipaddress;
+    hashString += std::to_string(prefixLength);
+    hashString += gateway;
+
+    // Only want 8 hex digits.
+    hexId << std::hex << ((std::hash<std::string>{}(hashString)) & 0xFFFFFFFF);
+    return hexId.str();
+}
+
+std::string EthernetInterface::generateNeighborId(const std::string& ipAddress,
+                                                  const std::string& macAddress)
+{
+    std::stringstream hexId;
+    std::string hashString = ipAddress + macAddress;
+
+    // Only want 8 hex digits.
+    hexId << std::hex << ((std::hash<std::string>{}(hashString)) & 0xFFFFFFFF);
+    return hexId.str();
+}
+
+void EthernetInterface::deleteObject(const std::string& ipaddress)
+{
+    auto it = addrs.find(ipaddress);
+    if (it == addrs.end())
+    {
+        log<level::ERR>("DeleteObject:Unable to find the object.");
+        return;
+    }
+    this->addrs.erase(it);
+    manager.writeToConfigurationFile();
+}
+
+void EthernetInterface::deleteStaticNeighborObject(const std::string& ipAddress)
+{
+    auto it = staticNeighbors.find(ipAddress);
+    if (it == staticNeighbors.end())
+    {
+        log<level::ERR>(
+            "DeleteStaticNeighborObject:Unable to find the object.");
+        return;
+    }
+    staticNeighbors.erase(it);
+    manager.writeToConfigurationFile();
+}
+
+void EthernetInterface::deleteVLANFromSystem(const std::string& interface)
+{
+    auto confDir = manager.getConfDir();
+    fs::path networkFile = confDir;
+    networkFile /= systemd::config::networkFilePrefix + interface +
+                   systemd::config::networkFileSuffix;
+
+    fs::path deviceFile = confDir;
+    deviceFile /= interface + systemd::config::deviceFileSuffix;
+
+    // delete the vlan network file
+    if (fs::is_regular_file(networkFile))
+    {
+        fs::remove(networkFile);
+    }
+
+    // delete the vlan device file
+    if (fs::is_regular_file(deviceFile))
+    {
+        fs::remove(deviceFile);
+    }
+
+    // TODO  systemd doesn't delete the virtual network interface
+    // even after deleting all the related configuartion.
+    // https://github.com/systemd/systemd/issues/6600
+    try
+    {
+        deleteInterface(interface);
+    }
+    catch (InternalFailure& e)
+    {
+        commit<InternalFailure>();
+    }
+}
+
+void EthernetInterface::deleteVLANObject(const std::string& interface)
+{
+    auto it = vlanInterfaces.find(interface);
+    if (it == vlanInterfaces.end())
+    {
+        log<level::ERR>("DeleteVLANObject:Unable to find the object",
+                        entry("INTERFACE=%s", interface.c_str()));
+        return;
+    }
+
+    deleteVLANFromSystem(interface);
+    // delete the interface
+    vlanInterfaces.erase(it);
+
+    manager.writeToConfigurationFile();
+}
+
+std::string EthernetInterface::generateObjectPath(
+    IP::Protocol addressType, const std::string& ipaddress,
+    uint8_t prefixLength, const std::string& gateway) const
+{
+    std::string type = convertForMessage(addressType);
+    type = type.substr(type.rfind('.') + 1);
+    std::transform(type.begin(), type.end(), type.begin(), ::tolower);
+
+    std::filesystem::path objectPath;
+    objectPath /= objPath;
+    objectPath /= type;
+    objectPath /= generateId(ipaddress, prefixLength, gateway);
+    return objectPath.string();
+}
+
+std::string EthernetInterface::generateStaticNeighborObjectPath(
+    const std::string& ipAddress, const std::string& macAddress) const
+{
+    std::filesystem::path objectPath;
+    objectPath /= objPath;
+    objectPath /= "static_neighbor";
+    objectPath /= generateNeighborId(ipAddress, macAddress);
+    return objectPath.string();
+}
+
+bool EthernetInterface::ipv6AcceptRA(bool value)
+{
+    if (value == EthernetInterfaceIntf::ipv6AcceptRA())
+    {
+        return value;
+    }
+    EthernetInterfaceIntf::ipv6AcceptRA(value);
+    manager.writeToConfigurationFile();
+    return value;
+}
+
+EthernetInterface::DHCPConf EthernetInterface::dhcpEnabled(DHCPConf value)
+{
+    if (value == EthernetInterfaceIntf::dhcpEnabled())
+    {
+        return value;
+    }
+
+    EthernetInterfaceIntf::dhcpEnabled(value);
+    manager.writeToConfigurationFile();
+    return value;
+}
+
+bool EthernetInterface::linkUp() const
+{
+    EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+    bool value = EthernetInterfaceIntf::linkUp();
+
+    if (eifSocket.sock < 0)
+    {
+        return value;
+    }
+
+    ifreq ifr = {};
+    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
+    if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) == 0)
+    {
+        value = static_cast<bool>(ifr.ifr_flags & IFF_RUNNING);
+    }
+    else
+    {
+        log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
+                        entry("ERROR=%s", strerror(errno)));
+    }
+    return value;
+}
+
+bool EthernetInterface::nicEnabled() const
+{
+    EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+    bool value = EthernetInterfaceIntf::nicEnabled();
+
+    if (eifSocket.sock < 0)
+    {
+        return value;
+    }
+
+    ifreq ifr = {};
+    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
+    if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) == 0)
+    {
+        value = static_cast<bool>(ifr.ifr_flags & IFF_UP);
+    }
+    else
+    {
+        log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
+                        entry("ERROR=%s", strerror(errno)));
+    }
+    return value;
+}
+
+bool EthernetInterface::nicEnabled(bool value)
+{
+    if (value == EthernetInterfaceIntf::nicEnabled())
+    {
+        return value;
+    }
+
+    EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+    if (eifSocket.sock < 0)
+    {
+        return EthernetInterfaceIntf::nicEnabled();
+    }
+
+    ifreq ifr = {};
+    std::strncpy(ifr.ifr_name, interfaceName().c_str(), IF_NAMESIZE - 1);
+    if (ioctl(eifSocket.sock, SIOCGIFFLAGS, &ifr) != 0)
+    {
+        log<level::ERR>("ioctl failed for SIOCGIFFLAGS:",
+                        entry("ERROR=%s", strerror(errno)));
+        return EthernetInterfaceIntf::nicEnabled();
+    }
+
+    ifr.ifr_flags &= ~IFF_UP;
+    ifr.ifr_flags |= value ? IFF_UP : 0;
+
+    if (ioctl(eifSocket.sock, SIOCSIFFLAGS, &ifr) != 0)
+    {
+        log<level::ERR>("ioctl failed for SIOCSIFFLAGS:",
+                        entry("ERROR=%s", strerror(errno)));
+        return EthernetInterfaceIntf::nicEnabled();
+    }
+    EthernetInterfaceIntf::nicEnabled(value);
+    writeConfigurationFile();
+
+    return value;
+}
+
+ServerList EthernetInterface::nameservers(ServerList /*value*/)
+{
+    elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property"));
+    return EthernetInterfaceIntf::nameservers();
+}
+
+ServerList EthernetInterface::staticNameServers(ServerList value)
+{
+    for (const auto& nameserverip : value)
+    {
+        if (!isValidIP(AF_INET, nameserverip) &&
+            !isValidIP(AF_INET6, nameserverip))
+        {
+            log<level::ERR>("Not a valid IP address"),
+                entry("ADDRESS=%s", nameserverip.c_str());
+            elog<InvalidArgument>(
+                Argument::ARGUMENT_NAME("StaticNameserver"),
+                Argument::ARGUMENT_VALUE(nameserverip.c_str()));
+        }
+    }
+    try
+    {
+        EthernetInterfaceIntf::staticNameServers(value);
+        writeConfigurationFile();
+        // resolved reads the DNS server configuration from the
+        // network file.
+        manager.restartSystemdUnit(networkdService);
+    }
+    catch (InternalFailure& e)
+    {
+        log<level::ERR>("Exception processing DNS entries");
+    }
+    return EthernetInterfaceIntf::staticNameServers();
+}
+
+void EthernetInterface::loadNameServers()
+{
+    EthernetInterfaceIntf::nameservers(getNameServerFromResolvd());
+    EthernetInterfaceIntf::staticNameServers(getstaticNameServerFromConf());
+}
+
+ServerList EthernetInterface::getstaticNameServerFromConf()
+{
+    fs::path confPath = manager.getConfDir();
+
+    std::string fileName = systemd::config::networkFilePrefix +
+                           interfaceName() + systemd::config::networkFileSuffix;
+    confPath /= fileName;
+    ServerList servers;
+    config::Parser parser(confPath.string());
+    auto rc = config::ReturnCode::SUCCESS;
+
+    std::tie(rc, servers) = parser.getValues("Network", "DNS");
+    if (rc != config::ReturnCode::SUCCESS)
+    {
+        log<level::DEBUG>("Unable to get the value for network[DNS]",
+                          entry("RC=%d", rc));
+    }
+    return servers;
+}
+
+ServerList EthernetInterface::getNameServerFromResolvd()
+{
+    ServerList servers;
+    std::string OBJ_PATH = RESOLVED_SERVICE_PATH + std::to_string(ifIndex());
+
+    /*
+      The DNS property under org.freedesktop.resolve1.Link interface contains
+      an array containing all DNS servers currently used by resolved. It
+      contains similar information as the DNS server data written to
+      /run/systemd/resolve/resolv.conf.
+
+      Each structure in the array consists of a numeric network interface index,
+      an address family, and a byte array containing the DNS server address
+      (either 4 bytes in length for IPv4 or 16 bytes in lengths for IPv6).
+      The array contains DNS servers configured system-wide, including those
+      possibly read from a foreign /etc/resolv.conf or the DNS= setting in
+      /etc/systemd/resolved.conf, as well as per-interface DNS server
+      information either retrieved from systemd-networkd or configured by
+      external software via SetLinkDNS().
+    */
+
+    using type = std::vector<std::tuple<int32_t, std::vector<uint8_t>>>;
+    std::variant<type> name; // Variable to capture the DNS property
+    auto method = bus.new_method_call(RESOLVED_SERVICE, OBJ_PATH.c_str(),
+                                      PROPERTY_INTERFACE, METHOD_GET);
+
+    method.append(RESOLVED_INTERFACE, "DNS");
+    auto reply = bus.call(method);
+
+    try
+    {
+        reply.read(name);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        log<level::ERR>("Failed to get DNS information from Systemd-Resolved");
+    }
+    auto tupleVector = std::get_if<type>(&name);
+    for (auto i = tupleVector->begin(); i != tupleVector->end(); ++i)
+    {
+        int addressFamily = std::get<0>(*i);
+        std::vector<uint8_t>& ipaddress = std::get<1>(*i);
+
+        switch (addressFamily)
+        {
+            case AF_INET:
+                if (ipaddress.size() == sizeof(struct in_addr))
+                {
+                    servers.push_back(toString(
+                        *reinterpret_cast<struct in_addr*>(ipaddress.data())));
+                }
+                else
+                {
+                    log<level::ERR>(
+                        "Invalid data recived from Systemd-Resolved");
+                }
+                break;
+
+            case AF_INET6:
+                if (ipaddress.size() == sizeof(struct in6_addr))
+                {
+                    servers.push_back(toString(
+                        *reinterpret_cast<struct in6_addr*>(ipaddress.data())));
+                }
+                else
+                {
+                    log<level::ERR>(
+                        "Invalid data recived from Systemd-Resolved");
+                }
+                break;
+
+            default:
+                log<level::ERR>(
+                    "Unsupported address family in DNS from Systemd-Resolved");
+                break;
+        }
+    }
+    return servers;
+}
+
+void EthernetInterface::loadVLAN(VlanId id)
+{
+    std::string vlanInterfaceName = interfaceName() + "." + std::to_string(id);
+    std::string path = objPath;
+    path += "_" + std::to_string(id);
+
+    DHCPConf dhcpEnabled =
+        getDHCPValue(manager.getConfDir().string(), vlanInterfaceName);
+    auto vlanIntf = std::make_unique<phosphor::network::VlanInterface>(
+        bus, path.c_str(), dhcpEnabled, EthernetInterfaceIntf::nicEnabled(), id,
+        *this, manager);
+
+    // Fetch the ip address from the system
+    // and create the dbus object.
+    vlanIntf->createIPAddressObjects();
+    vlanIntf->createStaticNeighborObjects();
+
+    this->vlanInterfaces.emplace(std::move(vlanInterfaceName),
+                                 std::move(vlanIntf));
+}
+
+ObjectPath EthernetInterface::createVLAN(VlanId id)
+{
+    std::string vlanInterfaceName = interfaceName() + "." + std::to_string(id);
+    std::string path = objPath;
+    path += "_" + std::to_string(id);
+
+    // Pass the parents nicEnabled property, so that the child
+    // VLAN interface can inherit.
+
+    auto vlanIntf = std::make_unique<phosphor::network::VlanInterface>(
+        bus, path.c_str(), EthernetInterface::DHCPConf::none,
+        EthernetInterfaceIntf::nicEnabled(), id, *this, manager);
+
+    // write the device file for the vlan interface.
+    vlanIntf->writeDeviceFile();
+
+    this->vlanInterfaces.emplace(vlanInterfaceName, std::move(vlanIntf));
+    // write the new vlan device entry to the configuration(network) file.
+    manager.writeToConfigurationFile();
+
+    return path;
+}
+
+bool EthernetInterface::getIPv6AcceptRAFromConf()
+{
+    fs::path confPath = manager.getConfDir();
+
+    std::string fileName = systemd::config::networkFilePrefix +
+                           interfaceName() + systemd::config::networkFileSuffix;
+    confPath /= fileName;
+    config::ValueList values;
+    config::Parser parser(confPath.string());
+    auto rc = config::ReturnCode::SUCCESS;
+    std::tie(rc, values) = parser.getValues("Network", "IPv6AcceptRA");
+    if (rc != config::ReturnCode::SUCCESS)
+    {
+        log<level::DEBUG>("Unable to get the value for Network[IPv6AcceptRA]",
+                          entry("rc=%d", rc));
+        return false;
+    }
+    return (values[0] == "true");
+}
+
+ServerList EthernetInterface::getNTPServersFromConf()
+{
+    fs::path confPath = manager.getConfDir();
+
+    std::string fileName = systemd::config::networkFilePrefix +
+                           interfaceName() + systemd::config::networkFileSuffix;
+    confPath /= fileName;
+
+    ServerList servers;
+    config::Parser parser(confPath.string());
+    auto rc = config::ReturnCode::SUCCESS;
+
+    std::tie(rc, servers) = parser.getValues("Network", "NTP");
+    if (rc != config::ReturnCode::SUCCESS)
+    {
+        log<level::DEBUG>("Unable to get the value for Network[NTP]",
+                          entry("rc=%d", rc));
+    }
+
+    return servers;
+}
+
+ServerList EthernetInterface::ntpServers(ServerList servers)
+{
+    auto ntpServers = EthernetInterfaceIntf::ntpServers(servers);
+
+    writeConfigurationFile();
+    // timesynchd reads the NTP server configuration from the
+    // network file.
+    manager.restartSystemdUnit(networkdService);
+    return ntpServers;
+}
+// Need to merge the below function with the code which writes the
+// config file during factory reset.
+// TODO openbmc/openbmc#1751
+
+void EthernetInterface::writeConfigurationFile()
+{
+    // write all the static ip address in the systemd-network conf file
+
+    using namespace std::string_literals;
+    namespace fs = std::filesystem;
+
+    // if there is vlan interafce then write the configuration file
+    // for vlan also.
+
+    for (const auto& intf : vlanInterfaces)
+    {
+        intf.second->writeConfigurationFile();
+    }
+
+    fs::path confPath = manager.getConfDir();
+
+    std::string fileName = systemd::config::networkFilePrefix +
+                           interfaceName() + systemd::config::networkFileSuffix;
+    confPath /= fileName;
+    std::fstream stream;
+
+    stream.open(confPath.c_str(), std::fstream::out);
+    if (!stream.is_open())
+    {
+        log<level::ERR>("Unable to open the file",
+                        entry("FILE=%s", confPath.c_str()));
+        elog<InternalFailure>();
+    }
+
+    // Write the device
+    stream << "[Match]\n";
+    stream << "Name=" << interfaceName() << "\n";
+
+    auto addrs = getAddresses();
+
+    // Write the link section
+    stream << "[Link]\n";
+    auto mac = MacAddressIntf::macAddress();
+    if (!mac.empty())
+    {
+        stream << "MACAddress=" << mac << "\n";
+    }
+
+    if (!EthernetInterfaceIntf::nicEnabled())
+    {
+        stream << "Unmanaged=yes\n";
+    }
+
+    // write the network section
+    stream << "[Network]\n";
+#ifdef LINK_LOCAL_AUTOCONFIGURATION
+    stream << "LinkLocalAddressing=yes\n";
+#else
+    stream << "LinkLocalAddressing=no\n";
+#endif
+    stream << std::boolalpha
+           << "IPv6AcceptRA=" << EthernetInterfaceIntf::ipv6AcceptRA() << "\n";
+
+    // Add the VLAN entry
+    for (const auto& intf : vlanInterfaces)
+    {
+        stream << "VLAN=" << intf.second->EthernetInterface::interfaceName()
+               << "\n";
+    }
+    // Add the NTP server
+    for (const auto& ntp : EthernetInterfaceIntf::ntpServers())
+    {
+        stream << "NTP=" << ntp << "\n";
+    }
+
+    // Add the DNS entry
+    for (const auto& dns : EthernetInterfaceIntf::staticNameServers())
+    {
+        stream << "DNS=" << dns << "\n";
+    }
+
+    // Add the DHCP entry
+    stream << "DHCP="s +
+                  mapDHCPToSystemd[EthernetInterfaceIntf::dhcpEnabled()] + "\n";
+
+    // Static IP addresses
+    for (const auto& addr : addrs)
+    {
+        if (originIsManuallyAssigned(addr.second->origin()) &&
+            !dhcpIsEnabled(addr.second->type()))
+        {
+            // Process all static addresses
+            std::string address = addr.second->address() + "/" +
+                                  std::to_string(addr.second->prefixLength());
+
+            // build the address entries. Do not use [Network] shortcuts to
+            // insert address entries.
+            stream << "[Address]\n";
+            stream << "Address=" << address << "\n";
+        }
+    }
+
+    auto gateway = EthernetInterfaceIntf::defaultGateway();
+    if (!gateway.empty())
+    {
+        stream << "[Route]\n";
+        stream << "Gateway=" << gateway << "\n";
+    }
+
+    auto gateway6 = EthernetInterfaceIntf::defaultGateway6();
+    if (!gateway6.empty())
+    {
+        stream << "[Route]\n";
+        stream << "Gateway=" << gateway6 << "\n";
+    }
+
+    if (manager.getSystemConf())
+    {
+        const auto& gateway = manager.getSystemConf()->defaultGateway();
+        if (!gateway.empty())
+        {
+            stream << "[Route]\n";
+            stream << "Gateway=" << gateway << "\n";
+        }
+        const auto& gateway6 = manager.getSystemConf()->defaultGateway6();
+        if (!gateway6.empty())
+        {
+            stream << "[Route]\n";
+            stream << "Gateway=" << gateway6 << "\n";
+        }
+    }
+
+    // Write the neighbor sections
+    for (const auto& neighbor : staticNeighbors)
+    {
+        stream << "[Neighbor]"
+               << "\n";
+        stream << "Address=" << neighbor.second->ipAddress() << "\n";
+        stream << "MACAddress=" << neighbor.second->macAddress() << "\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;
+    // write the dhcp section
+    stream << "[DHCP]\n";
+
+    // Hardcoding the client identifier to mac, to address below issue
+    // https://github.com/openbmc/openbmc/issues/1280
+    stream << "ClientIdentifier=mac\n";
+    if (manager.getDHCPConf())
+    {
+        auto value = manager.getDHCPConf()->dnsEnabled() ? "true"s : "false"s;
+        stream << "UseDNS="s + value + "\n";
+
+        value = manager.getDHCPConf()->ntpEnabled() ? "true"s : "false"s;
+        stream << "UseNTP="s + value + "\n";
+
+        value = manager.getDHCPConf()->hostNameEnabled() ? "true"s : "false"s;
+        stream << "UseHostname="s + value + "\n";
+
+        value =
+            manager.getDHCPConf()->sendHostNameEnabled() ? "true"s : "false"s;
+        stream << "SendHostname="s + value + "\n";
+    }
+}
+
+std::string EthernetInterface::macAddress(std::string value)
+{
+    ether_addr newMAC;
+    try
+    {
+        newMAC = mac_address::fromString(value);
+    }
+    catch (std::invalid_argument&)
+    {
+        log<level::ERR>("MACAddress is not valid.",
+                        entry("MAC=%s", value.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("MACAddress"),
+                              Argument::ARGUMENT_VALUE(value.c_str()));
+    }
+    if (!mac_address::isUnicast(newMAC))
+    {
+        log<level::ERR>("MACAddress is not valid.",
+                        entry("MAC=%s", value.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("MACAddress"),
+                              Argument::ARGUMENT_VALUE(value.c_str()));
+    }
+
+    auto interface = interfaceName();
+    std::string validMAC = mac_address::toString(newMAC);
+
+    // We don't need to update the system if the address is unchanged
+    ether_addr oldMAC = mac_address::fromString(MacAddressIntf::macAddress());
+    if (!stdplus::raw::equal(newMAC, oldMAC))
+    {
+        // Update everything that depends on the MAC value
+        for (const auto& [name, intf] : vlanInterfaces)
+        {
+            intf->MacAddressIntf::macAddress(validMAC);
+        }
+        MacAddressIntf::macAddress(validMAC);
+
+        // TODO: would remove the call below and
+        //      just restart systemd-netwokd
+        //      through https://github.com/systemd/systemd/issues/6696
+        execute("/sbin/ip", "ip", "link", "set", "dev", interface.c_str(),
+                "down");
+        manager.writeToConfigurationFile();
+    }
+
+#ifdef HAVE_UBOOT_ENV
+    // Ensure that the valid address is stored in the u-boot-env
+    auto envVar = interfaceToUbootEthAddr(interface.c_str());
+    if (envVar)
+    {
+        // Trimming MAC addresses that are out of range. eg: AA:FF:FF:FF:FF:100;
+        // and those having more than 6 bytes. eg: AA:AA:AA:AA:AA:AA:BB
+        execute("/sbin/fw_setenv", "fw_setenv", envVar->c_str(),
+                validMAC.c_str());
+    }
+#endif // HAVE_UBOOT_ENV
+
+    return value;
+}
+
+void EthernetInterface::deleteAll()
+{
+    if (dhcpIsEnabled(IP::Protocol::IPv4, true))
+    {
+        log<level::INFO>("DHCP enabled on the interface"),
+            entry("INTERFACE=%s", interfaceName().c_str());
+    }
+
+    // clear all the ip on the interface
+    addrs.clear();
+    manager.writeToConfigurationFile();
+}
+
+std::string EthernetInterface::defaultGateway(std::string gateway)
+{
+    auto gw = EthernetInterfaceIntf::defaultGateway();
+    if (gw == gateway)
+    {
+        return gw;
+    }
+
+    if (!isValidIP(AF_INET, gateway))
+    {
+        log<level::ERR>("Not a valid v4 Gateway",
+                        entry("GATEWAY=%s", gateway.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("GATEWAY"),
+                              Argument::ARGUMENT_VALUE(gateway.c_str()));
+    }
+    gw = EthernetInterfaceIntf::defaultGateway(gateway);
+    manager.writeToConfigurationFile();
+    return gw;
+}
+
+std::string EthernetInterface::defaultGateway6(std::string gateway)
+{
+    auto gw = EthernetInterfaceIntf::defaultGateway6();
+    if (gw == gateway)
+    {
+        return gw;
+    }
+
+    if (!isValidIP(AF_INET6, gateway))
+    {
+        log<level::ERR>("Not a valid v6 Gateway",
+                        entry("GATEWAY=%s", gateway.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("GATEWAY"),
+                              Argument::ARGUMENT_VALUE(gateway.c_str()));
+    }
+    gw = EthernetInterfaceIntf::defaultGateway6(gateway);
+    manager.writeToConfigurationFile();
+    return gw;
+}
+} // namespace network
+} // namespace phosphor
diff --git a/src/ethernet_interface.hpp b/src/ethernet_interface.hpp
new file mode 100644
index 0000000..8e28b51
--- /dev/null
+++ b/src/ethernet_interface.hpp
@@ -0,0 +1,372 @@
+#pragma once
+
+#include "types.hpp"
+#include "util.hpp"
+#include "xyz/openbmc_project/Network/IP/Create/server.hpp"
+#include "xyz/openbmc_project/Network/Neighbor/CreateStatic/server.hpp"
+
+#include <filesystem>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
+#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
+#include <xyz/openbmc_project/Network/MACAddress/server.hpp>
+
+#ifndef SDBUSPP_NEW_CAMELCASE
+#define dhcpEnabled dHCPEnabled
+#define ip iP
+#define ipAddress iPAddress
+#define ipv6AcceptRA iPv6AcceptRA
+#define macAddress mACAddress
+#define nicEnabled nICEnabled
+#define ntpServers nTPServers
+#endif
+
+namespace phosphor
+{
+namespace network
+{
+
+using Ifaces = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface,
+    sdbusplus::xyz::openbmc_project::Network::server::MACAddress,
+    sdbusplus::xyz::openbmc_project::Network::IP::server::Create,
+    sdbusplus::xyz::openbmc_project::Network::Neighbor::server::CreateStatic,
+    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
+
+using IP = sdbusplus::xyz::openbmc_project::Network::server::IP;
+
+using EthernetInterfaceIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface;
+using MacAddressIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::MACAddress;
+
+using ServerList = std::vector<std::string>;
+using ObjectPath = sdbusplus::message::object_path;
+
+namespace fs = std::filesystem;
+
+class Manager; // forward declaration of network manager.
+
+class TestEthernetInterface;
+
+class VlanInterface;
+
+class IPAddress;
+
+class Neighbor;
+
+using LinkSpeed = uint16_t;
+using DuplexMode = uint8_t;
+using Autoneg = uint8_t;
+using LinkUp = bool;
+using NICEnabled = bool;
+using VlanId = uint32_t;
+using InterfaceName = std::string;
+using InterfaceInfo =
+    std::tuple<LinkSpeed, DuplexMode, Autoneg, LinkUp, NICEnabled>;
+using AddressMap = std::map<std::string, std::shared_ptr<IPAddress>>;
+using NeighborMap = std::map<std::string, std::shared_ptr<Neighbor>>;
+using VlanInterfaceMap =
+    std::map<InterfaceName, std::unique_ptr<VlanInterface>>;
+
+/** @class EthernetInterface
+ *  @brief OpenBMC Ethernet Interface implementation.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.EthernetInterface DBus API.
+ */
+class EthernetInterface : public Ifaces
+{
+  public:
+    EthernetInterface() = delete;
+    EthernetInterface(const EthernetInterface&) = delete;
+    EthernetInterface& operator=(const EthernetInterface&) = delete;
+    EthernetInterface(EthernetInterface&&) = delete;
+    EthernetInterface& operator=(EthernetInterface&&) = delete;
+    virtual ~EthernetInterface() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] dhcpEnabled - is dhcp enabled(true/false).
+     *  @param[in] parent - parent object.
+     *  @param[in] emitSignal - true if the object added signal needs to be
+     *                          send.
+     */
+    EthernetInterface(sdbusplus::bus::bus& bus, const std::string& objPath,
+                      DHCPConf dhcpEnabled, Manager& parent,
+                      bool emitSignal = true);
+
+    /** @brief Function used to load the nameservers.
+     */
+    virtual void loadNameServers();
+
+    /** @brief Function to create ipAddress dbus object.
+     *  @param[in] addressType - Type of ip address.
+     *  @param[in] ipAddress- IP address.
+     *  @param[in] prefixLength - Length of prefix.
+     *  @param[in] gateway - Gateway ip address.
+     */
+
+    ObjectPath ip(IP::Protocol addressType, std::string ipAddress,
+                  uint8_t prefixLength, std::string gateway) override;
+
+    /** @brief Function to create static neighbor dbus object.
+     *  @param[in] ipAddress - IP address.
+     *  @param[in] macAddress - Low level MAC address.
+     */
+    ObjectPath neighbor(std::string ipAddress, std::string macAddress) override;
+
+    /* @brief delete the dbus object of the given ipAddress.
+     * @param[in] ipAddress - IP address.
+     */
+    void deleteObject(const std::string& ipAddress);
+
+    /* @brief delete the dbus object of the given ipAddress.
+     * @param[in] ipAddress - IP address.
+     */
+    void deleteStaticNeighborObject(const std::string& ipAddress);
+
+    /* @brief delete the vlan dbus object of the given interface.
+     *        Also deletes the device file and the network file.
+     * @param[in] interface - VLAN Interface.
+     */
+    void deleteVLANObject(const std::string& interface);
+
+    /* @brief creates the dbus object(IPaddres) given in the address list.
+     * @param[in] addrs - address list for which dbus objects needs
+     *                    to create.
+     */
+    void createIPAddressObjects();
+
+    /* @brief creates the dbus object(Neighbor) given in the neighbor list.
+     */
+    void createStaticNeighborObjects();
+
+    /* @brief Gets the index of the interface on the system
+     */
+    unsigned ifIndex() const;
+
+    /* @brief Gets all the ip addresses.
+     * @returns the list of ipAddress.
+     */
+    const AddressMap& getAddresses() const
+    {
+        return addrs;
+    }
+
+    /* @brief Gets all the static neighbor entries.
+     * @returns Static neighbor map.
+     */
+    const NeighborMap& getStaticNeighbors() const
+    {
+        return staticNeighbors;
+    }
+
+    /** Set value of DHCPEnabled */
+    DHCPConf dhcpEnabled(DHCPConf value) override;
+
+    /** @brief Selectively disables DHCP
+     *  @param[in] protocol - The IPv4 or IPv6 protocol to return to static
+     *                        addressing mode
+     */
+    void disableDHCP(IP::Protocol protocol);
+
+    /** Retrieve Link State */
+    bool linkUp() const override;
+
+    /** Retrieve NIC State */
+    bool nicEnabled() const override;
+
+    /** Set value of NICEnabled */
+    bool nicEnabled(bool value) override;
+
+    /** @brief sets the MAC address.
+     *  @param[in] value - MAC address which needs to be set on the system.
+     *  @returns macAddress of the interface or throws an error.
+     */
+    std::string macAddress(std::string value) override;
+
+    /** @brief get the IPv6AcceptRA flag from the network configuration file
+     *
+     */
+    bool getIPv6AcceptRAFromConf();
+
+    /** @brief check conf file for Router Advertisements
+     *
+     */
+    bool ipv6AcceptRA(bool value) override;
+
+    /** @brief sets the NTP servers.
+     *  @param[in] value - vector of NTP servers.
+     */
+    ServerList ntpServers(ServerList value) override;
+
+    /** @brief sets the DNS/nameservers.
+     *  @param[in] value - vector of DNS servers.
+     */
+    ServerList nameservers(ServerList value) override;
+
+    /** @brief sets the Static DNS/nameservers.
+     *  @param[in] value - vector of DNS servers.
+     */
+
+    ServerList staticNameServers(ServerList value) override;
+
+    /** @brief create Vlan interface.
+     *  @param[in] id- VLAN identifier.
+     */
+    ObjectPath createVLAN(VlanId id);
+
+    /** @brief load the vlan info from the system
+     *         and creates the ip address dbus objects.
+     *  @param[in] vlanID- VLAN identifier.
+     */
+    void loadVLAN(VlanId vlanID);
+
+    /** @brief write the network conf file with the in-memory objects.
+     */
+    void writeConfigurationFile();
+
+    /** @brief delete all dbus objects.
+     */
+    void deleteAll();
+
+    /** @brief set the default v4 gateway of the interface.
+     *  @param[in] gateway - default v4 gateway of the interface.
+     */
+    std::string defaultGateway(std::string gateway) override;
+
+    /** @brief set the default v6 gateway of the interface.
+     *  @param[in] gateway - default v6 gateway of the interface.
+     */
+    std::string defaultGateway6(std::string gateway) override;
+
+    using EthernetInterfaceIntf::dhcpEnabled;
+    using EthernetInterfaceIntf::interfaceName;
+    using EthernetInterfaceIntf::linkUp;
+    using EthernetInterfaceIntf::nicEnabled;
+    using MacAddressIntf::macAddress;
+
+    using EthernetInterfaceIntf::defaultGateway;
+    using EthernetInterfaceIntf::defaultGateway6;
+    /** @brief Absolute path of the resolv conf file */
+    static constexpr auto resolvConfFile = "/etc/resolv.conf";
+
+  protected:
+    /** @brief get the info of the ethernet interface.
+     *  @return tuple having the link speed,autonegotiation,duplexmode .
+     */
+    InterfaceInfo getInterfaceInfo() const;
+
+    /* @brief delete the vlan interface from system.
+     * @param[in] interface - vlan Interface.
+     */
+    void deleteVLANFromSystem(const std::string& interface);
+
+    /** @brief get the mac address of the interface.
+     *  @param[in] interfaceName - Network interface name.
+     *  @return macaddress on success
+     */
+
+    std::string getMACAddress(const std::string& interfaceName) const;
+
+    /** @brief construct the ip address dbus object path.
+     *  @param[in] addressType - Type of ip address.
+     *  @param[in] ipAddress - IP address.
+     *  @param[in] prefixLength - Length of prefix.
+     *  @param[in] gateway - Gateway address.
+
+     *  @return path of the address object.
+     */
+
+    std::string generateObjectPath(IP::Protocol addressType,
+                                   const std::string& ipAddress,
+                                   uint8_t prefixLength,
+                                   const std::string& gateway) const;
+
+    std::string
+        generateStaticNeighborObjectPath(const std::string& ipAddress,
+                                         const std::string& macAddress) const;
+
+    /** @brief generates the id by doing hash of ipAddress,
+     *         prefixlength and the gateway.
+     *  @param[in] ipAddress - IP address.
+     *  @param[in] prefixLength - Length of prefix.
+     *  @param[in] gateway - Gateway address.
+     *  @return hash string.
+     */
+
+    static std::string generateId(const std::string& ipAddress,
+                                  uint8_t prefixLength,
+                                  const std::string& gateway);
+
+    /** @brief generates the id by doing hash of ipAddress
+     *         and the mac address.
+     *  @param[in] ipAddress  - IP address.
+     *  @param[in] macAddress - Gateway address.
+     *  @return hash string.
+     */
+    static std::string generateNeighborId(const std::string& ipAddress,
+                                          const std::string& macAddress);
+
+    /** @brief write the dhcp section **/
+    void writeDHCPSection(std::fstream& stream);
+
+    /** @brief get the NTP server list from the network conf
+     *
+     */
+    ServerList getNTPServersFromConf();
+
+    /** @brief get the name server details from the network conf
+     *
+     */
+    virtual ServerList getNameServerFromResolvd();
+    ServerList getstaticNameServerFromConf();
+
+    /** @brief Persistent sdbusplus DBus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** @brief Network Manager object. */
+    Manager& manager;
+
+    /** @brief Persistent map of IPAddress dbus objects and their names */
+    AddressMap addrs;
+
+    /** @brief Persistent map of Neighbor dbus objects and their names */
+    NeighborMap staticNeighbors;
+
+    /** @brief Persistent map of VLAN interface dbus objects and their names */
+    VlanInterfaceMap vlanInterfaces;
+
+    /** @brief Dbus object path */
+    std::string objPath;
+
+    friend class TestEthernetInterface;
+
+  private:
+    /** @brief Determines if DHCP is active for the IP::Protocol supplied.
+     *  @param[in] protocol - Either IPv4 or IPv6
+     *  @param[in] ignoreProtocol - Allows IPv4 and IPv6 to be checked using a
+     *                              single call.
+     *  @returns true/false value if DHCP is active for the input protocol
+     */
+    bool dhcpIsEnabled(IP::Protocol protocol, bool ignoreProtocol = false);
+
+    /** @brief Determines if DHCP will be active following next reconfig
+     *  @param[in] protocol - Either IPv4 or IPv6
+     *  @param[in] nextDHCPState - The new DHCP mode to take affect
+     *  @returns true/false value if DHCP is active for the input protocol
+     */
+    bool dhcpToBeEnabled(IP::Protocol family, const std::string& nextDHCPState);
+
+    /** @brief Determines if the address is manually assigned
+     *  @param[in] origin - The origin entry of the IP::Address
+     *  @returns true/false value if the address is static
+     */
+    bool originIsManuallyAssigned(IP::AddressOrigin origin);
+};
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/ipaddress.cpp b/src/ipaddress.cpp
new file mode 100644
index 0000000..f30cf34
--- /dev/null
+++ b/src/ipaddress.cpp
@@ -0,0 +1,73 @@
+#include "config.h"
+
+#include "ipaddress.hpp"
+
+#include "ethernet_interface.hpp"
+#include "util.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+namespace phosphor
+{
+namespace network
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
+using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
+
+IPAddress::IPAddress(sdbusplus::bus::bus& bus, const char* objPath,
+                     EthernetInterface& parent, IP::Protocol type,
+                     const std::string& ipaddress, IP::AddressOrigin origin,
+                     uint8_t prefixLength, const std::string& gateway) :
+    IPIfaces(bus, objPath, true),
+    parent(parent)
+{
+
+    IP::address(ipaddress);
+    IP::prefixLength(prefixLength);
+    IP::gateway(gateway);
+    IP::type(type);
+    IP::origin(origin);
+
+    // Emit deferred signal.
+    emit_object_added();
+}
+std::string IPAddress::address(std::string /*ipAddress*/)
+{
+    elog<NotAllowed>(Reason("Property update is not allowed"));
+}
+uint8_t IPAddress::prefixLength(uint8_t /*value*/)
+{
+    elog<NotAllowed>(Reason("Property update is not allowed"));
+}
+std::string IPAddress::gateway(std::string /*gateway*/)
+{
+    elog<NotAllowed>(Reason("Property update is not allowed"));
+}
+IP::Protocol IPAddress::type(IP::Protocol /*type*/)
+{
+    elog<NotAllowed>(Reason("Property update is not allowed"));
+}
+IP::AddressOrigin IPAddress::origin(IP::AddressOrigin /*origin*/)
+{
+    elog<NotAllowed>(Reason("Property update is not allowed"));
+}
+void IPAddress::delete_()
+{
+    if (origin() != IP::AddressOrigin::Static)
+    {
+        log<level::ERR>("Tried to delete a non-static address"),
+            entry("ADDRESS=%s", address().c_str()),
+            entry("PREFIX=%" PRIu8, prefixLength()),
+            entry("INTERFACE=%s", parent.interfaceName().c_str());
+        elog<InternalFailure>();
+    }
+
+    parent.deleteObject(address());
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/ipaddress.hpp b/src/ipaddress.hpp
new file mode 100644
index 0000000..3ed551a
--- /dev/null
+++ b/src/ipaddress.hpp
@@ -0,0 +1,75 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <xyz/openbmc_project/Network/IP/server.hpp>
+#include <xyz/openbmc_project/Object/Delete/server.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using IPIfaces = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::Network::server::IP,
+    sdbusplus::xyz::openbmc_project::Object::server::Delete>;
+
+using IP = sdbusplus::xyz::openbmc_project::Network::server::IP;
+
+class EthernetInterface;
+
+/** @class IPAddress
+ *  @brief OpenBMC IPAddress implementation.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.IPProtocol
+ *  xyz.openbmc_project.Network.IP Dbus interfaces.
+ */
+class IPAddress : public IPIfaces
+{
+  public:
+    IPAddress() = delete;
+    IPAddress(const IPAddress&) = delete;
+    IPAddress& operator=(const IPAddress&) = delete;
+    IPAddress(IPAddress&&) = delete;
+    IPAddress& operator=(IPAddress&&) = delete;
+    virtual ~IPAddress() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] parent - Parent object.
+     *  @param[in] type - ipaddress type(v4/v6).
+     *  @param[in] ipAddress - ipadress.
+     *  @param[in] origin - origin of ipaddress(dhcp/static/SLAAC/LinkLocal).
+     *  @param[in] prefixLength - Length of prefix.
+     *  @param[in] gateway - gateway address.
+     */
+    IPAddress(sdbusplus::bus::bus& bus, const char* objPath,
+              EthernetInterface& parent, IP::Protocol type,
+              const std::string& ipAddress, IP::AddressOrigin origin,
+              uint8_t prefixLength, const std::string& gateway);
+
+    std::string address(std::string ipAddress) override;
+    uint8_t prefixLength(uint8_t) override;
+    std::string gateway(std::string gateway) override;
+    IP::Protocol type(IP::Protocol type) override;
+    IP::AddressOrigin origin(IP::AddressOrigin origin) override;
+
+    /** @brief Delete this d-bus object.
+     */
+    void delete_() override;
+
+    using IP::address;
+    using IP::gateway;
+    using IP::origin;
+    using IP::prefixLength;
+    using IP::type;
+
+  private:
+    /** @brief Parent Object. */
+    EthernetInterface& parent;
+};
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..31371f9
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,94 @@
+phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
+phosphor_logging_dep = dependency('phosphor-logging')
+
+src_includes = include_directories('.')
+
+executable(
+  'ncsi-netlink',
+  'argument.cpp',
+  'ncsi_netlink_main.cpp',
+  'ncsi_util.cpp',
+  implicit_include_directories: false,
+  include_directories: src_includes,
+  dependencies: [
+    dependency('libnl-3.0'),
+    dependency('libnl-genl-3.0'),
+    phosphor_dbus_interfaces_dep,
+    phosphor_logging_dep,
+  ],
+  install: true,
+  install_dir: get_option('bindir'))
+
+json_dep = declare_dependency()
+if get_option('sync-mac')
+  # nlohmann_json might not have a pkg-config. It is header only so just make
+  # sure we can access the needed symbols from the header.
+  has_json = meson.get_compiler('cpp').has_header_symbol(
+    'nlohmann/json.hpp',
+    'nlohmann::json::string_t',
+    required: false)
+  if not has_json
+    json_dep = dependency(
+      'nlohmann_json',
+      fallback: ['nlohmann_json', 'nlohmann_json_dep'],
+      required: true)
+  endif
+endif
+
+networkd_deps = [
+  json_dep,
+  phosphor_dbus_interfaces_dep,
+  phosphor_logging_dep,
+  sdbusplus_dep,
+  dependency('sdeventplus', fallback: ['sdeventplus', 'sdeventplus_dep']),
+  dependency('stdplus', fallback: ['stdplus', 'stdplus_dep']),
+]
+
+conf_header = configure_file(
+  output: 'config.h',
+  configuration: conf_data)
+
+networkd_generated = [
+  conf_header,
+] + generated_sources
+
+networkd_includes = [
+  src_includes,
+  generated_includes,
+]
+
+networkd_lib = static_library(
+  'networkd',
+  networkd_generated,
+  'ethernet_interface.cpp',
+  'neighbor.cpp',
+  'ipaddress.cpp',
+  'netlink.cpp',
+  'network_config.cpp',
+  'network_manager.cpp',
+  'system_configuration.cpp',
+  'util.cpp',
+  'routing_table.cpp',
+  'config_parser.cpp',
+  'dhcp_configuration.cpp',
+  'vlan_interface.cpp',
+  'rtnetlink_server.cpp',
+  'dns_updater.cpp',
+  'watch.cpp',
+  implicit_include_directories: false,
+  include_directories: networkd_includes,
+  dependencies: networkd_deps)
+
+networkd_dep = declare_dependency(
+  sources: networkd_generated,
+  dependencies: networkd_deps,
+  include_directories: networkd_includes,
+  link_with: networkd_lib)
+
+executable(
+  'phosphor-network-manager',
+  'network_manager_main.cpp',
+  implicit_include_directories: false,
+  dependencies: networkd_dep,
+  install: true,
+  install_dir: get_option('bindir'))
diff --git a/src/ncsi_netlink_main.cpp b/src/ncsi_netlink_main.cpp
new file mode 100644
index 0000000..9db624f
--- /dev/null
+++ b/src/ncsi_netlink_main.cpp
@@ -0,0 +1,111 @@
+/**
+ * Copyright © 2018 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "argument.hpp"
+#include "ncsi_util.hpp"
+
+#include <iostream>
+#include <string>
+
+static void exitWithError(const char* err, char** argv)
+{
+    phosphor::network::ncsi::ArgumentParser::usage(argv);
+    std::cerr << "ERROR: " << err << "\n";
+    exit(EXIT_FAILURE);
+}
+
+int main(int argc, char** argv)
+{
+    using namespace phosphor::network;
+    using namespace phosphor::network::ncsi;
+    // Read arguments.
+    auto options = ArgumentParser(argc, argv);
+    int packageInt{};
+    int channelInt{};
+    int indexInt{};
+
+    // Parse out interface argument.
+    auto ifIndex = (options)["index"];
+    try
+    {
+        indexInt = stoi(ifIndex, nullptr);
+    }
+    catch (const std::exception& e)
+    {
+        exitWithError("Interface not specified.", argv);
+    }
+
+    if (indexInt < 0)
+    {
+        exitWithError("Interface value should be greater than equal to 0",
+                      argv);
+    }
+
+    // Parse out package argument.
+    auto package = (options)["package"];
+    try
+    {
+        packageInt = stoi(package, nullptr);
+    }
+    catch (const std::exception& e)
+    {
+        packageInt = DEFAULT_VALUE;
+    }
+
+    if (packageInt < 0)
+    {
+        packageInt = DEFAULT_VALUE;
+    }
+
+    // Parse out channel argument.
+    auto channel = (options)["channel"];
+    try
+    {
+        channelInt = stoi(channel, nullptr);
+    }
+    catch (const std::exception& e)
+    {
+        channelInt = DEFAULT_VALUE;
+    }
+
+    if (channelInt < 0)
+    {
+        channelInt = DEFAULT_VALUE;
+    }
+
+    auto setCmd = (options)["set"];
+    if (setCmd == "true")
+    {
+        // Can not perform set operation without package.
+        if (packageInt == DEFAULT_VALUE)
+        {
+            exitWithError("Package not specified.", argv);
+        }
+        return ncsi::setChannel(indexInt, packageInt, channelInt);
+    }
+    else if ((options)["info"] == "true")
+    {
+        return ncsi::getInfo(indexInt, packageInt);
+    }
+    else if ((options)["clear"] == "true")
+    {
+        return ncsi::clearInterface(indexInt);
+    }
+    else
+    {
+        exitWithError("No Command specified", argv);
+    }
+    return 0;
+}
diff --git a/src/ncsi_util.cpp b/src/ncsi_util.cpp
new file mode 100644
index 0000000..902911d
--- /dev/null
+++ b/src/ncsi_util.cpp
@@ -0,0 +1,301 @@
+#include "ncsi_util.hpp"
+
+#include <linux/ncsi.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/genl/genl.h>
+#include <netlink/netlink.h>
+
+#include <iostream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+namespace ncsi
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+using CallBack = int (*)(struct nl_msg* msg, void* arg);
+
+namespace internal
+{
+
+using nlMsgPtr = std::unique_ptr<nl_msg, decltype(&::nlmsg_free)>;
+using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>;
+
+CallBack infoCallBack = [](struct nl_msg* msg, void* /*arg*/) {
+    using namespace phosphor::network::ncsi;
+    auto nlh = nlmsg_hdr(msg);
+
+    struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
+    struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
+        {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
+        {NLA_U32, 0, 0},    {NLA_U32, 0, 0},
+    };
+
+    struct nlattr* packagetb[NCSI_PKG_ATTR_MAX + 1] = {nullptr};
+    struct nla_policy packagePolicy[NCSI_PKG_ATTR_MAX + 1] = {
+        {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
+        {NLA_FLAG, 0, 0},   {NLA_NESTED, 0, 0},
+    };
+
+    struct nlattr* channeltb[NCSI_CHANNEL_ATTR_MAX + 1] = {nullptr};
+    struct nla_policy channelPolicy[NCSI_CHANNEL_ATTR_MAX + 1] = {
+        {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
+        {NLA_FLAG, 0, 0},   {NLA_NESTED, 0, 0}, {NLA_UNSPEC, 0, 0},
+    };
+
+    auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
+    if (!tb[NCSI_ATTR_PACKAGE_LIST])
+    {
+        std::cerr << "No Packages" << std::endl;
+        return -1;
+    }
+
+    auto attrTgt = static_cast<nlattr*>(nla_data(tb[NCSI_ATTR_PACKAGE_LIST]));
+    if (!attrTgt)
+    {
+        std::cerr << "Package list attribute is null" << std::endl;
+        return -1;
+    }
+
+    auto rem = nla_len(tb[NCSI_ATTR_PACKAGE_LIST]);
+    nla_for_each_nested(attrTgt, tb[NCSI_ATTR_PACKAGE_LIST], rem)
+    {
+        ret = nla_parse_nested(packagetb, NCSI_PKG_ATTR_MAX, attrTgt,
+                               packagePolicy);
+        if (ret < 0)
+        {
+            std::cerr << "Failed to parse package nested" << std::endl;
+            return -1;
+        }
+
+        if (packagetb[NCSI_PKG_ATTR_ID])
+        {
+            auto attrID = nla_get_u32(packagetb[NCSI_PKG_ATTR_ID]);
+            std::cout << "Package has id : " << std::hex << attrID << std::endl;
+        }
+        else
+        {
+            std::cout << "Package with no id" << std::endl;
+        }
+
+        if (packagetb[NCSI_PKG_ATTR_FORCED])
+        {
+            std::cout << "This package is forced" << std::endl;
+        }
+
+        auto channelListTarget = static_cast<nlattr*>(
+            nla_data(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]));
+
+        auto channelrem = nla_len(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]);
+        nla_for_each_nested(channelListTarget,
+                            packagetb[NCSI_PKG_ATTR_CHANNEL_LIST], channelrem)
+        {
+            ret = nla_parse_nested(channeltb, NCSI_CHANNEL_ATTR_MAX,
+                                   channelListTarget, channelPolicy);
+            if (ret < 0)
+            {
+                std::cerr << "Failed to parse channel nested" << std::endl;
+                return -1;
+            }
+
+            if (channeltb[NCSI_CHANNEL_ATTR_ID])
+            {
+                auto channel = nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_ID]);
+                if (channeltb[NCSI_CHANNEL_ATTR_ACTIVE])
+                {
+                    std::cout << "Channel Active : " << std::hex << channel
+                              << std::endl;
+                }
+                else
+                {
+                    std::cout << "Channel Not Active : " << std::hex << channel
+                              << std::endl;
+                }
+
+                if (channeltb[NCSI_CHANNEL_ATTR_FORCED])
+                {
+                    std::cout << "Channel is forced" << std::endl;
+                }
+            }
+            else
+            {
+                std::cout << "Channel with no ID" << std::endl;
+            }
+
+            if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR])
+            {
+                auto major =
+                    nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR]);
+                std::cout << "Channel Major Version : " << std::hex << major
+                          << std::endl;
+            }
+            if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR])
+            {
+                auto minor =
+                    nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR]);
+                std::cout << "Channel Minor Version : " << std::hex << minor
+                          << std::endl;
+            }
+            if (channeltb[NCSI_CHANNEL_ATTR_VERSION_STR])
+            {
+                auto str =
+                    nla_get_string(channeltb[NCSI_CHANNEL_ATTR_VERSION_STR]);
+                std::cout << "Channel Version Str :" << str << std::endl;
+            }
+            if (channeltb[NCSI_CHANNEL_ATTR_LINK_STATE])
+            {
+
+                auto link =
+                    nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_LINK_STATE]);
+                std::cout << "Channel Link State : " << std::hex << link
+                          << std::endl;
+            }
+            if (channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST])
+            {
+                std::cout << "Active Vlan ids" << std::endl;
+                auto vids = channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST];
+                auto vid = static_cast<nlattr*>(nla_data(vids));
+                auto len = nla_len(vids);
+                while (nla_ok(vid, len))
+                {
+                    auto id = nla_get_u16(vid);
+                    std::cout << "VID : " << id << std::endl;
+                    vid = nla_next(vid, &len);
+                }
+            }
+        }
+    }
+    return (int)NL_SKIP;
+};
+
+int applyCmd(int ifindex, int cmd, int package = DEFAULT_VALUE,
+             int channel = DEFAULT_VALUE, int flags = NONE,
+             CallBack function = nullptr)
+{
+    nlSocketPtr socket(nl_socket_alloc(), &::nl_socket_free);
+    auto ret = genl_connect(socket.get());
+    if (ret < 0)
+    {
+        std::cerr << "Failed to open the socket , RC : " << ret << std::endl;
+        return ret;
+    }
+
+    auto driverID = genl_ctrl_resolve(socket.get(), "NCSI");
+    if (driverID < 0)
+    {
+        std::cerr << "Failed to resolve, RC : " << ret << std::endl;
+        return driverID;
+    }
+
+    nlMsgPtr msg(nlmsg_alloc(), &::nlmsg_free);
+
+    auto msgHdr = genlmsg_put(msg.get(), 0, 0, driverID, 0, flags, cmd, 0);
+    if (!msgHdr)
+    {
+        std::cerr << "Unable to add the netlink headers , COMMAND : " << cmd
+                  << std::endl;
+        return -1;
+    }
+
+    if (package != DEFAULT_VALUE)
+    {
+        ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_PACKAGE_ID,
+                          package);
+        if (ret < 0)
+        {
+            std::cerr << "Failed to set the attribute , RC : " << ret
+                      << "PACKAGE " << std::hex << package << std::endl;
+            return ret;
+        }
+    }
+
+    if (channel != DEFAULT_VALUE)
+    {
+        ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_CHANNEL_ID,
+                          channel);
+        if (ret < 0)
+        {
+            std::cerr << "Failed to set the attribute , RC : " << ret
+                      << "CHANNEL : " << std::hex << channel << std::endl;
+            return ret;
+        }
+    }
+
+    ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_IFINDEX, ifindex);
+    if (ret < 0)
+    {
+        std::cerr << "Failed to set the attribute , RC : " << ret
+                  << "INTERFACE : " << std::hex << ifindex << std::endl;
+        return ret;
+    }
+
+    if (function)
+    {
+        // Add a callback function to the socket
+        nl_socket_modify_cb(socket.get(), NL_CB_VALID, NL_CB_CUSTOM, function,
+                            nullptr);
+    }
+
+    ret = nl_send_auto(socket.get(), msg.get());
+    if (ret < 0)
+    {
+        std::cerr << "Failed to send the message , RC : " << ret << std::endl;
+        return ret;
+    }
+
+    ret = nl_recvmsgs_default(socket.get());
+    if (ret < 0)
+    {
+        std::cerr << "Failed to receive the message , RC : " << ret
+                  << std::endl;
+    }
+    return ret;
+}
+
+} // namespace internal
+
+int setChannel(int ifindex, int package, int channel)
+{
+    std::cout << "Set Channel : " << std::hex << channel
+              << ", PACKAGE : " << std::hex << package
+              << ", IFINDEX :  " << std::hex << ifindex << std::endl;
+    return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_SET_INTERFACE,
+                              package, channel);
+}
+
+int clearInterface(int ifindex)
+{
+    std::cout << "ClearInterface , IFINDEX :" << std::hex << ifindex
+              << std::endl;
+    return internal::applyCmd(ifindex,
+                              ncsi_nl_commands::NCSI_CMD_CLEAR_INTERFACE);
+}
+
+int getInfo(int ifindex, int package)
+{
+    std::cout << "Get Info , PACKAGE :  " << std::hex << package
+              << ", IFINDEX :  " << std::hex << ifindex << std::endl;
+    if (package == DEFAULT_VALUE)
+    {
+        return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_PKG_INFO,
+                                  package, DEFAULT_VALUE, NLM_F_DUMP,
+                                  internal::infoCallBack);
+    }
+    else
+    {
+        return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_PKG_INFO,
+                                  package, DEFAULT_VALUE, NONE,
+                                  internal::infoCallBack);
+    }
+}
+
+} // namespace ncsi
+} // namespace network
+} // namespace phosphor
diff --git a/src/ncsi_util.hpp b/src/ncsi_util.hpp
new file mode 100644
index 0000000..db754fe
--- /dev/null
+++ b/src/ncsi_util.hpp
@@ -0,0 +1,44 @@
+namespace phosphor
+{
+namespace network
+{
+namespace ncsi
+{
+
+constexpr auto DEFAULT_VALUE = -1;
+constexpr auto NONE = 0;
+
+/* @brief  This function will ask underlying NCSI driver
+ *         to set a specific  package or package/channel
+ *         combination as the preferred choice.
+ *         This function talks with the NCSI driver over
+ *         netlink messages.
+ * @param[in] ifindex - Interface Index.
+ * @param[in] package - NCSI Package.
+ * @param[in] channel - Channel number with in the package.
+ * @returns 0 on success and negative value for failure.
+ */
+int setChannel(int ifindex, int package, int channel);
+
+/* @brief  This function will ask underlying NCSI driver
+ *         to clear any preferred setting from the given
+ *         interface.
+ *         This function talks with the NCSI driver over
+ *         netlink messages.
+ * @param[in] ifindex - Interface Index.
+ * @returns 0 on success and negative value for failure.
+ */
+int clearInterface(int ifindex);
+
+/* @brief  This function is used to dump all the info
+ *         of the package and the channels underlying
+ *         the package.
+ * @param[in] ifindex - Interface Index.
+ * @param[in] package - NCSI Package.
+ * @returns 0 on success and negative value for failure.
+ */
+int getInfo(int ifindex, int package);
+
+} // namespace ncsi
+} // namespace network
+} // namespace phosphor
diff --git a/src/neighbor.cpp b/src/neighbor.cpp
new file mode 100644
index 0000000..11b0666
--- /dev/null
+++ b/src/neighbor.cpp
@@ -0,0 +1,108 @@
+#include "config.h"
+
+#include "neighbor.hpp"
+
+#include "ethernet_interface.hpp"
+#include "netlink.hpp"
+#include "util.hpp"
+
+#include <linux/neighbour.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <stdexcept>
+#include <stdplus/raw.hpp>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace phosphor
+{
+namespace network
+{
+namespace detail
+{
+
+void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr,
+                   std::string_view msg, std::vector<NeighborInfo>& neighbors)
+{
+    if (hdr.nlmsg_type != RTM_NEWNEIGH)
+    {
+        throw std::runtime_error("Not a neighbor msg");
+    }
+    auto ndm = stdplus::raw::extract<ndmsg>(msg);
+
+    // Filter out neighbors we don't care about
+    unsigned ifindex = ndm.ndm_ifindex;
+    if (filter.interface != 0 && filter.interface != ifindex)
+    {
+        return;
+    }
+    if ((ndm.ndm_state & filter.state) == 0)
+    {
+        return;
+    }
+
+    // Build the neighbor info for our valid neighbor
+    NeighborInfo neighbor;
+    neighbor.interface = ifindex;
+    neighbor.state = ndm.ndm_state;
+    bool set_addr = false;
+    while (!msg.empty())
+    {
+        auto [hdr, data] = netlink::extractRtAttr(msg);
+        if (hdr.rta_type == NDA_LLADDR)
+        {
+            neighbor.mac = stdplus::raw::copyFrom<ether_addr>(data);
+        }
+        else if (hdr.rta_type == NDA_DST)
+        {
+            neighbor.address = addrFromBuf(ndm.ndm_family, data);
+            set_addr = true;
+        }
+    }
+    if (!set_addr)
+    {
+        throw std::runtime_error("Missing address");
+    }
+    neighbors.push_back(std::move(neighbor));
+}
+
+} // namespace detail
+
+std::vector<NeighborInfo> getCurrentNeighbors(const NeighborFilter& filter)
+{
+    std::vector<NeighborInfo> neighbors;
+    auto cb = [&filter, &neighbors](const nlmsghdr& hdr, std::string_view msg) {
+        detail::parseNeighbor(filter, hdr, msg, neighbors);
+    };
+    ndmsg msg{};
+    msg.ndm_ifindex = filter.interface;
+    netlink::performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, msg, cb);
+    return neighbors;
+}
+
+Neighbor::Neighbor(sdbusplus::bus::bus& bus, const char* objPath,
+                   EthernetInterface& parent, const std::string& ipAddress,
+                   const std::string& macAddress, State state) :
+    NeighborObj(bus, objPath, true),
+    parent(parent)
+{
+    this->ipAddress(ipAddress);
+    this->macAddress(macAddress);
+    this->state(state);
+
+    // Emit deferred signal.
+    emit_object_added();
+}
+
+void Neighbor::delete_()
+{
+    parent.deleteStaticNeighborObject(ipAddress());
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/neighbor.hpp b/src/neighbor.hpp
new file mode 100644
index 0000000..cca9c11
--- /dev/null
+++ b/src/neighbor.hpp
@@ -0,0 +1,105 @@
+#pragma once
+
+#include "types.hpp"
+
+#include <linux/netlink.h>
+#include <net/ethernet.h>
+
+#include <cstdint>
+#include <optional>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <string_view>
+#include <vector>
+#include <xyz/openbmc_project/Network/Neighbor/server.hpp>
+#include <xyz/openbmc_project/Object/Delete/server.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using NeighborIntf = sdbusplus::xyz::openbmc_project::Network::server::Neighbor;
+
+using NeighborObj = sdbusplus::server::object::object<
+    NeighborIntf, sdbusplus::xyz::openbmc_project::Object::server::Delete>;
+
+class EthernetInterface;
+
+/* @class NeighborFilter
+ */
+struct NeighborFilter
+{
+    unsigned interface;
+    uint16_t state;
+
+    /* @brief Creates an empty filter */
+    NeighborFilter() : interface(0), state(~UINT16_C(0))
+    {
+    }
+};
+
+/** @class NeighborInfo
+ *  @brief Information about a neighbor from the kernel
+ */
+struct NeighborInfo
+{
+    unsigned interface;
+    InAddrAny address;
+    std::optional<ether_addr> mac;
+    uint16_t state;
+};
+
+/** @brief Returns a list of the current system neighbor table
+ */
+std::vector<NeighborInfo> getCurrentNeighbors(const NeighborFilter& filter);
+
+/** @class Neighbor
+ *  @brief OpenBMC network neighbor implementation.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.Neighbor dbus interface.
+ */
+class Neighbor : public NeighborObj
+{
+  public:
+    using State = NeighborIntf::State;
+
+    Neighbor() = delete;
+    Neighbor(const Neighbor&) = delete;
+    Neighbor& operator=(const Neighbor&) = delete;
+    Neighbor(Neighbor&&) = delete;
+    Neighbor& operator=(Neighbor&&) = delete;
+    virtual ~Neighbor() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] parent - Parent object.
+     *  @param[in] ipAddress - IP address.
+     *  @param[in] macAddress - Low level MAC address.
+     *  @param[in] state - The state of the neighbor entry.
+     */
+    Neighbor(sdbusplus::bus::bus& bus, const char* objPath,
+             EthernetInterface& parent, const std::string& ipAddress,
+             const std::string& macAddress, State state);
+
+    /** @brief Delete this d-bus object.
+     */
+    void delete_() override;
+
+  private:
+    /** @brief Parent Object. */
+    EthernetInterface& parent;
+};
+
+namespace detail
+{
+
+void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr,
+                   std::string_view msg, std::vector<NeighborInfo>& neighbors);
+
+} // namespace detail
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/netlink.cpp b/src/netlink.cpp
new file mode 100644
index 0000000..9039575
--- /dev/null
+++ b/src/netlink.cpp
@@ -0,0 +1,195 @@
+#include "netlink.hpp"
+
+#include "util.hpp"
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <array>
+#include <stdexcept>
+#include <stdplus/raw.hpp>
+#include <system_error>
+
+namespace phosphor
+{
+namespace network
+{
+namespace netlink
+{
+namespace detail
+{
+
+void processMsg(std::string_view& msgs, bool& done, const ReceiveCallback& cb)
+{
+    // Parse and update the message buffer
+    auto hdr = stdplus::raw::copyFrom<nlmsghdr>(msgs);
+    if (hdr.nlmsg_len < sizeof(hdr))
+    {
+        throw std::runtime_error("Invalid nlmsg length");
+    }
+    if (msgs.size() < hdr.nlmsg_len)
+    {
+        throw std::runtime_error("Bad nlmsg payload");
+    }
+    auto msg = msgs.substr(NLMSG_HDRLEN, hdr.nlmsg_len - NLMSG_HDRLEN);
+    msgs.remove_prefix(NLMSG_ALIGN(hdr.nlmsg_len));
+
+    // Figure out how to handle the individual message
+    bool doCallback = true;
+    if (hdr.nlmsg_flags & NLM_F_MULTI)
+    {
+        done = false;
+    }
+    if (hdr.nlmsg_type == NLMSG_NOOP)
+    {
+        doCallback = false;
+    }
+    else if (hdr.nlmsg_type == NLMSG_DONE)
+    {
+        if (done)
+        {
+            throw std::runtime_error("Got done for non-multi msg");
+        }
+        done = true;
+        doCallback = false;
+    }
+    else if (hdr.nlmsg_type == NLMSG_ERROR)
+    {
+        auto err = stdplus::raw::copyFrom<nlmsgerr>(msg);
+        // This is just an ACK so don't do the callback
+        if (err.error <= 0)
+        {
+            doCallback = false;
+        }
+    }
+    // All multi-msg headers must have the multi flag
+    if (!done && !(hdr.nlmsg_flags & NLM_F_MULTI))
+    {
+        throw std::runtime_error("Got non-multi msg before done");
+    }
+    if (doCallback)
+    {
+        cb(hdr, msg);
+    }
+}
+
+static void receive(int sock, const ReceiveCallback& cb)
+{
+    // We need to make sure we have enough room for an entire packet otherwise
+    // it gets truncated. The netlink docs guarantee packets will not exceed 8K
+    std::array<char, 8192> buf;
+
+    iovec iov{};
+    iov.iov_base = buf.data();
+    iov.iov_len = buf.size();
+
+    sockaddr_nl from{};
+    from.nl_family = AF_NETLINK;
+
+    msghdr hdr{};
+    hdr.msg_name = &from;
+    hdr.msg_namelen = sizeof(from);
+    hdr.msg_iov = &iov;
+    hdr.msg_iovlen = 1;
+
+    // We only do multiple recvs if we have a MULTI type message
+    bool done = true;
+    do
+    {
+        ssize_t recvd = recvmsg(sock, &hdr, 0);
+        if (recvd < 0)
+        {
+            throw std::system_error(errno, std::generic_category(),
+                                    "netlink recvmsg");
+        }
+        if (recvd == 0)
+        {
+            throw std::runtime_error("netlink recvmsg: Got empty payload");
+        }
+
+        std::string_view msgs(buf.data(), recvd);
+        do
+        {
+            processMsg(msgs, done, cb);
+        } while (!done && !msgs.empty());
+
+        if (done && !msgs.empty())
+        {
+            throw std::runtime_error("Extra unprocessed netlink messages");
+        }
+    } while (!done);
+}
+
+static void requestSend(int sock, void* data, size_t size)
+{
+    sockaddr_nl dst{};
+    dst.nl_family = AF_NETLINK;
+
+    iovec iov{};
+    iov.iov_base = data;
+    iov.iov_len = size;
+
+    msghdr hdr{};
+    hdr.msg_name = reinterpret_cast<sockaddr*>(&dst);
+    hdr.msg_namelen = sizeof(dst);
+    hdr.msg_iov = &iov;
+    hdr.msg_iovlen = 1;
+
+    if (sendmsg(sock, &hdr, 0) < 0)
+    {
+        throw std::system_error(errno, std::generic_category(),
+                                "netlink sendmsg");
+    }
+}
+
+static int newRequestSocket(int protocol)
+{
+    int sock = socket(AF_NETLINK, SOCK_RAW, protocol);
+    if (sock < 0)
+    {
+        throw std::system_error(errno, std::generic_category(), "netlink open");
+    }
+
+    sockaddr_nl local{};
+    local.nl_family = AF_NETLINK;
+    int r = bind(sock, reinterpret_cast<sockaddr*>(&local), sizeof(local));
+    if (r < 0)
+    {
+        close(sock);
+        throw std::system_error(errno, std::generic_category(), "netlink bind");
+    }
+
+    return sock;
+}
+
+void performRequest(int protocol, void* data, size_t size,
+                    const ReceiveCallback& cb)
+{
+    Descriptor sock(newRequestSocket(protocol));
+    requestSend(sock(), data, size);
+    receive(sock(), cb);
+}
+
+} // namespace detail
+
+std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data)
+{
+    auto hdr = stdplus::raw::copyFrom<rtattr>(data);
+    if (hdr.rta_len < RTA_LENGTH(0))
+    {
+        throw std::runtime_error("Invalid rtattr length");
+    }
+    if (data.size() < hdr.rta_len)
+    {
+        throw std::runtime_error("Not enough data for rtattr");
+    }
+    auto attr = data.substr(RTA_LENGTH(0), hdr.rta_len - RTA_LENGTH(0));
+    data.remove_prefix(RTA_ALIGN(hdr.rta_len));
+    return {hdr, attr};
+}
+
+} // namespace netlink
+} // namespace network
+} // namespace phosphor
diff --git a/src/netlink.hpp b/src/netlink.hpp
new file mode 100644
index 0000000..e1a8253
--- /dev/null
+++ b/src/netlink.hpp
@@ -0,0 +1,69 @@
+#pragma once
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <functional>
+#include <string_view>
+#include <tuple>
+#include <type_traits>
+
+namespace phosphor
+{
+namespace network
+{
+namespace netlink
+{
+
+/* @brief Called on each nlmsg received on the socket
+ */
+using ReceiveCallback = std::function<void(const nlmsghdr&, std::string_view)>;
+
+namespace detail
+{
+
+void processMsg(std::string_view& msgs, bool& done, const ReceiveCallback& cb);
+
+void performRequest(int protocol, void* data, size_t size,
+                    const ReceiveCallback& cb);
+
+} // namespace detail
+
+/* @brief Call on a block of rtattrs to parse a single one out
+ *        Updates the input to remove the attr parsed out.
+ *
+ * @param[in,out] attrs - The buffer holding rtattrs to parse
+ * @return A tuple of rtattr header + data buffer for the attr
+ */
+std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data);
+
+/** @brief Performs a netlink request of the specified type with the given
+ *  message Calls the callback upon receiving
+ *
+ *  @param[in] protocol - The netlink protocol to use when opening the socket
+ *  @param[in] type     - The netlink message type
+ *  @param[in] flags    - Additional netlink flags for the request
+ *  @param[in] msg      - The message payload for the request
+ *  @param[in] cb       - Called for each response message payload
+ */
+template <typename T>
+void performRequest(int protocol, uint16_t type, uint16_t flags, const T& msg,
+                    const ReceiveCallback& cb)
+{
+    static_assert(std::is_trivially_copyable_v<T>);
+
+    struct
+    {
+        nlmsghdr hdr;
+        T msg;
+    } data{};
+    data.hdr.nlmsg_len = sizeof(data);
+    data.hdr.nlmsg_type = type;
+    data.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+    data.msg = msg;
+
+    detail::performRequest(protocol, &data, sizeof(data), cb);
+}
+
+} // namespace netlink
+} // namespace network
+} // namespace phosphor
diff --git a/src/network_config.cpp b/src/network_config.cpp
new file mode 100644
index 0000000..94c8eae
--- /dev/null
+++ b/src/network_config.cpp
@@ -0,0 +1,47 @@
+#include "config.h"
+
+#include "network_config.hpp"
+
+#include <fstream>
+#include <string>
+
+namespace phosphor
+{
+namespace network
+{
+
+namespace bmc
+{
+void writeDHCPDefault(const std::string& filename, const std::string& interface)
+{
+    std::ofstream filestream;
+
+    filestream.open(filename);
+    // Add the following line to your phosphor-network bbappend file
+    // to control IPV6_ACCEPT_RA
+    //   EXTRA_OECONF_append = " --enable-ipv6-accept-ra=yes"
+    // If this switch is not present or set to 'no'
+    // ENABLE_IPV6_ACCEPT_RA will be undefined.
+    // The new value is only assigned on first boot, when the default
+    // file is not present, or after the default file has been
+    // manually removed.
+    filestream << "[Match]\nName=" << interface <<
+                "\n[Network]\nDHCP=true\n"
+#ifdef LINK_LOCAL_AUTOCONFIGURATION
+                "LinkLocalAddressing=yes\n"
+#else
+                "LinkLocalAddressing=no\n"
+#endif
+#ifdef ENABLE_IPV6_ACCEPT_RA
+                "IPv6AcceptRA=true\n"
+#else
+                "IPv6AcceptRA=false\n"
+
+#endif
+                "[DHCP]\nClientIdentifier=mac\n";
+    filestream.close();
+}
+} // namespace bmc
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/network_config.hpp b/src/network_config.hpp
new file mode 100644
index 0000000..7260ca2
--- /dev/null
+++ b/src/network_config.hpp
@@ -0,0 +1,15 @@
+#include <string>
+
+namespace phosphor
+{
+namespace network
+{
+
+namespace bmc
+{
+void writeDHCPDefault(const std::string& filename,
+                      const std::string& interface);
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/network_manager.cpp b/src/network_manager.cpp
new file mode 100644
index 0000000..751d1a1
--- /dev/null
+++ b/src/network_manager.cpp
@@ -0,0 +1,289 @@
+#include "config.h"
+
+#include "network_manager.hpp"
+
+#include "ipaddress.hpp"
+#include "network_config.hpp"
+#include "types.hpp"
+#include "util.hpp"
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <net/if.h>
+
+#include <algorithm>
+#include <bitset>
+#include <filesystem>
+#include <fstream>
+#include <map>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <string>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+constexpr char SYSTEMD_BUSNAME[] = "org.freedesktop.systemd1";
+constexpr char SYSTEMD_PATH[] = "/org/freedesktop/systemd1";
+constexpr char SYSTEMD_INTERFACE[] = "org.freedesktop.systemd1.Manager";
+constexpr auto FirstBootFile = "/var/lib/network/firstBoot_";
+
+namespace phosphor
+{
+namespace network
+{
+
+extern std::unique_ptr<Timer> refreshObjectTimer;
+extern std::unique_ptr<Timer> restartTimer;
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+Manager::Manager(sdbusplus::bus::bus& bus, const char* objPath,
+                 const std::string& path) :
+    details::VLANCreateIface(bus, objPath, true),
+    bus(bus), objectPath(objPath)
+{
+    fs::path confDir(path);
+    setConfDir(confDir);
+}
+
+bool Manager::createDefaultNetworkFiles(bool force)
+{
+    auto isCreated = false;
+    try
+    {
+        // Directory would have created before with
+        // setConfDir function.
+        if (force)
+        {
+            // Factory Reset case
+            // we need to forcefully write the files
+            // so delete the existing ones.
+            if (fs::is_directory(confDir))
+            {
+                for (const auto& file : fs::directory_iterator(confDir))
+                {
+                    fs::remove(file.path());
+                }
+            }
+        }
+
+        auto interfaceStrList = getInterfaces();
+        for (const auto& interface : interfaceStrList)
+        {
+            // if the interface has '.' in the name, it means that this is a
+            // VLAN - don't create the network file.
+            if (interface.find(".") != std::string::npos)
+            {
+                continue;
+            }
+
+            auto fileName = systemd::config::networkFilePrefix + interface +
+                            systemd::config::networkFileSuffix;
+
+            fs::path filePath = confDir;
+            filePath /= fileName;
+
+            // create the interface specific network file
+            // if not exist or we forcefully wants to write
+            // the network file.
+
+            if (force || !fs::is_regular_file(filePath.string()))
+            {
+                bmc::writeDHCPDefault(filePath.string(), interface);
+                log<level::INFO>("Created the default network file.",
+                                 entry("INTERFACE=%s", interface.c_str()));
+                isCreated = true;
+            }
+        }
+    }
+    catch (std::exception& e)
+    {
+        log<level::ERR>("Unable to create the default network file");
+    }
+    return isCreated;
+}
+
+void Manager::setConfDir(const fs::path& dir)
+{
+    confDir = dir;
+
+    if (!fs::exists(confDir))
+    {
+        if (!fs::create_directories(confDir))
+        {
+            log<level::ERR>("Unable to create the network conf dir",
+                            entry("DIR=%s", confDir.c_str()));
+            elog<InternalFailure>();
+        }
+    }
+}
+
+void Manager::createInterfaces()
+{
+    // clear all the interfaces first
+    interfaces.clear();
+
+    auto interfaceStrList = getInterfaces();
+
+    for (auto& interface : interfaceStrList)
+    {
+        fs::path objPath = objectPath;
+        auto index = interface.find(".");
+
+        // interface can be of vlan type or normal ethernet interface.
+        // vlan interface looks like "interface.vlanid",so here by looking
+        // at the interface name we decide that we need
+        // to create the vlaninterface or normal physical interface.
+        if (index != std::string::npos)
+        {
+            // it is vlan interface
+            auto interfaceName = interface.substr(0, index);
+            auto vlanid = interface.substr(index + 1);
+            uint32_t vlanInt = std::stoul(vlanid);
+
+            interfaces[interfaceName]->loadVLAN(vlanInt);
+            continue;
+        }
+        // normal ethernet interface
+        objPath /= interface;
+
+        auto dhcp = getDHCPValue(confDir, interface);
+
+        auto intf = std::make_shared<phosphor::network::EthernetInterface>(
+            bus, objPath.string(), dhcp, *this);
+
+        intf->createIPAddressObjects();
+        intf->createStaticNeighborObjects();
+        intf->loadNameServers();
+
+        this->interfaces.emplace(
+            std::make_pair(std::move(interface), std::move(intf)));
+    }
+}
+
+void Manager::createChildObjects()
+{
+    // creates the ethernet interface dbus object.
+    createInterfaces();
+
+    systemConf.reset(nullptr);
+    dhcpConf.reset(nullptr);
+
+    fs::path objPath = objectPath;
+    objPath /= "config";
+
+    // create the system conf object.
+    systemConf = std::make_unique<phosphor::network::SystemConfiguration>(
+        bus, objPath.string(), *this);
+    // create the dhcp conf object.
+    objPath /= "dhcp";
+    dhcpConf = std::make_unique<phosphor::network::dhcp::Configuration>(
+        bus, objPath.string(), *this);
+}
+
+ObjectPath Manager::vlan(IntfName interfaceName, uint32_t id)
+{
+    return interfaces[interfaceName]->createVLAN(id);
+}
+
+void Manager::reset()
+{
+    if (!createDefaultNetworkFiles(true))
+    {
+        log<level::ERR>("Network Factory Reset failed.");
+        return;
+        // TODO: openbmc/openbmc#1721 - Log ResetFailed error here.
+    }
+
+    log<level::INFO>("Network Factory Reset done.");
+}
+
+// Need to merge the below function with the code which writes the
+// config file during factory reset.
+// TODO openbmc/openbmc#1751
+void Manager::writeToConfigurationFile()
+{
+    // write all the static ip address in the systemd-network conf file
+    for (const auto& intf : interfaces)
+    {
+        intf.second->writeConfigurationFile();
+    }
+    restartTimers();
+}
+
+#ifdef SYNC_MAC_FROM_INVENTORY
+void Manager::setFistBootMACOnInterface(
+    const std::pair<std::string, std::string>& inventoryEthPair)
+{
+    for (const auto& interface : interfaces)
+    {
+        if (interface.first == inventoryEthPair.first)
+        {
+            auto returnMAC =
+                interface.second->macAddress(inventoryEthPair.second);
+            if (returnMAC == inventoryEthPair.second)
+            {
+                log<level::INFO>("Set the MAC on "),
+                    entry("interface : ", interface.first.c_str()),
+                    entry("MAC : ", inventoryEthPair.second.c_str());
+                std::error_code ec;
+                if (std::filesystem::is_directory("/var/lib/network", ec))
+                {
+                    std::ofstream persistentFile(FirstBootFile +
+                                                 interface.first);
+                }
+                break;
+            }
+            else
+            {
+                log<level::INFO>("MAC is Not Set on ethernet Interface");
+            }
+        }
+    }
+}
+
+#endif
+
+void Manager::restartTimers()
+{
+    using namespace std::chrono;
+    if (refreshObjectTimer && restartTimer)
+    {
+        restartTimer->restartOnce(restartTimeout);
+        refreshObjectTimer->restartOnce(refreshTimeout);
+    }
+}
+
+void Manager::restartSystemdUnit(const std::string& unit)
+{
+    try
+    {
+        auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                          SYSTEMD_INTERFACE, "ResetFailedUnit");
+        method.append(unit);
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>("Failed to reset failed unit",
+                        entry("UNIT=%s", unit.c_str()),
+                        entry("ERR=%s", ex.what()));
+        elog<InternalFailure>();
+    }
+
+    try
+    {
+        auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                          SYSTEMD_INTERFACE, "RestartUnit");
+        method.append(unit.c_str(), "replace");
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>("Failed to restart service", entry("ERR=%s", ex.what()),
+                        entry("UNIT=%s", unit.c_str()));
+        elog<InternalFailure>();
+    }
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/network_manager.hpp b/src/network_manager.hpp
new file mode 100644
index 0000000..227955c
--- /dev/null
+++ b/src/network_manager.hpp
@@ -0,0 +1,183 @@
+#pragma once
+
+#include "dhcp_configuration.hpp"
+#include "ethernet_interface.hpp"
+#include "system_configuration.hpp"
+#include "vlan_interface.hpp"
+#include "xyz/openbmc_project/Network/VLAN/Create/server.hpp"
+
+#include <filesystem>
+#include <list>
+#include <memory>
+#include <sdbusplus/bus.hpp>
+#include <string>
+#include <vector>
+#include <xyz/openbmc_project/Common/FactoryReset/server.hpp>
+
+#ifndef SDBUSPP_NEW_CAMELCASE
+#define vlan vLAN
+#endif
+
+namespace phosphor
+{
+namespace network
+{
+
+using SystemConfPtr = std::unique_ptr<SystemConfiguration>;
+using DHCPConfPtr = std::unique_ptr<dhcp::Configuration>;
+
+namespace fs = std::filesystem;
+namespace details
+{
+
+template <typename T, typename U>
+using ServerObject = typename sdbusplus::server::object::object<T, U>;
+
+using VLANCreateIface = details::ServerObject<
+    sdbusplus::xyz::openbmc_project::Network::VLAN::server::Create,
+    sdbusplus::xyz::openbmc_project::Common::server::FactoryReset>;
+
+} // namespace details
+
+/** @class Manager
+ *  @brief OpenBMC network manager implementation.
+ */
+class Manager : public details::VLANCreateIface
+{
+  public:
+    Manager() = delete;
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = delete;
+    Manager& operator=(Manager&&) = delete;
+    virtual ~Manager() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] dir - Network Configuration directory path.
+     */
+    Manager(sdbusplus::bus::bus& bus, const char* objPath,
+            const std::string& dir);
+
+    ObjectPath vlan(IntfName interfaceName, uint32_t id) override;
+
+    /** @brief write the network conf file with the in-memory objects.
+     */
+    void writeToConfigurationFile();
+
+    /** @brief Fetch the interface and the ipaddress details
+     *         from the system and create the ethernet interraces
+     *         dbus object.
+     */
+    virtual void createInterfaces();
+
+    /** @brief create child interface object and the system conf object.
+     */
+    void createChildObjects();
+
+    /** @brief sets the network conf directory.
+     *  @param[in] dirName - Absolute path of the directory.
+     */
+    void setConfDir(const fs::path& dir);
+
+    /** @brief gets the network conf directory.
+     */
+    fs::path getConfDir()
+    {
+        return confDir;
+    }
+
+    /** @brief gets the system conf object.
+     *
+     */
+    const SystemConfPtr& getSystemConf()
+    {
+        return systemConf;
+    }
+
+    /** @brief gets the dhcp conf object.
+     *
+     */
+    const DHCPConfPtr& getDHCPConf()
+    {
+        return dhcpConf;
+    }
+
+    /** @brief create the default network files for each interface
+     *  @detail if force param is true then forcefully create the network
+     *          files otherwise if network file doesn't exist then
+     *          create it.
+     *  @param[in] force - forcefully create the file
+     *  @return true if network file created else false
+     */
+    bool createDefaultNetworkFiles(bool force);
+
+    /** @brief restart the network timers. */
+    void restartTimers();
+
+    /** @brief This function gets the MAC address from the VPD and
+     *  sets it on the corresponding ethernet interface during first
+     *  Boot, once it sets the MAC from VPD, it creates a file named
+     *  firstBoot under /var/lib to make sure we dont run this function
+     *  again.
+     *
+     *  @param[in] ethPair - Its a pair of ethernet interface name & the
+     * corresponding MAC Address from the VPD
+     *
+     *  return - NULL
+     */
+    void setFistBootMACOnInterface(
+        const std::pair<std::string, std::string>& ethPair);
+
+    /** @brief Restart the systemd unit
+     *  @param[in] unit - systemd unit name which needs to be
+     *                    restarted.
+     */
+    virtual void restartSystemdUnit(const std::string& unit);
+
+    /** @brief Returns the number of interfaces under this manager.
+     *
+     * @return the number of interfaces managed by this manager.
+     */
+    int getInterfaceCount()
+    {
+        return interfaces.size();
+    }
+
+    /** @brief Does the requested interface exist under this manager?
+     *
+     * @param[in] intf - the interface name to check.
+     * @return true if found, false otherwise.
+     */
+    bool hasInterface(const std::string& intf)
+    {
+        return (interfaces.find(intf) != interfaces.end());
+    }
+
+  protected:
+    /** @brief Persistent sdbusplus DBus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** @brief Persistent map of EthernetInterface dbus objects and their names
+     */
+    std::map<IntfName, std::shared_ptr<EthernetInterface>> interfaces;
+
+    /** @brief BMC network reset - resets network configuration for BMC. */
+    void reset() override;
+
+    /** @brief Path of Object. */
+    std::string objectPath;
+
+    /** @brief pointer to system conf object. */
+    SystemConfPtr systemConf = nullptr;
+
+    /** @brief pointer to dhcp conf object. */
+    DHCPConfPtr dhcpConf = nullptr;
+
+    /** @brief Network Configuration directory. */
+    fs::path confDir;
+};
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/network_manager_main.cpp b/src/network_manager_main.cpp
new file mode 100644
index 0000000..b0d6d2e
--- /dev/null
+++ b/src/network_manager_main.cpp
@@ -0,0 +1,342 @@
+#include "config.h"
+
+#include "network_manager.hpp"
+#include "rtnetlink_server.hpp"
+#include "types.hpp"
+#include "watch.hpp"
+
+#include <linux/netlink.h>
+
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <memory>
+#ifdef SYNC_MAC_FROM_INVENTORY
+#include <nlohmann/json.hpp>
+#endif
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/server/manager.hpp>
+#include <sdeventplus/event.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+using phosphor::logging::elog;
+using phosphor::logging::entry;
+using phosphor::logging::level;
+using phosphor::logging::log;
+using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using DbusObjectPath = std::string;
+using DbusInterface = std::string;
+using PropertyValue = std::string;
+
+constexpr char NETWORK_CONF_DIR[] = "/etc/systemd/network";
+
+constexpr char DEFAULT_OBJPATH[] = "/xyz/openbmc_project/network";
+
+constexpr auto firstBootPath = "/var/lib/network/firstBoot_";
+constexpr auto configFile = "/usr/share/network/config.json";
+
+constexpr auto invNetworkIntf =
+    "xyz.openbmc_project.Inventory.Item.NetworkInterface";
+
+namespace phosphor
+{
+namespace network
+{
+
+std::unique_ptr<phosphor::network::Manager> manager = nullptr;
+std::unique_ptr<Timer> refreshObjectTimer = nullptr;
+std::unique_ptr<Timer> restartTimer = nullptr;
+
+#ifdef SYNC_MAC_FROM_INVENTORY
+std::unique_ptr<sdbusplus::bus::match::match> EthInterfaceMatch = nullptr;
+std::vector<std::string> first_boot_status;
+
+bool setInventoryMACOnSystem(sdbusplus::bus::bus& bus,
+                             const nlohmann::json& configJson,
+                             const std::string& intfname)
+{
+    try
+    {
+        auto inventoryMAC = mac_address::getfromInventory(bus, intfname);
+        if (!mac_address::toString(inventoryMAC).empty())
+        {
+            log<level::INFO>("Mac Address in Inventory on "),
+                entry("Interface : ", intfname.c_str()),
+                entry("MAC Address :",
+                      (mac_address::toString(inventoryMAC)).c_str());
+            manager->setFistBootMACOnInterface(std::make_pair(
+                intfname.c_str(), mac_address::toString(inventoryMAC)));
+            first_boot_status.push_back(intfname.c_str());
+            bool status = true;
+            for (const auto& keys : configJson.items())
+            {
+                if (!(std::find(first_boot_status.begin(),
+                                first_boot_status.end(),
+                                keys.key()) != first_boot_status.end()))
+                {
+                    log<level::INFO>("Interface MAC is NOT set from VPD"),
+                        entry("INTERFACE", keys.key().c_str());
+                    status = false;
+                }
+            }
+            if (status)
+            {
+                log<level::INFO>("Removing the match for ethernet interfaces");
+                phosphor::network::EthInterfaceMatch = nullptr;
+            }
+        }
+        else
+        {
+            log<level::INFO>("Nothing is present in Inventory");
+            return false;
+        }
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>("Exception occurred during getting of MAC "
+                        "address from Inventory");
+        return false;
+    }
+    return true;
+}
+
+// register the macthes to be monitored from inventory manager
+void registerSignals(sdbusplus::bus::bus& bus, const nlohmann::json& configJson)
+{
+    log<level::INFO>("Registering the Inventory Signals Matcher");
+
+    static std::unique_ptr<sdbusplus::bus::match::match> MacAddressMatch;
+
+    auto callback = [&](sdbusplus::message::message& m) {
+        std::map<DbusObjectPath,
+                 std::map<DbusInterface, std::variant<PropertyValue>>>
+            interfacesProperties;
+
+        sdbusplus::message::object_path objPath;
+        std::pair<std::string, std::string> ethPair;
+        m.read(objPath, interfacesProperties);
+
+        for (const auto& pattern : configJson.items())
+        {
+            if (objPath.str.find(pattern.value()) != std::string::npos)
+            {
+                for (auto& interface : interfacesProperties)
+                {
+                    if (interface.first == invNetworkIntf)
+                    {
+                        for (const auto& property : interface.second)
+                        {
+                            if (property.first == "MACAddress")
+                            {
+                                ethPair = std::make_pair(
+                                    pattern.key(),
+                                    std::get<std::string>(property.second));
+                                break;
+                            }
+                        }
+                        break;
+                    }
+                }
+                if (!(ethPair.first.empty() || ethPair.second.empty()))
+                {
+                    manager->setFistBootMACOnInterface(ethPair);
+                }
+            }
+        }
+    };
+
+    MacAddressMatch = std::make_unique<sdbusplus::bus::match::match>(
+        bus,
+        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+        "member='InterfacesAdded',path='/xyz/openbmc_project/"
+        "inventory'",
+        callback);
+}
+
+void watchEthernetInterface(sdbusplus::bus::bus& bus,
+                            const nlohmann::json& configJson)
+{
+    auto mycallback = [&](sdbusplus::message::message& m) {
+        std::map<DbusObjectPath,
+                 std::map<DbusInterface, std::variant<PropertyValue>>>
+            interfacesProperties;
+
+        sdbusplus::message::object_path objPath;
+        std::pair<std::string, std::string> ethPair;
+        m.read(objPath, interfacesProperties);
+        for (const auto& interfaces : interfacesProperties)
+        {
+            if (interfaces.first ==
+                "xyz.openbmc_project.Network.EthernetInterface")
+            {
+                for (const auto& property : interfaces.second)
+                {
+                    if (property.first == "InterfaceName")
+                    {
+                        std::string infname =
+                            std::get<std::string>(property.second);
+
+                        if (configJson.find(infname) == configJson.end())
+                        {
+                            // ethernet interface not found in configJSON
+                            // check if it is not sit0 interface, as it is
+                            // expected.
+                            if (infname != "sit0")
+                            {
+                                log<level::ERR>(
+                                    "Wrong Interface Name in Config Json");
+                            }
+                        }
+                        else
+                        {
+                            if (!phosphor::network::setInventoryMACOnSystem(
+                                    bus, configJson, infname))
+                            {
+                                phosphor::network::registerSignals(bus,
+                                                                   configJson);
+                                phosphor::network::EthInterfaceMatch = nullptr;
+                            }
+                        }
+                        break;
+                    }
+                }
+                break;
+            }
+        }
+    };
+    // Incase if phosphor-inventory-manager started early and the VPD is already
+    // collected by the time network service has come up, better to check the
+    // VPD directly and set the MAC Address on the respective Interface.
+
+    bool registeredSignals = false;
+    for (const auto& interfaceString : configJson.items())
+    {
+        if (!std::filesystem::exists(firstBootPath + interfaceString.key()) &&
+            !registeredSignals)
+        {
+
+            log<level::INFO>(
+                "First boot file is not present, check VPD for MAC");
+            phosphor::network::EthInterfaceMatch = std::make_unique<
+                sdbusplus::bus::match::match>(
+                bus,
+                "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+                "member='InterfacesAdded',path='/xyz/openbmc_project/network'",
+                mycallback);
+            registeredSignals = true;
+        }
+    }
+}
+
+#endif
+
+/** @brief refresh the network objects. */
+void refreshObjects()
+{
+    if (manager)
+    {
+        log<level::INFO>("Refreshing the objects.");
+        manager->createChildObjects();
+        log<level::INFO>("Refreshing complete.");
+    }
+}
+
+/** @brief restart the systemd networkd. */
+void restartNetwork()
+{
+    if (manager)
+    {
+        manager->restartSystemdUnit("systemd-networkd.service");
+    }
+}
+
+void initializeTimers()
+{
+    auto event = sdeventplus::Event::get_default();
+    refreshObjectTimer =
+        std::make_unique<Timer>(event, std::bind(refreshObjects));
+    restartTimer = std::make_unique<Timer>(event, std::bind(restartNetwork));
+}
+
+} // namespace network
+} // namespace phosphor
+
+void createNetLinkSocket(phosphor::Descriptor& smartSock)
+{
+    // RtnetLink socket
+    auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, NETLINK_ROUTE);
+    if (fd < 0)
+    {
+        log<level::ERR>("Unable to create the net link socket",
+                        entry("ERRNO=%d", errno));
+        elog<InternalFailure>();
+    }
+    smartSock.set(fd);
+}
+
+int main(int /*argc*/, char** /*argv*/)
+{
+    phosphor::network::initializeTimers();
+
+    auto bus = sdbusplus::bus::new_default();
+
+    // Need sd_event to watch for OCC device errors
+    sd_event* event = nullptr;
+    auto r = sd_event_default(&event);
+    if (r < 0)
+    {
+        log<level::ERR>("Error creating a default sd_event handler");
+        return r;
+    }
+
+    phosphor::network::EventPtr eventPtr{event};
+    event = nullptr;
+
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
+
+    // Add sdbusplus Object Manager for the 'root' path of the network manager.
+    sdbusplus::server::manager::manager objManager(bus, DEFAULT_OBJPATH);
+    bus.request_name(DEFAULT_BUSNAME);
+
+    phosphor::network::manager = std::make_unique<phosphor::network::Manager>(
+        bus, DEFAULT_OBJPATH, NETWORK_CONF_DIR);
+
+    // create the default network files if the network file
+    // is not there for any interface.
+    // Parameter false means don't create the network
+    // files forcefully.
+    if (phosphor::network::manager->createDefaultNetworkFiles(false))
+    {
+        // if files created restart the network.
+        // don't need to call the create child objects as eventhandler
+        // will create it.
+        phosphor::network::restartNetwork();
+    }
+    else
+    {
+        // this will add the additional fixes which is needed
+        // in the existing network file.
+        phosphor::network::manager->writeToConfigurationFile();
+        // whenever the configuration file gets written it restart
+        // the network which creates the network objects
+    }
+
+    // RtnetLink socket
+    phosphor::Descriptor smartSock;
+    createNetLinkSocket(smartSock);
+
+    // RTNETLINK event handler
+    phosphor::network::rtnetlink::Server svr(eventPtr, smartSock);
+
+#ifdef SYNC_MAC_FROM_INVENTORY
+    std::ifstream in(configFile);
+    nlohmann::json configJson;
+    in >> configJson;
+    phosphor::network::watchEthernetInterface(bus, configJson);
+#endif
+    sd_event_loop(eventPtr.get());
+}
diff --git a/src/routing_table.cpp b/src/routing_table.cpp
new file mode 100644
index 0000000..68a9ee3
--- /dev/null
+++ b/src/routing_table.cpp
@@ -0,0 +1,232 @@
+#include "routing_table.hpp"
+
+#include "util.hpp"
+
+#include <arpa/inet.h>
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <optional>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <stdexcept>
+#include <string_view>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+namespace route
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+Table::Table()
+{
+    try
+    {
+        getRoutes();
+    }
+    catch (InternalFailure& e)
+    {
+        commit<InternalFailure>();
+    }
+}
+
+int Table::readNetLinkSock(int sockFd, std::array<char, BUFSIZE>& buf)
+{
+    struct nlmsghdr* nlHdr = nullptr;
+    int readLen{};
+    int msgLen{};
+    uint8_t seqNum = 1;
+    uint8_t pID = getpid();
+    char* bufPtr = buf.data();
+
+    do
+    {
+        // Receive response from the kernel
+        if ((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0)
+        {
+            auto error = errno;
+            log<level::ERR>("Socket recv failed:",
+                            entry("ERROR=%s", strerror(error)));
+            elog<InternalFailure>();
+        }
+
+        nlHdr = reinterpret_cast<nlmsghdr*>(bufPtr);
+
+        // Check if the header is valid
+
+        if ((NLMSG_OK(nlHdr, readLen) == 0) ||
+            (nlHdr->nlmsg_type == NLMSG_ERROR))
+        {
+
+            auto error = errno;
+            log<level::ERR>("Error validating header",
+                            entry("NLMSGTYPE=%d", nlHdr->nlmsg_type),
+                            entry("ERROR=%s", strerror(error)));
+            elog<InternalFailure>();
+        }
+
+        // Check if the its the last message
+        if (nlHdr->nlmsg_type == NLMSG_DONE)
+        {
+            break;
+        }
+        else
+        {
+            // Else move the pointer to buffer appropriately
+            bufPtr += readLen;
+            msgLen += readLen;
+        }
+
+        // Check if its a multi part message
+        if ((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0)
+        {
+            break;
+        }
+    } while ((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pID));
+    return msgLen;
+}
+
+void Table::parseRoutes(const nlmsghdr* nlHdr)
+{
+    rtmsg* rtMsg = nullptr;
+    rtattr* rtAttr = nullptr;
+    int rtLen{};
+    std::optional<InAddrAny> dstAddr;
+    std::optional<InAddrAny> gateWayAddr;
+    char ifName[IF_NAMESIZE] = {};
+
+    rtMsg = reinterpret_cast<rtmsg*>(NLMSG_DATA(nlHdr));
+
+    // If the route is not for AF_INET{,6} or does not belong to main routing
+    // table then return.
+    if ((rtMsg->rtm_family != AF_INET && rtMsg->rtm_family != AF_INET6) ||
+        rtMsg->rtm_table != RT_TABLE_MAIN)
+    {
+        return;
+    }
+
+    // get the rtattr field
+    rtAttr = reinterpret_cast<rtattr*>(RTM_RTA(rtMsg));
+
+    rtLen = RTM_PAYLOAD(nlHdr);
+
+    for (; RTA_OK(rtAttr, rtLen); rtAttr = RTA_NEXT(rtAttr, rtLen))
+    {
+        std::string_view attrData(reinterpret_cast<char*>(RTA_DATA(rtAttr)),
+                                  RTA_PAYLOAD(rtAttr));
+        switch (rtAttr->rta_type)
+        {
+            case RTA_OIF:
+                if_indextoname(*reinterpret_cast<int*>(RTA_DATA(rtAttr)),
+                               ifName);
+                break;
+            case RTA_GATEWAY:
+                gateWayAddr = addrFromBuf(rtMsg->rtm_family, attrData);
+                break;
+            case RTA_DST:
+                dstAddr = addrFromBuf(rtMsg->rtm_family, attrData);
+                break;
+        }
+    }
+
+    std::string dstStr;
+    if (dstAddr)
+    {
+        dstStr = toString(*dstAddr);
+    }
+    std::string gatewayStr;
+    if (gateWayAddr)
+    {
+        gatewayStr = toString(*gateWayAddr);
+    }
+    if (!dstAddr && gateWayAddr)
+    {
+        std::string ifNameStr(ifName);
+        if (rtMsg->rtm_family == AF_INET)
+        {
+            defaultGateway[ifNameStr] = gatewayStr;
+        }
+        else if (rtMsg->rtm_family == AF_INET6)
+        {
+            defaultGateway6[ifNameStr] = gatewayStr;
+        }
+    }
+    Entry route(dstStr, gatewayStr, ifName);
+    // if there is already existing route for this network
+    // then ignore the next one as it would not be used by the
+    // routing policy
+    // So don't update the route entry for the network for which
+    // there is already a route exist.
+    if (routeList.find(dstStr) == routeList.end())
+    {
+        routeList.emplace(std::make_pair(dstStr, std::move(route)));
+    }
+}
+
+Map Table::getRoutes()
+{
+    nlmsghdr* nlMsg = nullptr;
+    std::array<char, BUFSIZE> msgBuf = {0};
+
+    int sock = -1;
+    int len{0};
+
+    uint8_t msgSeq{0};
+
+    // Create Socket
+    if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during socket creation",
+                        entry("ERRNO=%s", strerror(error)));
+        elog<InternalFailure>();
+    }
+
+    phosphor::Descriptor smartSock(sock);
+    sock = -1;
+
+    // point the header and the msg structure pointers into the buffer.
+    nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data());
+    // Length of message
+    nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg));
+    // Get the routes from kernel routing table
+    nlMsg->nlmsg_type = RTM_GETROUTE;
+    // The message is a request for dump
+    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
+
+    nlMsg->nlmsg_seq = msgSeq;
+    nlMsg->nlmsg_pid = getpid();
+
+    // Send the request
+    if (send(smartSock(), nlMsg, nlMsg->nlmsg_len, 0) < 0)
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during send on netlink socket",
+                        entry("ERRNO=%s", strerror(error)));
+        elog<InternalFailure>();
+    }
+
+    // Read the response
+    len = readNetLinkSock(smartSock(), msgBuf);
+
+    // Parse and print the response
+    for (; NLMSG_OK(nlMsg, len); nlMsg = NLMSG_NEXT(nlMsg, len))
+    {
+        parseRoutes(nlMsg);
+    }
+    return routeList;
+}
+
+} // namespace route
+} // namespace network
+} // namespace phosphor
diff --git a/src/routing_table.hpp b/src/routing_table.hpp
new file mode 100644
index 0000000..8b634c6
--- /dev/null
+++ b/src/routing_table.hpp
@@ -0,0 +1,105 @@
+#pragma once
+
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <sys/socket.h>
+
+#include <iostream>
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace phosphor
+{
+namespace network
+{
+namespace route
+{
+constexpr auto BUFSIZE = 4096;
+
+struct Entry
+{
+    // destination network
+    std::string destination;
+    // gateway for this network.
+    std::string gateway;
+    // interface for this route
+    std::string interface;
+    Entry(const std::string& dest, const std::string& gtw,
+          const std::string& intf) :
+        destination(dest),
+        gateway(gtw), interface(intf)
+    {
+    }
+
+    bool operator==(const Entry& rhs)
+    {
+        return this->destination == rhs.destination &&
+               this->gateway == rhs.gateway && this->interface == rhs.interface;
+    }
+};
+
+// Map of network address and the route entry
+using Map = std::map<std::string, struct Entry>;
+
+class Table
+{
+  public:
+    Table();
+    ~Table() = default;
+    Table(const Table&) = default;
+    Table& operator=(const Table&) = default;
+    Table(Table&&) = default;
+    Table& operator=(Table&&) = default;
+
+    /**
+     * @brief gets the list of routes.
+     *
+     * @returns list of routes.
+     */
+    Map getRoutes();
+
+    /**
+     * @brief gets the default v4 gateway.
+     *
+     * @returns the default v4 gateway list.
+     */
+    std::map<std::string, std::string> getDefaultGateway() const
+    {
+        return defaultGateway;
+    };
+
+    /**
+     * @brief gets the default v6 gateway.
+     *
+     * @returns the default v6 gateway list.
+     */
+    std::map<std::string, std::string> getDefaultGateway6() const
+    {
+        return defaultGateway6;
+    };
+
+  private:
+    /**
+     * @brief read the routing data from the socket and fill the buffer.
+     *
+     * @param[in] bufPtr - unique pointer to confidentiality algorithm
+     *                     instance
+     */
+    int readNetLinkSock(int sockFd, std::array<char, BUFSIZE>& buff);
+    /**
+     * @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::map<std::string, std::string> defaultGateway;  // default gateway list
+    std::map<std::string, std::string> defaultGateway6; // default gateway list
+    Map routeList;                                      // List of routes
+};
+
+} // namespace route
+} // namespace network
+} // namespace phosphor
diff --git a/src/rtnetlink_server.cpp b/src/rtnetlink_server.cpp
new file mode 100644
index 0000000..07ca08c
--- /dev/null
+++ b/src/rtnetlink_server.cpp
@@ -0,0 +1,171 @@
+#include "rtnetlink_server.hpp"
+
+#include "types.hpp"
+#include "util.hpp"
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <systemd/sd-daemon.h>
+#include <unistd.h>
+
+#include <memory>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <string_view>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+extern std::unique_ptr<Timer> refreshObjectTimer;
+
+namespace rtnetlink
+{
+
+static bool shouldRefresh(const struct nlmsghdr& hdr, std::string_view data)
+{
+    switch (hdr.nlmsg_type)
+    {
+        case RTM_NEWADDR:
+        case RTM_DELADDR:
+        case RTM_NEWROUTE:
+        case RTM_DELROUTE:
+        {
+            return true;
+        }
+        case RTM_NEWNEIGH:
+        case RTM_DELNEIGH:
+        {
+            struct ndmsg ndm;
+            if (data.size() < sizeof(ndm))
+            {
+                return false;
+            }
+            memcpy(&ndm, data.data(), sizeof(ndm));
+            // We only want to refresh for static neighbors
+            return ndm.ndm_state & NUD_PERMANENT;
+        }
+    }
+
+    return false;
+}
+
+/* Call Back for the sd event loop */
+static int eventHandler(sd_event_source* /*es*/, int fd, uint32_t /*revents*/,
+                        void* /*userdata*/)
+{
+    char buffer[phosphor::network::rtnetlink::BUFSIZE]{};
+    int len{};
+
+    auto netLinkHeader = reinterpret_cast<struct nlmsghdr*>(buffer);
+    while ((len = recv(fd, netLinkHeader, phosphor::network::rtnetlink::BUFSIZE,
+                       0)) > 0)
+    {
+        for (; (NLMSG_OK(netLinkHeader, len)) &&
+               (netLinkHeader->nlmsg_type != NLMSG_DONE);
+             netLinkHeader = NLMSG_NEXT(netLinkHeader, len))
+        {
+            std::string_view data(
+                reinterpret_cast<const char*>(NLMSG_DATA(netLinkHeader)),
+                netLinkHeader->nlmsg_len - NLMSG_HDRLEN);
+            if (shouldRefresh(*netLinkHeader, data))
+            {
+                // starting the timer here to make sure that we don't want
+                // create the child objects multiple times.
+                if (!refreshObjectTimer->isEnabled())
+                {
+                    // if start timer throws exception then let the application
+                    // crash
+                    refreshObjectTimer->restartOnce(refreshTimeout);
+                } // end if
+            }     // end if
+
+        } // end for
+
+    } // end while
+
+    return 0;
+}
+
+Server::Server(EventPtr& eventPtr, const phosphor::Descriptor& smartSock)
+{
+    using namespace phosphor::logging;
+    using InternalFailure =
+        sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+    struct sockaddr_nl addr
+    {
+    };
+    int r{};
+
+    sigset_t ss{};
+    // check that the given socket is valid or not.
+    if (smartSock() < 0)
+    {
+        r = -EBADF;
+        goto finish;
+    }
+
+    if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 ||
+        sigaddset(&ss, SIGINT) < 0)
+    {
+        r = -errno;
+        goto finish;
+    }
+    /* Block SIGTERM first, so that the event loop can handle it */
+    if (sigprocmask(SIG_BLOCK, &ss, NULL) < 0)
+    {
+        r = -errno;
+        goto finish;
+    }
+
+    /* Let's make use of the default handler and "floating"
+       reference features of sd_event_add_signal() */
+
+    r = sd_event_add_signal(eventPtr.get(), NULL, SIGTERM, NULL, NULL);
+    if (r < 0)
+    {
+        goto finish;
+    }
+
+    r = sd_event_add_signal(eventPtr.get(), NULL, SIGINT, NULL, NULL);
+    if (r < 0)
+    {
+        goto finish;
+    }
+
+    std::memset(&addr, 0, sizeof(addr));
+    addr.nl_family = AF_NETLINK;
+    addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR |
+                     RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_NEIGH;
+
+    if (bind(smartSock(), (struct sockaddr*)&addr, sizeof(addr)) < 0)
+    {
+        r = -errno;
+        goto finish;
+    }
+
+    r = sd_event_add_io(eventPtr.get(), nullptr, smartSock(), EPOLLIN,
+                        eventHandler, nullptr);
+    if (r < 0)
+    {
+        goto finish;
+    }
+
+finish:
+
+    if (r < 0)
+    {
+        log<level::ERR>("Failure Occurred in starting of server:",
+                        entry("ERRNO=%d", errno));
+        elog<InternalFailure>();
+    }
+}
+
+} // namespace rtnetlink
+} // namespace network
+} // namespace phosphor
diff --git a/src/rtnetlink_server.hpp b/src/rtnetlink_server.hpp
new file mode 100644
index 0000000..e62f51c
--- /dev/null
+++ b/src/rtnetlink_server.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "types.hpp"
+#include "util.hpp"
+
+#include <systemd/sd-event.h>
+
+namespace phosphor
+{
+namespace network
+{
+namespace rtnetlink
+{
+
+constexpr auto BUFSIZE = 4096;
+
+/** General rtnetlink server which waits for the POLLIN event
+    and calls the  call back once it gets the event.
+    Usage would be create the server with the  call back
+    and call the run method.
+ */
+
+class Server
+{
+
+  public:
+    /** @brief Constructor
+     *
+     *  @details Sets up the server to handle incoming RTNETLINK events
+     *
+     *  @param[in] eventPtr - Unique ptr reference to sd_event.
+     *  @param[in] socket - netlink socket.
+     */
+    Server(EventPtr& eventPtr, const phosphor::Descriptor& socket);
+
+    Server() = delete;
+    ~Server() = default;
+    Server(const Server&) = delete;
+    Server& operator=(const Server&) = delete;
+    Server(Server&&) = default;
+    Server& operator=(Server&&) = default;
+};
+
+} // namespace rtnetlink
+} // namespace network
+} // namespace phosphor
diff --git a/src/system_configuration.cpp b/src/system_configuration.cpp
new file mode 100644
index 0000000..4fbf601
--- /dev/null
+++ b/src/system_configuration.cpp
@@ -0,0 +1,151 @@
+#include "config.h"
+
+#include "system_configuration.hpp"
+
+#include "network_manager.hpp"
+#include "routing_table.hpp"
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+// systemd service to kick start a target.
+constexpr auto HOSTNAMED_SERVICE = "org.freedesktop.hostname1";
+constexpr auto HOSTNAMED_SERVICE_PATH = "/org/freedesktop/hostname1";
+constexpr auto HOSTNAMED_INTERFACE = "org.freedesktop.hostname1";
+constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
+constexpr auto METHOD_GET = "Get";
+constexpr auto METHOD_SET = "SetStaticHostname";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using InvalidArgumentMetadata = xyz::openbmc_project::Common::InvalidArgument;
+
+using SystemConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+
+SystemConfiguration::SystemConfiguration(sdbusplus::bus::bus& bus,
+                                         const std::string& objPath,
+                                         Manager& parent) :
+    Iface(bus, objPath.c_str(), true),
+    bus(bus), manager(parent)
+{
+    auto name = getHostNameFromSystem();
+    route::Table routingTable;
+
+    SystemConfigIntf::hostName(name);
+    auto gatewayList = routingTable.getDefaultGateway();
+    auto gateway6List = routingTable.getDefaultGateway6();
+    // Assign first entry of gateway list
+    std::string gateway;
+    std::string gateway6;
+    if (!gatewayList.empty())
+    {
+        gateway = gatewayList.begin()->second;
+    }
+    if (!gateway6List.empty())
+    {
+        gateway6 = gateway6List.begin()->second;
+    }
+
+    SystemConfigIntf::defaultGateway(gateway);
+    SystemConfigIntf::defaultGateway6(gateway6);
+
+    this->emit_object_added();
+}
+
+std::string SystemConfiguration::hostName(std::string name)
+{
+    if (SystemConfigIntf::hostName() == name)
+    {
+        return name;
+    }
+    auto method = bus.new_method_call(HOSTNAMED_SERVICE, HOSTNAMED_SERVICE_PATH,
+                                      HOSTNAMED_INTERFACE, METHOD_SET);
+
+    method.append(name, true);
+
+    if (!bus.call(method))
+    {
+        log<level::ERR>("Failed to set the hostname");
+        report<InternalFailure>();
+        return SystemConfigIntf::hostName();
+    }
+
+    return SystemConfigIntf::hostName(name);
+}
+
+std::string SystemConfiguration::getHostNameFromSystem() const
+{
+    try
+    {
+        std::variant<std::string> name;
+        auto method =
+            bus.new_method_call(HOSTNAMED_SERVICE, HOSTNAMED_SERVICE_PATH,
+                                PROPERTY_INTERFACE, METHOD_GET);
+
+        method.append(HOSTNAMED_INTERFACE, "Hostname");
+
+        auto reply = bus.call(method);
+
+        reply.read(name);
+        return std::get<std::string>(name);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>(
+            "Failed to get the hostname from systemd-hostnamed service",
+            entry("ERR=%s", ex.what()));
+    }
+    return "";
+}
+
+std::string SystemConfiguration::defaultGateway(std::string gateway)
+{
+    auto gw = SystemConfigIntf::defaultGateway();
+    if (gw == gateway)
+    {
+        return gw;
+    }
+
+    if (!isValidIP(AF_INET, gateway))
+    {
+        log<level::ERR>("Not a valid v4 Gateway",
+                        entry("GATEWAY=%s", gateway.c_str()));
+        elog<InvalidArgument>(
+            InvalidArgumentMetadata::ARGUMENT_NAME("GATEWAY"),
+            InvalidArgumentMetadata::ARGUMENT_VALUE(gateway.c_str()));
+    }
+    gw = SystemConfigIntf::defaultGateway(gateway);
+    manager.writeToConfigurationFile();
+    return gw;
+}
+
+std::string SystemConfiguration::defaultGateway6(std::string gateway)
+{
+    auto gw = SystemConfigIntf::defaultGateway6();
+    if (gw == gateway)
+    {
+        return gw;
+    }
+
+    if (!isValidIP(AF_INET6, gateway))
+    {
+        log<level::ERR>("Not a valid v6 Gateway",
+                        entry("GATEWAY=%s", gateway.c_str()));
+        elog<InvalidArgument>(
+            InvalidArgumentMetadata::ARGUMENT_NAME("GATEWAY"),
+            InvalidArgumentMetadata::ARGUMENT_VALUE(gateway.c_str()));
+    }
+    gw = SystemConfigIntf::defaultGateway6(gateway);
+    manager.writeToConfigurationFile();
+    return gw;
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/system_configuration.hpp b/src/system_configuration.hpp
new file mode 100644
index 0000000..a29309c
--- /dev/null
+++ b/src/system_configuration.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <xyz/openbmc_project/Network/SystemConfiguration/server.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using SystemConfigIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+
+using Iface = sdbusplus::server::object::object<SystemConfigIntf>;
+
+class Manager; // forward declaration of network manager.
+
+/** @class SystemConfiguration
+ *  @brief Network system configuration.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Network.SystemConfiguration DBus API.
+ */
+class SystemConfiguration : public Iface
+{
+  public:
+    SystemConfiguration() = default;
+    SystemConfiguration(const SystemConfiguration&) = delete;
+    SystemConfiguration& operator=(const SystemConfiguration&) = delete;
+    SystemConfiguration(SystemConfiguration&&) = delete;
+    SystemConfiguration& operator=(SystemConfiguration&&) = delete;
+    virtual ~SystemConfiguration() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] parent - Parent object.
+     */
+    SystemConfiguration(sdbusplus::bus::bus& bus, const std::string& objPath,
+                        Manager& parent);
+
+    /** @brief set the hostname of the system.
+     *  @param[in] name - host name of the system.
+     */
+    std::string hostName(std::string name) override;
+
+    /** @brief set the default v4 gateway of the system.
+     *  @param[in] gateway - default v4 gateway of the system.
+     */
+    std::string defaultGateway(std::string gateway) override;
+
+    using SystemConfigIntf::defaultGateway;
+
+    /** @brief set the default v6 gateway of the system.
+     *  @param[in] gateway - default v6 gateway of the system.
+     */
+    std::string defaultGateway6(std::string gateway) override;
+
+    using SystemConfigIntf::defaultGateway6;
+
+  private:
+    /** @brief get the hostname from the system by doing
+     *         dbus call to hostnamed service.
+     */
+    std::string getHostNameFromSystem() const;
+
+    /** @brief Persistent sdbusplus DBus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** @brief Network Manager object. */
+    Manager& manager;
+};
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/types.hpp b/src/types.hpp
new file mode 100644
index 0000000..082d588
--- /dev/null
+++ b/src/types.hpp
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "ipaddress.hpp"
+
+#include <ifaddrs.h>
+#include <netinet/in.h>
+#include <systemd/sd-event.h>
+
+#include <array>
+#include <chrono>
+#include <cstddef>
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <sdeventplus/clock.hpp>
+#include <sdeventplus/utility/timer.hpp>
+#include <set>
+#include <string>
+#include <variant>
+#include <vector>
+
+namespace phosphor
+{
+namespace network
+{
+
+using namespace std::chrono_literals;
+
+// wait for three seconds before restarting the networkd
+constexpr auto restartTimeout = 3s;
+
+// refresh the objets after five seconds as network
+// configuration takes 3-4 sec after systemd-networkd restart.
+constexpr auto refreshTimeout = restartTimeout + 7s;
+
+namespace systemd
+{
+namespace config
+{
+
+constexpr auto networkFilePrefix = "00-bmc-";
+constexpr auto networkFileSuffix = ".network";
+constexpr auto deviceFileSuffix = ".netdev";
+
+} // namespace config
+} // namespace systemd
+
+using IntfName = std::string;
+
+struct AddrInfo
+{
+    uint8_t addrType;
+    std::string ipaddress;
+    uint16_t prefix;
+};
+
+using Addr_t = ifaddrs*;
+
+struct AddrDeleter
+{
+    void operator()(Addr_t ptr) const
+    {
+        freeifaddrs(ptr);
+    }
+};
+
+using AddrPtr = std::unique_ptr<ifaddrs, AddrDeleter>;
+
+/* Need a custom deleter for freeing up sd_event */
+struct EventDeleter
+{
+    void operator()(sd_event* event) const
+    {
+        sd_event_unref(event);
+    }
+};
+using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
+
+template <typename T>
+using UniquePtr = std::unique_ptr<T, std::function<void(T*)>>;
+
+// Byte representations for common address types in network byte order
+using InAddrAny = std::variant<struct in_addr, struct in6_addr>;
+
+using AddrList = std::list<AddrInfo>;
+using IntfAddrMap = std::map<IntfName, AddrList>;
+using InterfaceList = std::set<IntfName>;
+
+using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644
index 0000000..5c5e427
--- /dev/null
+++ b/src/util.cpp
@@ -0,0 +1,673 @@
+#include "util.hpp"
+
+#include "config_parser.hpp"
+#include "types.hpp"
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <net/if.h>
+#include <sys/wait.h>
+
+#include <algorithm>
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+#include <filesystem>
+#include <fstream>
+#include <list>
+#ifdef SYNC_MAC_FROM_INVENTORY
+#include <nlohmann/json.hpp>
+#endif
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <stdexcept>
+#include <stdplus/raw.hpp>
+#include <string>
+#include <variant>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+namespace fs = std::filesystem;
+
+namespace internal
+{
+
+void executeCommandinChildProcess(const char* path, char** args)
+{
+    using namespace std::string_literals;
+    pid_t pid = fork();
+    int status{};
+
+    if (pid == 0)
+    {
+        execv(path, args);
+        auto error = errno;
+        // create the command from var args.
+        std::string command = path + " "s;
+
+        for (int i = 0; args[i]; i++)
+        {
+            command += args[i] + " "s;
+        }
+
+        log<level::ERR>("Couldn't exceute the command",
+                        entry("ERRNO=%d", error),
+                        entry("CMD=%s", command.c_str()));
+        elog<InternalFailure>();
+    }
+    else if (pid < 0)
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", error));
+        elog<InternalFailure>();
+    }
+    else if (pid > 0)
+    {
+        while (waitpid(pid, &status, 0) == -1)
+        {
+            if (errno != EINTR)
+            { // Error other than EINTR
+                status = -1;
+                break;
+            }
+        }
+
+        if (status < 0)
+        {
+            std::string command = path + " "s;
+            for (int i = 0; args[i]; i++)
+            {
+                command += args[i] + " "s;
+            }
+
+            log<level::ERR>("Unable to execute the command",
+                            entry("CMD=%s", command.c_str()),
+                            entry("STATUS=%d", status));
+            elog<InternalFailure>();
+        }
+    }
+}
+
+/** @brief Get ignored interfaces from environment */
+std::string_view getIgnoredInterfacesEnv()
+{
+    auto r = std::getenv("IGNORED_INTERFACES");
+    if (r == nullptr)
+    {
+        return "";
+    }
+    return r;
+}
+
+/** @brief Parse the comma separated interface names */
+std::set<std::string_view> parseInterfaces(std::string_view interfaces)
+{
+    std::set<std::string_view> result;
+    while (true)
+    {
+        auto sep = interfaces.find(',');
+        auto interface = interfaces.substr(0, sep);
+        while (!interface.empty() && std::isspace(interface.front()))
+        {
+            interface.remove_prefix(1);
+        }
+        while (!interface.empty() && std::isspace(interface.back()))
+        {
+            interface.remove_suffix(1);
+        }
+        if (!interface.empty())
+        {
+            result.insert(interface);
+        }
+        if (sep == interfaces.npos)
+        {
+            break;
+        }
+        interfaces = interfaces.substr(sep + 1);
+    }
+    return result;
+}
+
+/** @brief Get the ignored interfaces */
+const std::set<std::string_view>& getIgnoredInterfaces()
+{
+    static auto ignoredInterfaces = parseInterfaces(getIgnoredInterfacesEnv());
+    return ignoredInterfaces;
+}
+
+} // namespace internal
+
+uint8_t toCidr(int addressFamily, const std::string& subnetMask)
+{
+    uint32_t subnet[sizeof(in6_addr) / sizeof(uint32_t)];
+    if (inet_pton(addressFamily, subnetMask.c_str(), &subnet) != 1)
+    {
+        log<level::ERR>("inet_pton failed:",
+                        entry("SUBNETMASK=%s", subnetMask.c_str()));
+        return 0;
+    }
+
+    static_assert(sizeof(in6_addr) % sizeof(uint32_t) == 0);
+    static_assert(sizeof(in_addr) % sizeof(uint32_t) == 0);
+    auto i = (addressFamily == AF_INET ? sizeof(in_addr) : sizeof(in6_addr)) /
+             sizeof(uint32_t);
+    while (i > 0)
+    {
+        if (subnet[--i] != 0)
+        {
+            auto v = be32toh(subnet[i]);
+            static_assert(sizeof(unsigned) == sizeof(uint32_t));
+            auto trailing = __builtin_ctz(v);
+            auto ret = (i + 1) * 32 - trailing;
+            bool valid = ~v == 0 || 32 == trailing + __builtin_clz(~v);
+            while (i > 0 && (valid = (~subnet[--i] == 0) && valid))
+                ;
+            if (!valid)
+            {
+                log<level::ERR>("Invalid netmask",
+                                entry("SUBNETMASK=%s", subnetMask.c_str()));
+                return 0;
+            }
+            return ret;
+        }
+    }
+    return 0;
+}
+
+std::string toMask(int addressFamily, uint8_t prefix)
+{
+    if (addressFamily == AF_INET6)
+    {
+        // TODO:- conversion for v6
+        return "";
+    }
+
+    if (prefix < 1 || prefix > 30)
+    {
+        log<level::ERR>("Invalid Prefix", entry("PREFIX=%d", prefix));
+        return "";
+    }
+    /* Create the netmask from the number of bits */
+    unsigned long mask = 0;
+    for (auto i = 0; i < prefix; i++)
+    {
+        mask |= 1 << (31 - i);
+    }
+    struct in_addr netmask;
+    netmask.s_addr = htonl(mask);
+    return inet_ntoa(netmask);
+}
+
+InAddrAny addrFromBuf(int addressFamily, std::string_view buf)
+{
+    if (addressFamily == AF_INET)
+    {
+        struct in_addr ret;
+        if (buf.size() != sizeof(ret))
+        {
+            throw std::runtime_error("Buf not in_addr sized");
+        }
+        memcpy(&ret, buf.data(), sizeof(ret));
+        return ret;
+    }
+    else if (addressFamily == AF_INET6)
+    {
+        struct in6_addr ret;
+        if (buf.size() != sizeof(ret))
+        {
+            throw std::runtime_error("Buf not in6_addr sized");
+        }
+        memcpy(&ret, buf.data(), sizeof(ret));
+        return ret;
+    }
+
+    throw std::runtime_error("Unsupported address family");
+}
+
+std::string toString(const struct in_addr& addr)
+{
+    std::string ip(INET_ADDRSTRLEN, '\0');
+    if (inet_ntop(AF_INET, &addr, ip.data(), ip.size()) == nullptr)
+    {
+        throw std::runtime_error("Failed to convert IP4 to string");
+    }
+
+    ip.resize(strlen(ip.c_str()));
+    return ip;
+}
+
+std::string toString(const struct in6_addr& addr)
+{
+    std::string ip(INET6_ADDRSTRLEN, '\0');
+    if (inet_ntop(AF_INET6, &addr, ip.data(), ip.size()) == nullptr)
+    {
+        throw std::runtime_error("Failed to convert IP6 to string");
+    }
+
+    ip.resize(strlen(ip.c_str()));
+    return ip;
+}
+
+std::string toString(const InAddrAny& addr)
+{
+    if (std::holds_alternative<struct in_addr>(addr))
+    {
+        const auto& v = std::get<struct in_addr>(addr);
+        return toString(v);
+    }
+    else if (std::holds_alternative<struct in6_addr>(addr))
+    {
+        const auto& v = std::get<struct in6_addr>(addr);
+        return toString(v);
+    }
+
+    throw std::runtime_error("Invalid addr type");
+}
+
+bool isLinkLocalIP(const std::string& address)
+{
+    return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
+}
+
+bool isValidIP(int addressFamily, const std::string& address)
+{
+    unsigned char buf[sizeof(struct in6_addr)];
+
+    return inet_pton(addressFamily, address.c_str(), buf) > 0;
+}
+
+bool isValidPrefix(int addressFamily, uint8_t prefixLength)
+{
+    if (addressFamily == AF_INET)
+    {
+        if (prefixLength < IPV4_MIN_PREFIX_LENGTH ||
+            prefixLength > IPV4_MAX_PREFIX_LENGTH)
+        {
+            return false;
+        }
+    }
+
+    if (addressFamily == AF_INET6)
+    {
+        if (prefixLength < IPV4_MIN_PREFIX_LENGTH ||
+            prefixLength > IPV6_MAX_PREFIX_LENGTH)
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+IntfAddrMap getInterfaceAddrs()
+{
+    IntfAddrMap intfMap{};
+    struct ifaddrs* ifaddr = nullptr;
+
+    // attempt to fill struct with ifaddrs
+    if (getifaddrs(&ifaddr) == -1)
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during the getifaddrs call",
+                        entry("ERRNO=%s", strerror(error)));
+        elog<InternalFailure>();
+    }
+
+    AddrPtr ifaddrPtr(ifaddr);
+    ifaddr = nullptr;
+
+    std::string intfName{};
+
+    for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
+    {
+        // walk interfaces
+        if (ifa->ifa_addr == nullptr)
+        {
+            continue;
+        }
+
+        // get only INET interfaces not ipv6
+        if (ifa->ifa_addr->sa_family == AF_INET ||
+            ifa->ifa_addr->sa_family == AF_INET6)
+        {
+            // if loopback, or not running ignore
+            if ((ifa->ifa_flags & IFF_LOOPBACK) ||
+                !(ifa->ifa_flags & IFF_RUNNING))
+            {
+                continue;
+            }
+            intfName = ifa->ifa_name;
+            AddrInfo info{};
+            char ip[INET6_ADDRSTRLEN] = {0};
+            char subnetMask[INET6_ADDRSTRLEN] = {0};
+
+            if (ifa->ifa_addr->sa_family == AF_INET)
+            {
+
+                inet_ntop(ifa->ifa_addr->sa_family,
+                          &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr),
+                          ip, sizeof(ip));
+
+                inet_ntop(
+                    ifa->ifa_addr->sa_family,
+                    &(((struct sockaddr_in*)(ifa->ifa_netmask))->sin_addr),
+                    subnetMask, sizeof(subnetMask));
+            }
+            else
+            {
+                inet_ntop(ifa->ifa_addr->sa_family,
+                          &(((struct sockaddr_in6*)(ifa->ifa_addr))->sin6_addr),
+                          ip, sizeof(ip));
+
+                inet_ntop(
+                    ifa->ifa_addr->sa_family,
+                    &(((struct sockaddr_in6*)(ifa->ifa_netmask))->sin6_addr),
+                    subnetMask, sizeof(subnetMask));
+            }
+
+            info.addrType = ifa->ifa_addr->sa_family;
+            info.ipaddress = ip;
+            info.prefix = toCidr(info.addrType, std::string(subnetMask));
+            intfMap[intfName].push_back(info);
+        }
+    }
+    return intfMap;
+}
+
+InterfaceList getInterfaces()
+{
+    InterfaceList interfaces{};
+    struct ifaddrs* ifaddr = nullptr;
+
+    // attempt to fill struct with ifaddrs
+    if (getifaddrs(&ifaddr) == -1)
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during the getifaddrs call",
+                        entry("ERRNO=%d", error));
+        elog<InternalFailure>();
+    }
+
+    AddrPtr ifaddrPtr(ifaddr);
+    ifaddr = nullptr;
+    const auto& ignoredInterfaces = internal::getIgnoredInterfaces();
+
+    for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
+    {
+        // walk interfaces
+        // if loopback ignore
+        if (ifa->ifa_flags & IFF_LOOPBACK ||
+            ignoredInterfaces.find(ifa->ifa_name) != ignoredInterfaces.end())
+        {
+            continue;
+        }
+        interfaces.emplace(ifa->ifa_name);
+    }
+    return interfaces;
+}
+
+void deleteInterface(const std::string& intf)
+{
+    pid_t pid = fork();
+    int status{};
+
+    if (pid == 0)
+    {
+
+        execl("/sbin/ip", "ip", "link", "delete", "dev", intf.c_str(), nullptr);
+        auto error = errno;
+        log<level::ERR>("Couldn't delete the device", entry("ERRNO=%d", error),
+                        entry("INTF=%s", intf.c_str()));
+        elog<InternalFailure>();
+    }
+    else if (pid < 0)
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", error));
+        elog<InternalFailure>();
+    }
+    else if (pid > 0)
+    {
+        while (waitpid(pid, &status, 0) == -1)
+        {
+            if (errno != EINTR)
+            { /* Error other than EINTR */
+                status = -1;
+                break;
+            }
+        }
+
+        if (status < 0)
+        {
+            log<level::ERR>("Unable to delete the interface",
+                            entry("INTF=%s", intf.c_str()),
+                            entry("STATUS=%d", status));
+            elog<InternalFailure>();
+        }
+    }
+}
+
+std::optional<std::string> interfaceToUbootEthAddr(const char* intf)
+{
+    constexpr char ethPrefix[] = "eth";
+    constexpr size_t ethPrefixLen = sizeof(ethPrefix) - 1;
+    if (strncmp(ethPrefix, intf, ethPrefixLen) != 0)
+    {
+        return std::nullopt;
+    }
+    const auto intfSuffix = intf + ethPrefixLen;
+    if (intfSuffix[0] == '\0')
+    {
+        return std::nullopt;
+    }
+    char* end;
+    unsigned long idx = strtoul(intfSuffix, &end, 10);
+    if (end[0] != '\0')
+    {
+        return std::nullopt;
+    }
+    if (idx == 0)
+    {
+        return "ethaddr";
+    }
+    return "eth" + std::to_string(idx) + "addr";
+}
+
+EthernetInterfaceIntf::DHCPConf getDHCPValue(const std::string& confDir,
+                                             const std::string& intf)
+{
+    EthernetInterfaceIntf::DHCPConf dhcp =
+        EthernetInterfaceIntf::DHCPConf::none;
+    // Get the interface mode value from systemd conf
+    // using namespace std::string_literals;
+    fs::path confPath = confDir;
+    std::string fileName = systemd::config::networkFilePrefix + intf +
+                           systemd::config::networkFileSuffix;
+    confPath /= fileName;
+
+    auto rc = config::ReturnCode::SUCCESS;
+    config::ValueList values;
+    config::Parser parser(confPath.string());
+
+    std::tie(rc, values) = parser.getValues("Network", "DHCP");
+    if (rc != config::ReturnCode::SUCCESS)
+    {
+        log<level::DEBUG>("Unable to get the value for Network[DHCP]",
+                          entry("RC=%d", rc));
+        return dhcp;
+    }
+    // There will be only single value for DHCP key.
+    if (values[0] == "true")
+    {
+        dhcp = EthernetInterfaceIntf::DHCPConf::both;
+    }
+    else if (values[0] == "ipv4")
+    {
+        dhcp = EthernetInterfaceIntf::DHCPConf::v4;
+    }
+    else if (values[0] == "ipv6")
+    {
+        dhcp = EthernetInterfaceIntf::DHCPConf::v6;
+    }
+    return dhcp;
+}
+
+namespace mac_address
+{
+
+constexpr auto mapperBus = "xyz.openbmc_project.ObjectMapper";
+constexpr auto mapperObj = "/xyz/openbmc_project/object_mapper";
+constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
+constexpr auto propIntf = "org.freedesktop.DBus.Properties";
+constexpr auto methodGet = "Get";
+constexpr auto configFile = "/usr/share/network/config.json";
+
+using DbusObjectPath = std::string;
+using DbusService = std::string;
+using DbusInterface = std::string;
+using ObjectTree =
+    std::map<DbusObjectPath, std::map<DbusService, std::vector<DbusInterface>>>;
+
+constexpr auto invBus = "xyz.openbmc_project.Inventory.Manager";
+constexpr auto invNetworkIntf =
+    "xyz.openbmc_project.Inventory.Item.NetworkInterface";
+constexpr auto invRoot = "/xyz/openbmc_project/inventory";
+
+ether_addr getfromInventory(sdbusplus::bus::bus& bus,
+                            const std::string& intfName)
+{
+
+    std::string interfaceName = intfName;
+
+#ifdef SYNC_MAC_FROM_INVENTORY
+    // load the config JSON from the Read Only Path
+    std::ifstream in(configFile);
+    nlohmann::json configJson;
+    in >> configJson;
+    interfaceName = configJson[intfName];
+#endif
+
+    std::vector<DbusInterface> interfaces;
+    interfaces.emplace_back(invNetworkIntf);
+
+    auto depth = 0;
+
+    auto mapperCall =
+        bus.new_method_call(mapperBus, mapperObj, mapperIntf, "GetSubTree");
+
+    mapperCall.append(invRoot, depth, interfaces);
+
+    auto mapperReply = bus.call(mapperCall);
+    if (mapperReply.is_method_error())
+    {
+        log<level::ERR>("Error in mapper call");
+        elog<InternalFailure>();
+    }
+
+    ObjectTree objectTree;
+    mapperReply.read(objectTree);
+
+    if (objectTree.empty())
+    {
+        log<level::ERR>("No Object has implemented the interface",
+                        entry("INTERFACE=%s", invNetworkIntf));
+        elog<InternalFailure>();
+    }
+
+    DbusObjectPath objPath;
+    DbusService service;
+
+    if (1 == objectTree.size())
+    {
+        objPath = objectTree.begin()->first;
+        service = objectTree.begin()->second.begin()->first;
+    }
+    else
+    {
+        // If there are more than 2 objects, object path must contain the
+        // interface name
+        for (auto const& object : objectTree)
+        {
+            log<level::INFO>("interface",
+                             entry("INT=%s", interfaceName.c_str()));
+            log<level::INFO>("object", entry("OBJ=%s", object.first.c_str()));
+
+            if (std::string::npos != object.first.find(interfaceName.c_str()))
+            {
+                objPath = object.first;
+                service = object.second.begin()->first;
+                break;
+            }
+        }
+
+        if (objPath.empty())
+        {
+            log<level::ERR>("Can't find the object for the interface",
+                            entry("intfName=%s", interfaceName.c_str()));
+            elog<InternalFailure>();
+        }
+    }
+
+    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                      propIntf, methodGet);
+
+    method.append(invNetworkIntf, "MACAddress");
+
+    auto reply = bus.call(method);
+    if (reply.is_method_error())
+    {
+        log<level::ERR>("Failed to get MACAddress",
+                        entry("PATH=%s", objPath.c_str()),
+                        entry("INTERFACE=%s", invNetworkIntf));
+        elog<InternalFailure>();
+    }
+
+    std::variant<std::string> value;
+    reply.read(value);
+    return fromString(std::get<std::string>(value));
+}
+
+ether_addr fromString(const char* str)
+{
+    struct ether_addr* mac = ether_aton(str);
+    if (mac == nullptr)
+    {
+        throw std::invalid_argument("Invalid MAC Address");
+    }
+    return *mac;
+}
+
+std::string toString(const ether_addr& mac)
+{
+    char buf[18] = {0};
+    snprintf(buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x", mac.ether_addr_octet[0],
+             mac.ether_addr_octet[1], mac.ether_addr_octet[2],
+             mac.ether_addr_octet[3], mac.ether_addr_octet[4],
+             mac.ether_addr_octet[5]);
+    return buf;
+}
+
+bool isEmpty(const ether_addr& mac)
+{
+    return stdplus::raw::equal(mac, ether_addr{});
+}
+
+bool isMulticast(const ether_addr& mac)
+{
+    return mac.ether_addr_octet[0] & 0b1;
+}
+
+bool isUnicast(const ether_addr& mac)
+{
+    return !isEmpty(mac) && !isMulticast(mac);
+}
+
+} // namespace mac_address
+} // namespace network
+} // namespace phosphor
diff --git a/src/util.hpp b/src/util.hpp
new file mode 100644
index 0000000..804d492
--- /dev/null
+++ b/src/util.hpp
@@ -0,0 +1,250 @@
+#pragma once
+
+#include "config.h"
+
+#include "ethernet_interface.hpp"
+#include "types.hpp"
+
+#include <netinet/ether.h>
+#include <unistd.h>
+
+#include <cstring>
+#include <optional>
+#include <sdbusplus/bus.hpp>
+#include <string>
+#include <string_view>
+#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using EthernetInterfaceIntf =
+    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface;
+
+constexpr auto IPV4_MIN_PREFIX_LENGTH = 1;
+constexpr auto IPV4_MAX_PREFIX_LENGTH = 32;
+constexpr auto IPV6_MAX_PREFIX_LENGTH = 128;
+constexpr auto IPV4_PREFIX = "169.254";
+constexpr auto IPV6_PREFIX = "fe80";
+
+namespace mac_address
+{
+
+/** @brief gets the MAC address from the Inventory.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] intfName - Interface name
+ */
+ether_addr getfromInventory(sdbusplus::bus::bus& bus,
+                            const std::string& intfName);
+
+/** @brief Converts the given mac address into byte form
+ *  @param[in] str - The mac address in human readable form
+ *  @returns A mac address in network byte order
+ *  @throws std::runtime_error for bad mac
+ */
+ether_addr fromString(const char* str);
+inline ether_addr fromString(const std::string& str)
+{
+    return fromString(str.c_str());
+}
+
+/** @brief Converts the given mac address bytes into a string
+ *  @param[in] mac - The mac address
+ *  @returns A valid mac address string
+ */
+std::string toString(const ether_addr& mac);
+
+/** @brief Determines if the mac address is empty
+ *  @param[in] mac - The mac address
+ *  @return True if 00:00:00:00:00:00
+ */
+bool isEmpty(const ether_addr& mac);
+
+/** @brief Determines if the mac address is a multicast address
+ *  @param[in] mac - The mac address
+ *  @return True if multicast bit is set
+ */
+bool isMulticast(const ether_addr& mac);
+
+/** @brief Determines if the mac address is a unicast address
+ *  @param[in] mac - The mac address
+ *  @return True if not multicast or empty
+ */
+bool isUnicast(const ether_addr& mac);
+
+} // namespace mac_address
+
+constexpr auto networkdService = "systemd-networkd.service";
+constexpr auto timeSynchdService = "systemd-timesyncd.service";
+
+/* @brief converts the given subnet into prefix notation.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] mask - Subnet Mask.
+ * @returns prefix.
+ */
+uint8_t toCidr(int addressFamily, const std::string& mask);
+
+/* @brief converts a sockaddr for the specified address family into
+ *        a type_safe InAddrAny.
+ * @param[in] addressFamily - The address family of the buf
+ * @param[in] buf - The network byte order address
+ */
+InAddrAny addrFromBuf(int addressFamily, std::string_view buf);
+
+/* @brief converts the ip bytes into a string representation
+ * @param[in] addr - input ip address to convert.
+ * @returns String representation of the ip.
+ */
+std::string toString(const InAddrAny& addr);
+std::string toString(const struct in_addr& addr);
+std::string toString(const struct in6_addr& addr);
+
+/* @brief converts the prefix into subnetmask.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] prefix - prefix length.
+ * @returns subnet mask.
+ */
+std::string toMask(int addressFamily, uint8_t prefix);
+
+/* @brief checks that the given ip address is link local or not.
+ * @param[in] address - IP address.
+ * @returns true if it is linklocal otherwise false.
+ */
+bool isLinkLocalIP(const std::string& address);
+
+/* @brief checks that the given ip address valid or not.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] address - IP address.
+ * @returns true if it is valid otherwise false.
+ */
+bool isValidIP(int addressFamily, const std::string& address);
+
+/* @brief checks that the given prefix is valid or not.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] prefix - prefix length.
+ * @returns true if it is valid otherwise false.
+ */
+bool isValidPrefix(int addressFamily, uint8_t prefixLength);
+
+/** @brief Gets the map of interface and the associated
+ *         address.
+ *  @returns map of interface and the address.
+ */
+IntfAddrMap getInterfaceAddrs();
+
+/** @brief Get all the interfaces from the system.
+ *  @returns list of interface names.
+ */
+InterfaceList getInterfaces();
+
+/** @brief Delete the given interface.
+ *  @param[in] intf - interface name.
+ */
+void deleteInterface(const std::string& intf);
+
+/** @brief Converts the interface name into a u-boot environment
+ *         variable that would hold its ethernet address.
+ *
+ *  @param[in] intf - interface name
+ *  @return The name of th environment key
+ */
+std::optional<std::string> interfaceToUbootEthAddr(const char* intf);
+
+/** @brief read the DHCP value from the configuration file
+ *  @param[in] confDir - Network configuration directory.
+ *  @param[in] intf - Interface name.
+ */
+EthernetInterfaceIntf::DHCPConf getDHCPValue(const std::string& confDir,
+                                             const std::string& intf);
+
+namespace internal
+{
+
+/* @brief runs the given command in child process.
+ * @param[in] path - path of the binary file which needs to be execeuted.
+ * @param[in] args - arguments of the command.
+ */
+void executeCommandinChildProcess(const char* path, char** args);
+
+/** @brief Get ignored interfaces from environment */
+std::string_view getIgnoredInterfacesEnv();
+
+/** @brief Parse the comma separated interface names */
+std::set<std::string_view> parseInterfaces(std::string_view interfaces);
+
+/** @brief Get the ignored interfaces */
+const std::set<std::string_view>& getIgnoredInterfaces();
+
+} // namespace internal
+
+/* @brief runs the given command in child process.
+ * @param[in] path -path of the binary file which needs to be execeuted.
+ * @param[in] tArgs - arguments of the command.
+ */
+template <typename... ArgTypes>
+void execute(const char* path, ArgTypes&&... tArgs)
+{
+    using expandType = char*[];
+
+    expandType args = {const_cast<char*>(tArgs)..., nullptr};
+
+    internal::executeCommandinChildProcess(path, args);
+}
+
+} // namespace network
+
+class Descriptor
+{
+  private:
+    /** default value */
+    int fd = -1;
+
+  public:
+    Descriptor() = default;
+    Descriptor(const Descriptor&) = delete;
+    Descriptor& operator=(const Descriptor&) = delete;
+    Descriptor(Descriptor&&) = delete;
+    Descriptor& operator=(Descriptor&&) = delete;
+
+    explicit Descriptor(int fd) : fd(fd)
+    {
+    }
+
+    /* @brief sets the internal file descriptor with the given descriptor
+     *        and closes the old descriptor.
+     * @param[in] descriptor - File/Socket descriptor.
+     */
+    void set(int descriptor)
+    {
+        // same descriptor given
+        if (fd == descriptor)
+        {
+            return;
+        }
+
+        // close the old descriptor
+        if (fd >= 0)
+        {
+            close(fd);
+        }
+
+        fd = descriptor;
+    }
+
+    ~Descriptor()
+    {
+        if (fd >= 0)
+        {
+            close(fd);
+        }
+    }
+
+    int operator()() const
+    {
+        return fd;
+    }
+};
+
+} // namespace phosphor
diff --git a/src/vlan_interface.cpp b/src/vlan_interface.cpp
new file mode 100644
index 0000000..4920c77
--- /dev/null
+++ b/src/vlan_interface.cpp
@@ -0,0 +1,80 @@
+#include "config.h"
+
+#include "vlan_interface.hpp"
+
+#include "ethernet_interface.hpp"
+#include "network_manager.hpp"
+
+#include <algorithm>
+#include <filesystem>
+#include <fstream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <string>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+VlanInterface::VlanInterface(sdbusplus::bus::bus& bus,
+                             const std::string& objPath, DHCPConf dhcpEnabled,
+                             bool nicEnabled, uint32_t vlanID,
+                             EthernetInterface& intf, Manager& parent) :
+    VlanIface(bus, objPath.c_str()),
+    DeleteIface(bus, objPath.c_str()),
+    EthernetInterface(bus, objPath, dhcpEnabled, parent, false),
+    parentInterface(intf)
+{
+    id(vlanID);
+    EthernetInterfaceIntf::nicEnabled(nicEnabled);
+    VlanIface::interfaceName(EthernetInterface::interfaceName());
+    MacAddressIntf::macAddress(parentInterface.macAddress());
+
+    emit_object_added();
+}
+
+std::string VlanInterface::macAddress(std::string)
+{
+    log<level::ERR>("Tried to set MAC address on VLAN");
+    elog<InternalFailure>();
+}
+
+void VlanInterface::writeDeviceFile()
+{
+    using namespace std::string_literals;
+    fs::path confPath = manager.getConfDir();
+    std::string fileName = EthernetInterface::interfaceName() + ".netdev"s;
+    confPath /= fileName;
+    std::fstream stream;
+    try
+    {
+        stream.open(confPath.c_str(), std::fstream::out);
+    }
+    catch (std::ios_base::failure& e)
+    {
+        log<level::ERR>("Unable to open the VLAN device file",
+                        entry("FILE=%s", confPath.c_str()),
+                        entry("ERROR=%s", e.what()));
+        elog<InternalFailure>();
+    }
+
+    stream << "[NetDev]\n";
+    stream << "Name=" << EthernetInterface::interfaceName() << "\n";
+    stream << "Kind=vlan\n";
+    stream << "[VLAN]\n";
+    stream << "Id=" << id() << "\n";
+    stream.close();
+}
+
+void VlanInterface::delete_()
+{
+    parentInterface.deleteVLANObject(EthernetInterface::interfaceName());
+}
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/vlan_interface.hpp b/src/vlan_interface.hpp
new file mode 100644
index 0000000..c003056
--- /dev/null
+++ b/src/vlan_interface.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include "ethernet_interface.hpp"
+#include "types.hpp"
+#include "xyz/openbmc_project/Network/VLAN/server.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <string>
+#include <xyz/openbmc_project/Object/Delete/server.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+
+class EthernetInterface;
+class Manager;
+
+using DeleteIface = sdbusplus::xyz::openbmc_project::Object::server::Delete;
+using VlanIface = sdbusplus::xyz::openbmc_project::Network::server::VLAN;
+
+/** @class VlanInterface
+ *  @brief OpenBMC vlan Interface implementation.
+ *  @details A concrete implementation for the vlan interface
+ */
+class VlanInterface : public VlanIface,
+                      public DeleteIface,
+                      public EthernetInterface
+{
+  public:
+    VlanInterface() = delete;
+    VlanInterface(const VlanInterface&) = delete;
+    VlanInterface& operator=(const VlanInterface&) = delete;
+    VlanInterface(VlanInterface&&) = delete;
+    VlanInterface& operator=(VlanInterface&&) = delete;
+    virtual ~VlanInterface() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Path to attach at.
+     *  @param[in] dhcpEnabled - DHCP enable value.
+     *  @param[in] vlanID - vlan identifier.
+     *  @param[in] intf - ethernet interface object.
+     *  @param[in] manager - network manager object.
+     *
+     *  This constructor is called during loading the VLAN Interface
+     */
+    VlanInterface(sdbusplus::bus::bus& bus, const std::string& objPath,
+                  DHCPConf dhcpEnabled, bool nicEnabled, uint32_t vlanID,
+                  EthernetInterface& intf, Manager& parent);
+
+    /** @brief Delete this d-bus object.
+     */
+    void delete_() override;
+
+    /** @brief sets the MAC address.
+     *  @param[in] value - MAC address which needs to be set on the system.
+     *  @returns macAddress of the interface or throws an error.
+     */
+    std::string macAddress(std::string value) override;
+
+    /** @brief writes the device configuration.
+               systemd reads this configuration file
+               and creates the vlan interface.*/
+    void writeDeviceFile();
+
+  private:
+    /** @brief VLAN Identifier. */
+    using VlanIface::id;
+
+    EthernetInterface& parentInterface;
+
+    friend class TestVlanInterface;
+};
+
+} // namespace network
+} // namespace phosphor
diff --git a/src/watch.cpp b/src/watch.cpp
new file mode 100644
index 0000000..0efe300
--- /dev/null
+++ b/src/watch.cpp
@@ -0,0 +1,125 @@
+#include "watch.hpp"
+
+#include <errno.h>
+#include <sys/inotify.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace network
+{
+namespace inotify
+{
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+Watch::Watch(phosphor::network::EventPtr& eventPtr, fs::path path,
+             UserCallBack userFunc, int flags, uint32_t mask, uint32_t events) :
+    path(path),
+    userFunc(userFunc), flags(flags), mask(mask), events(events),
+    fd(inotifyInit())
+{
+    // Check if watch file exists
+    // This is supposed to be there always
+    if (!fs::is_regular_file(path))
+    {
+        log<level::ERR>("Watch file doesn't exist",
+                        entry("FILE=%s", path.c_str()));
+        elog<InternalFailure>();
+    }
+
+    auto dirPath = path.parent_path();
+    wd = inotify_add_watch(fd(), dirPath.c_str(), mask);
+    if (wd == -1)
+    {
+        log<level::ERR>("Error from inotify_add_watch",
+                        entry("ERRNO=%d", errno));
+        elog<InternalFailure>();
+    }
+
+    // Register the fd with sd_event infrastructure and setup a
+    // callback handler to be invoked on events
+    auto rc = sd_event_add_io(eventPtr.get(), nullptr, fd(), events,
+                              Watch::processEvents, this);
+    if (rc < 0)
+    {
+        // Failed to add to event loop
+        log<level::ERR>("Error registering with sd_event_add_io",
+                        entry("RC=%d", rc));
+        elog<InternalFailure>();
+    }
+}
+
+int Watch::inotifyInit()
+{
+    auto fd = inotify_init1(flags);
+    if (fd < 0)
+    {
+        log<level::ERR>("Error from inotify_init1", entry("ERRNO=%d", errno));
+        elog<InternalFailure>();
+    }
+    return fd;
+}
+
+int Watch::processEvents(sd_event_source* /*eventSource*/, int fd,
+                         uint32_t retEvents, void* userData)
+{
+    auto watch = static_cast<Watch*>(userData);
+
+    // Not the ones we are interested in
+    if (!(retEvents & watch->events))
+    {
+        return 0;
+    }
+
+    // Buffer size to be used while reading events.
+    // per inotify(7), below number should be fine for reading
+    // at-least one event
+    constexpr auto maxBytes = sizeof(struct inotify_event) + NAME_MAX + 1;
+    uint8_t eventData[maxBytes]{};
+
+    auto bytes = read(fd, eventData, maxBytes);
+    if (bytes <= 0)
+    {
+        // Failed to read inotify event data
+        // Report error and return
+        log<level::ERR>("Error reading inotify event",
+                        entry("ERRNO=%d", errno));
+        report<InternalFailure>();
+        return 0;
+    }
+
+    auto offset = 0;
+    auto stateFile = watch->path.filename();
+    while (offset < bytes)
+    {
+        auto event = reinterpret_cast<inotify_event*>(&eventData[offset]);
+
+        // Filter the interesting ones
+        auto mask = event->mask & watch->mask;
+        if (mask)
+        {
+            if ((event->len > 0) &&
+                (strstr(event->name, stateFile.string().c_str())))
+            {
+                if (watch->userFunc)
+                {
+                    watch->userFunc(watch->path);
+                }
+                // Found the event of interest
+                break;
+            }
+        }
+        // Move past this entry
+        offset += offsetof(inotify_event, name) + event->len;
+    }
+    return 0;
+}
+
+} // namespace inotify
+} // namespace network
+} // namespace phosphor
diff --git a/src/watch.hpp b/src/watch.hpp
new file mode 100644
index 0000000..b45f53f
--- /dev/null
+++ b/src/watch.hpp
@@ -0,0 +1,109 @@
+#pragma once
+
+#include "dns_updater.hpp"
+#include "types.hpp"
+#include "util.hpp"
+
+#include <sys/inotify.h>
+#include <systemd/sd-event.h>
+
+#include <filesystem>
+#include <functional>
+#include <map>
+
+namespace phosphor
+{
+namespace network
+{
+namespace inotify
+{
+
+namespace fs = std::filesystem;
+
+// Auxiliary callback to be invoked on inotify events
+using UserCallBack = std::function<void(const std::string&)>;
+
+/** @class Watch
+ *
+ *  @brief Adds inotify watch on directory
+ *
+ *  @details Calls back user function on matching events
+ */
+class Watch
+{
+  public:
+    Watch() = delete;
+    Watch(const Watch&) = delete;
+    Watch& operator=(const Watch&) = delete;
+    Watch(Watch&&) = delete;
+    Watch& operator=(Watch&&) = delete;
+
+    /** @brief Hooks inotify watch with sd-event
+     *
+     *  @param[in] eventPtr - Reference to sd_event wrapped in unique_ptr
+     *  @param[in] path     - File path to be watched
+     *  @param[in] userFunc - User specific callback function on events
+     *  @param[in] flags    - Flags to be supplied to inotify
+     *  @param[in] mask     - Mask of events to be supplied to inotify
+     *  @param[in] events   - Events to be watched
+     */
+    Watch(phosphor::network::EventPtr& eventPtr, const fs::path path,
+          UserCallBack userFunc, int flags = IN_NONBLOCK,
+          uint32_t mask = IN_CLOSE_WRITE, uint32_t events = EPOLLIN);
+
+    /** @brief Remove inotify watch and close fd's */
+    ~Watch()
+    {
+        if ((fd() >= 0) && (wd >= 0))
+        {
+            inotify_rm_watch(fd(), wd);
+        }
+    }
+
+  private:
+    /** @brief Callback invoked when inotify event fires
+     *
+     *  @details On a matching event, calls back into user supplied
+     *           function if there is one registered
+     *
+     *  @param[in] eventSource - Event source
+     *  @param[in] fd          - Inotify fd
+     *  @param[in] retEvents   - Events that matched for fd
+     *  @param[in] userData    - Pointer to Watch object
+     *
+     *  @returns 0 on success, -1 on fail
+     */
+    static int processEvents(sd_event_source* eventSource, int fd,
+                             uint32_t retEvents, void* userData);
+
+    /** @brief Initializes an inotify instance
+     *
+     *  @return Descriptor on success, -1 on failure
+     */
+    int inotifyInit();
+
+    /** @brief File path to be watched */
+    const fs::path path;
+
+    /** @brief User callback function */
+    UserCallBack userFunc;
+
+    /** @brief Inotify flags */
+    int flags;
+
+    /** @brief Mask of events */
+    uint32_t mask;
+
+    /** @brief Events to be watched */
+    uint32_t events;
+
+    /** @brief Watch descriptor */
+    int wd = -1;
+
+    /** @brief File descriptor manager */
+    phosphor::Descriptor fd;
+};
+
+} // namespace inotify
+} // namespace network
+} // namespace phosphor
