diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 85af636..da4df20 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -16,6 +16,8 @@
 #pragma once
 
 #include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <boost/optional.hpp>
 #include <dbus_singleton.hpp>
 #include <error_messages.hpp>
 #include <node.hpp>
@@ -33,38 +35,37 @@
     sdbusplus::message::variant<std::string, bool, uint8_t, int16_t, uint16_t,
                                 int32_t, uint32_t, int64_t, uint64_t, double>>;
 
-using GetManagedObjectsType = boost::container::flat_map<
+using GetManagedObjects = std::vector<std::pair<
     sdbusplus::message::object_path,
-    boost::container::flat_map<
+    std::vector<std::pair<
         std::string,
         boost::container::flat_map<
             std::string, sdbusplus::message::variant<
                              std::string, bool, uint8_t, int16_t, uint16_t,
-                             int32_t, uint32_t, int64_t, uint64_t, double>>>>;
+                             int32_t, uint32_t, int64_t, uint64_t, double>>>>>>;
+
+enum class LinkType
+{
+    Local,
+    Global
+};
 
 /**
  * Structure for keeping IPv4 data required by Redfish
- * TODO(Pawel) consider change everything to ptr, or to non-ptr values.
  */
 struct IPv4AddressData
 {
     std::string id;
-    const std::string *address;
-    const std::string *domain;
-    const std::string *gateway;
+    std::string address;
+    std::string domain;
+    std::string gateway;
     std::string netmask;
     std::string origin;
-    bool global;
-    /**
-     * @brief Operator< to enable sorting
-     *
-     * @param[in] obj   Object to compare with
-     *
-     * @return This object id < supplied object id
-     */
+    LinkType linktype;
+
     bool operator<(const IPv4AddressData &obj) const
     {
-        return (id < obj.id);
+        return id < obj.id;
     }
 };
 
@@ -74,771 +75,695 @@
  */
 struct EthernetInterfaceData
 {
-    const unsigned int *speed;
-    const bool *autoNeg;
-    const std::string *hostname;
-    const std::string *defaultGateway;
-    const std::string *macAddress;
-    const unsigned int *vlanId;
+    uint32_t speed;
+    bool auto_neg;
+    std::string hostname;
+    std::string default_gateway;
+    std::string mac_address;
+    boost::optional<uint32_t> vlan_id;
 };
 
-/**
- * OnDemandEthernetProvider
- * Ethernet provider class that retrieves data directly from dbus, before
- * setting it into JSON output. This does not cache any data.
- *
- * TODO(Pawel)
- * This perhaps shall be different file, which has to be chosen on compile time
- * depending on OEM needs
- */
-class OnDemandEthernetProvider
+// Helper function that changes bits netmask notation (i.e. /24)
+// into full dot notation
+inline std::string getNetmask(unsigned int bits)
 {
-  private:
-    // Consts that may have influence on EthernetProvider performance/memory
-    // usage
-    const size_t maxIpV4AddressesPerInterface = 10;
+    uint32_t value = 0xffffffff << (32 - bits);
+    std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
+                          std::to_string((value >> 16) & 0xff) + "." +
+                          std::to_string((value >> 8) & 0xff) + "." +
+                          std::to_string(value & 0xff);
+    return netmask;
+}
 
-    // Helper function that allows to extract GetAllPropertiesType from
-    // GetManagedObjectsType, based on object path, and interface name
-    const PropertiesMapType *extractInterfaceProperties(
-        const sdbusplus::message::object_path &objpath,
-        const std::string &interface, const GetManagedObjectsType &dbus_data)
+inline std::string
+    translateAddressOriginDbusToRedfish(const std::string &inputOrigin,
+                                        bool isIPv4)
+{
+    if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
     {
-        const auto &dbusObj = dbus_data.find(objpath);
-        if (dbusObj != dbus_data.end())
+        return "Static";
+    }
+    if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal")
+    {
+        if (isIPv4)
         {
-            const auto &iface = dbusObj->second.find(interface);
-            if (iface != dbusObj->second.end())
+            return "IPv4LinkLocal";
+        }
+        else
+        {
+            return "LinkLocal";
+        }
+    }
+    if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP")
+    {
+        if (isIPv4)
+        {
+            return "DHCP";
+        }
+        else
+        {
+            return "DHCPv6";
+        }
+    }
+    if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC")
+    {
+        return "SLAAC";
+    }
+    return "";
+}
+
+inline std::string
+    translateAddressOriginRedfishToDbus(const std::string &inputOrigin)
+{
+    if (inputOrigin == "Static")
+    {
+        return "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
+    }
+    if (inputOrigin == "DHCP" || inputOrigin == "DHCPv6")
+    {
+        return "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
+    }
+    if (inputOrigin == "IPv4LinkLocal" || inputOrigin == "LinkLocal")
+    {
+        return "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal";
+    }
+    if (inputOrigin == "SLAAC")
+    {
+        return "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC";
+    }
+    return "";
+}
+
+inline void extractEthernetInterfaceData(const std::string &ethiface_id,
+                                         const GetManagedObjects &dbus_data,
+                                         EthernetInterfaceData &ethData)
+{
+    for (const auto &objpath : dbus_data)
+    {
+        if (objpath.first == "/xyz/openbmc_project/network/" + ethiface_id)
+        {
+            for (const auto &ifacePair : objpath.second)
             {
-                return &iface->second;
-            }
-        }
-        return nullptr;
-    }
-
-    // Helper Wrapper that does inline object_path conversion from string
-    // into sdbusplus::message::object_path type
-    inline const PropertiesMapType *
-        extractInterfaceProperties(const std::string &objpath,
-                                   const std::string &interface,
-                                   const GetManagedObjectsType &dbus_data)
-    {
-        const auto &dbusObj = sdbusplus::message::object_path{objpath};
-        return extractInterfaceProperties(dbusObj, interface, dbus_data);
-    }
-
-    // Helper function that allows to get pointer to the property from
-    // GetAllPropertiesType native, or extracted by GetAllPropertiesType
-    template <typename T>
-    inline T const *const extractProperty(const PropertiesMapType &properties,
-                                          const std::string &name)
-    {
-        const auto &property = properties.find(name);
-        if (property != properties.end())
-        {
-            return mapbox::getPtr<const T>(property->second);
-        }
-        return nullptr;
-    }
-    // TODO(Pawel) Consider to move the above functions to dbus
-    // generic_interfaces.hpp
-
-    // Helper function that extracts data from several dbus objects and several
-    // interfaces required by single ethernet interface instance
-    void extractEthernetInterfaceData(const std::string &ethifaceId,
-                                      const GetManagedObjectsType &dbus_data,
-                                      EthernetInterfaceData &eth_data)
-    {
-        // Extract data that contains MAC Address
-        const PropertiesMapType *macProperties = extractInterfaceProperties(
-            "/xyz/openbmc_project/network/" + ethifaceId,
-            "xyz.openbmc_project.Network.MACAddress", dbus_data);
-
-        if (macProperties != nullptr)
-        {
-            eth_data.macAddress =
-                extractProperty<std::string>(*macProperties, "MACAddress");
-        }
-
-        const PropertiesMapType *vlanProperties = extractInterfaceProperties(
-            "/xyz/openbmc_project/network/" + ethifaceId,
-            "xyz.openbmc_project.Network.VLAN", dbus_data);
-
-        if (vlanProperties != nullptr)
-        {
-            eth_data.vlanId =
-                extractProperty<unsigned int>(*vlanProperties, "Id");
-        }
-
-        // Extract data that contains link information (auto negotiation and
-        // speed)
-        const PropertiesMapType *ethProperties = extractInterfaceProperties(
-            "/xyz/openbmc_project/network/" + ethifaceId,
-            "xyz.openbmc_project.Network.EthernetInterface", dbus_data);
-
-        if (ethProperties != nullptr)
-        {
-            eth_data.autoNeg = extractProperty<bool>(*ethProperties, "AutoNeg");
-            eth_data.speed =
-                extractProperty<unsigned int>(*ethProperties, "Speed");
-        }
-
-        // Extract data that contains network config (HostName and DefaultGW)
-        const PropertiesMapType *configProperties = extractInterfaceProperties(
-            "/xyz/openbmc_project/network/config",
-            "xyz.openbmc_project.Network.SystemConfiguration", dbus_data);
-
-        if (configProperties != nullptr)
-        {
-            eth_data.hostname =
-                extractProperty<std::string>(*configProperties, "HostName");
-            eth_data.defaultGateway = extractProperty<std::string>(
-                *configProperties, "DefaultGateway");
-        }
-    }
-
-    // Helper function that changes bits netmask notation (i.e. /24)
-    // into full dot notation
-    inline std::string getNetmask(unsigned int bits)
-    {
-        uint32_t value = 0xffffffff << (32 - bits);
-        std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
-                              std::to_string((value >> 16) & 0xff) + "." +
-                              std::to_string((value >> 8) & 0xff) + "." +
-                              std::to_string(value & 0xff);
-        return netmask;
-    }
-
-    // Helper function that extracts data for single ethernet ipv4 address
-    void extractIPv4Data(const std::string &ethifaceId,
-                         const GetManagedObjectsType &dbus_data,
-                         std::vector<IPv4AddressData> &ipv4_config)
-    {
-        const std::string pathStart =
-            "/xyz/openbmc_project/network/" + ethifaceId + "/ipv4/";
-
-        // Since there might be several IPv4 configurations aligned with
-        // single ethernet interface, loop over all of them
-        for (auto &objpath : dbus_data)
-        {
-            // Check if proper patter for object path appears
-            if (boost::starts_with(
-                    static_cast<const std::string &>(objpath.first), pathStart))
-            {
-                // and get approrpiate interface
-                const auto &interface =
-                    objpath.second.find("xyz.openbmc_project.Network.IP");
-                if (interface != objpath.second.end())
+                if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress")
                 {
-                    // Make a properties 'shortcut', to make everything more
-                    // readable
-                    const PropertiesMapType &properties = interface->second;
-                    // Instance IPv4AddressData structure, and set as
-                    // appropriate
-                    IPv4AddressData ipv4Address;
-
-                    ipv4Address.id =
-                        static_cast<const std::string &>(objpath.first)
-                            .substr(pathStart.size());
-
-                    // IPv4 address
-                    ipv4Address.address =
-                        extractProperty<std::string>(properties, "Address");
-                    // IPv4 gateway
-                    ipv4Address.gateway =
-                        extractProperty<std::string>(properties, "Gateway");
-
-                    // Origin is kind of DBus object so fetch pointer...
-                    const std::string *origin =
-                        extractProperty<std::string>(properties, "Origin");
-                    if (origin != nullptr)
+                    for (const auto &propertyPair : ifacePair.second)
                     {
-                        ipv4Address.origin =
-                            translateAddressOriginBetweenDBusAndRedfish(
-                                origin, true, true);
-                    }
-
-                    // Netmask is presented as PrefixLength
-                    const auto *mask =
-                        extractProperty<uint8_t>(properties, "PrefixLength");
-                    if (mask != nullptr)
-                    {
-                        // convert it to the string
-                        ipv4Address.netmask = getNetmask(*mask);
-                    }
-
-                    // Attach IPv4 only if address is present
-                    if (ipv4Address.address != nullptr)
-                    {
-                        // Check if given address is local, or global
-                        if (boost::starts_with(*ipv4Address.address, "169.254"))
+                        if (propertyPair.first == "MACAddress")
                         {
-                            ipv4Address.global = false;
+                            const std::string *mac =
+                                mapbox::getPtr<const std::string>(
+                                    propertyPair.second);
+                            if (mac != nullptr)
+                            {
+                                ethData.mac_address = *mac;
+                            }
                         }
-                        else
+                    }
+                }
+                else if (ifacePair.first == "xyz.openbmc_project.Network.VLAN")
+                {
+                    for (const auto &propertyPair : ifacePair.second)
+                    {
+                        if (propertyPair.first == "Id")
                         {
-                            ipv4Address.global = true;
+                            const uint32_t *id = mapbox::getPtr<const uint32_t>(
+                                propertyPair.second);
+                            if (id != nullptr)
+                            {
+                                ethData.vlan_id = *id;
+                            }
                         }
-                        ipv4_config.emplace_back(std::move(ipv4Address));
+                    }
+                }
+                else if (ifacePair.first ==
+                         "xyz.openbmc_project.Network.EthernetInterface")
+                {
+                    for (const auto &propertyPair : ifacePair.second)
+                    {
+                        if (propertyPair.first == "AutoNeg")
+                        {
+                            const bool *auto_neg =
+                                mapbox::getPtr<const bool>(propertyPair.second);
+                            if (auto_neg != nullptr)
+                            {
+                                ethData.auto_neg = *auto_neg;
+                            }
+                        }
+                        else if (propertyPair.first == "Speed")
+                        {
+                            const uint32_t *speed =
+                                mapbox::getPtr<const uint32_t>(
+                                    propertyPair.second);
+                            if (speed != nullptr)
+                            {
+                                ethData.speed = *speed;
+                            }
+                        }
+                    }
+                }
+                else if (ifacePair.first ==
+                         "xyz.openbmc_project.Network.SystemConfiguration")
+                {
+                    for (const auto &propertyPair : ifacePair.second)
+                    {
+                        if (propertyPair.first == "HostName")
+                        {
+                            const std::string *hostname =
+                                mapbox::getPtr<const std::string>(
+                                    propertyPair.second);
+                            if (hostname != nullptr)
+                            {
+                                ethData.hostname = *hostname;
+                            }
+                        }
+                        else if (propertyPair.first == "DefaultGateway")
+                        {
+                            const std::string *defaultGateway =
+                                mapbox::getPtr<const std::string>(
+                                    propertyPair.second);
+                            if (defaultGateway != nullptr)
+                            {
+                                ethData.default_gateway = *defaultGateway;
+                            }
+                        }
                     }
                 }
             }
         }
-
-        /**
-         * We have to sort this vector and ensure that order of IPv4 addresses
-         * is consistent between GETs to allow modification and deletion in
-         * PATCHes
-         */
-        std::sort(ipv4_config.begin(), ipv4_config.end());
     }
+}
+
+// Helper function that extracts data for single ethernet ipv4 address
+inline void
+    extractIPData(const std::string &ethiface_id,
+                  const GetManagedObjects &dbus_data,
+                  boost::container::flat_set<IPv4AddressData> &ipv4_config)
+{
+    const std::string ipv4PathStart =
+        "/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/";
+
+    // Since there might be several IPv4 configurations aligned with
+    // single ethernet interface, loop over all of them
+    for (const auto &objpath : dbus_data)
+    {
+        // Check if proper pattern for object path appears
+        if (boost::starts_with(objpath.first.str, ipv4PathStart))
+        {
+            for (auto &interface : objpath.second)
+            {
+                if (interface.first == "xyz.openbmc_project.Network.IP")
+                {
+                    // Instance IPv4AddressData structure, and set as
+                    // appropriate
+                    std::pair<
+                        boost::container::flat_set<IPv4AddressData>::iterator,
+                        bool>
+                        it = ipv4_config.insert(
+                            {objpath.first.str.substr(ipv4PathStart.size())});
+                    IPv4AddressData &ipv4_address = *it.first;
+                    for (auto &property : interface.second)
+                    {
+                        if (property.first == "Address")
+                        {
+                            const std::string *address =
+                                mapbox::getPtr<const std::string>(
+                                    property.second);
+                            if (address != nullptr)
+                            {
+                                ipv4_address.address = *address;
+                            }
+                        }
+                        else if (property.first == "Gateway")
+                        {
+                            const std::string *gateway =
+                                mapbox::getPtr<const std::string>(
+                                    property.second);
+                            if (gateway != nullptr)
+                            {
+                                ipv4_address.gateway = *gateway;
+                            }
+                        }
+                        else if (property.first == "Origin")
+                        {
+                            const std::string *origin =
+                                mapbox::getPtr<const std::string>(
+                                    property.second);
+                            if (origin != nullptr)
+                            {
+                                ipv4_address.origin =
+                                    translateAddressOriginDbusToRedfish(*origin,
+                                                                        true);
+                            }
+                        }
+                        else if (property.first == "PrefixLength")
+                        {
+                            const uint8_t *mask =
+                                mapbox::getPtr<uint8_t>(property.second);
+                            if (mask != nullptr)
+                            {
+                                // convert it to the string
+                                ipv4_address.netmask = getNetmask(*mask);
+                            }
+                        }
+                        else
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "Got extra property: " << property.first
+                                << " on the " << objpath.first.str << " object";
+                        }
+                    }
+                    // Check if given address is local, or global
+                    ipv4_address.linktype =
+                        boost::starts_with(ipv4_address.address, "169.254.")
+                            ? LinkType::Global
+                            : LinkType::Local;
+                }
+            }
+        }
+    }
+}
+
+/**
+ * @brief Sets given Id on the given VLAN interface through D-Bus
+ *
+ * @param[in] ifaceId       Id of VLAN interface that should be modified
+ * @param[in] inputVlanId   New ID of the VLAN
+ * @param[in] callback      Function that will be called after the operation
+ *
+ * @return None.
+ */
+template <typename CallbackFunc>
+void changeVlanId(const std::string &ifaceId, const uint32_t &inputVlanId,
+                  CallbackFunc &&callback)
+{
+    crow::connections::systemBus->async_method_call(
+        callback, "xyz.openbmc_project.Network",
+        std::string("/xyz/openbmc_project/network/") + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.VLAN", "Id",
+        sdbusplus::message::variant<uint32_t>(inputVlanId));
+}
+
+/**
+ * @brief Helper function that verifies IP address to check if it is in
+ *        proper format. If bits pointer is provided, also calculates active
+ *        bit count for Subnet Mask.
+ *
+ * @param[in]  ip     IP that will be verified
+ * @param[out] bits   Calculated mask in bits notation
+ *
+ * @return true in case of success, false otherwise
+ */
+inline bool ipv4VerifyIpAndGetBitcount(const std::string &ip,
+                                       uint8_t *bits = nullptr)
+{
+    std::vector<std::string> bytesInMask;
+
+    boost::split(bytesInMask, ip, boost::is_any_of("."));
 
     static const constexpr int ipV4AddressSectionsCount = 4;
-
-  public:
-    /**
-     * @brief Creates VLAN for given interface with given Id through D-Bus
-     *
-     * @param[in] ifaceId       Id of interface for which VLAN will be created
-     * @param[in] inputVlanId   ID of the new VLAN
-     * @param[in] callback      Function that will be called after the operation
-     *
-     * @return None.
-     */
-    template <typename CallbackFunc>
-    void createVlan(const std::string &ifaceId, const uint64_t &inputVlanId,
-                    CallbackFunc &&callback)
+    if (bytesInMask.size() != ipV4AddressSectionsCount)
     {
-        crow::connections::systemBus->async_method_call(
-            callback, "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network",
-            "xyz.openbmc_project.Network.VLAN.Create", "VLAN", ifaceId,
-            static_cast<uint32_t>(inputVlanId));
-    };
+        return false;
+    }
 
-    /**
-     * @brief Sets given Id on the given VLAN interface through D-Bus
-     *
-     * @param[in] ifaceId       Id of VLAN interface that should be modified
-     * @param[in] inputVlanId   New ID of the VLAN
-     * @param[in] callback      Function that will be called after the operation
-     *
-     * @return None.
-     */
-    template <typename CallbackFunc>
-    static void changeVlanId(const std::string &ifaceId,
-                             const uint32_t &inputVlanId,
-                             CallbackFunc &&callback)
+    if (bits != nullptr)
     {
-        crow::connections::systemBus->async_method_call(
-            callback, "xyz.openbmc_project.Network",
-            std::string("/xyz/openbmc_project/network/") + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.VLAN", "Id",
-            sdbusplus::message::variant<uint32_t>(inputVlanId));
-    };
+        *bits = 0;
+    }
 
-    /**
-     * @brief Helper function that verifies IP address to check if it is in
-     *        proper format. If bits pointer is provided, also calculates active
-     *        bit count for Subnet Mask.
-     *
-     * @param[in]  ip     IP that will be verified
-     * @param[out] bits   Calculated mask in bits notation
-     *
-     * @return true in case of success, false otherwise
-     */
-    bool ipv4VerifyIpAndGetBitcount(const std::string &ip,
-                                    uint8_t *bits = nullptr)
+    char *endPtr;
+    long previousValue = 255;
+    bool firstZeroInByteHit;
+    for (const std::string &byte : bytesInMask)
     {
-        std::vector<std::string> bytesInMask;
+        if (byte.empty())
+        {
+            return false;
+        }
 
-        boost::split(bytesInMask, ip, boost::is_any_of("."));
+        // Use strtol instead of stroi to avoid exceptions
+        long value = std::strtol(byte.c_str(), &endPtr, 10);
 
-        if (bytesInMask.size() != ipV4AddressSectionsCount)
+        // endPtr should point to the end of the string, otherwise given string
+        // is not 100% number
+        if (*endPtr != '\0')
+        {
+            return false;
+        }
+
+        // Value should be contained in byte
+        if (value < 0 || value > 255)
         {
             return false;
         }
 
         if (bits != nullptr)
         {
-            *bits = 0;
-        }
-
-        char *endPtr;
-        long previousValue = 255;
-        bool firstZeroInByteHit;
-
-        for (const std::string &byte : bytesInMask)
-        {
-            if (byte.empty())
+            // Mask has to be continuous between bytes
+            if (previousValue != 255 && value != 0)
             {
                 return false;
             }
 
-            // Use strtol instead of stroi to avoid exceptions
-            long value = std::strtol(byte.c_str(), &endPtr, 10);
+            // Mask has to be continuous inside bytes
+            firstZeroInByteHit = false;
 
-            // endPtr should point to the end of the string, otherwise given
-            // string is not 100% number
-            if (*endPtr != '\0')
+            // Count bits
+            for (int bitIdx = 7; bitIdx >= 0; bitIdx--)
             {
-                return false;
-            }
-
-            // Value should be contained in byte
-            if (value < 0 || value > 255)
-            {
-                return false;
-            }
-
-            if (bits != nullptr)
-            {
-                // Mask has to be continuous between bytes
-                if (previousValue != 255 && value != 0)
+                if (value & (1 << bitIdx))
                 {
-                    return false;
-                }
-
-                // Mask has to be continuous inside bytes
-                firstZeroInByteHit = false;
-
-                // Count bits
-                for (int bitIdx = 7; bitIdx >= 0; bitIdx--)
-                {
-                    if (value & (1 << bitIdx))
+                    if (firstZeroInByteHit)
                     {
-                        if (firstZeroInByteHit)
-                        {
-                            // Continuity not preserved
-                            return false;
-                        }
-                        else
-                        {
-                            (*bits)++;
-                        }
+                        // Continuity not preserved
+                        return false;
                     }
                     else
                     {
-                        firstZeroInByteHit = true;
+                        (*bits)++;
                     }
                 }
-            }
-
-            previousValue = value;
-        }
-
-        return true;
-    }
-
-    /**
-     * @brief Changes IPv4 address type property (Address, Gateway)
-     *
-     * @param[in] ifaceId     Id of interface whose IP should be modified
-     * @param[in] ipIdx       index of IP in input array that should be modified
-     * @param[in] ipHash      DBus Hash id of modified IP
-     * @param[in] name        Name of field in JSON representation
-     * @param[in] newValue    New value that should be written
-     * @param[io] asyncResp   Response object that will be returned to client
-     *
-     * @return true if give IP is valid and has been sent do D-Bus, false
-     * otherwise
-     */
-    void changeIPv4AddressProperty(const std::string &ifaceId, int ipIdx,
-                                   const std::string &ipHash,
-                                   const std::string &name,
-                                   const std::string &newValue,
-                                   const std::shared_ptr<AsyncResp> &asyncResp)
-    {
-        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
-                         name{std::move(name)}, newValue{std::move(newValue)}](
-                            const boost::system::error_code ec) {
-            if (ec)
-            {
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue, messages::internalError(),
-                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/" + name);
-            }
-            else
-            {
-                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] =
-                    newValue;
-            }
-        };
-
-        crow::connections::systemBus->async_method_call(
-            std::move(callback), "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.IP", name,
-            sdbusplus::message::variant<std::string>(newValue));
-    };
-
-    /**
-     * @brief Changes IPv4 address origin property
-     *
-     * @param[in] ifaceId       Id of interface whose IP should be modified
-     * @param[in] ipIdx         index of IP in input array that should be
-     * modified
-     * @param[in] ipHash        DBus Hash id of modified IP
-     * @param[in] newValue      New value in Redfish format
-     * @param[in] newValueDbus  New value in D-Bus format
-     * @param[io] asyncResp     Response object that will be returned to client
-     *
-     * @return true if give IP is valid and has been sent do D-Bus, false
-     * otherwise
-     */
-    void changeIPv4Origin(const std::string &ifaceId, int ipIdx,
-                          const std::string &ipHash,
-                          const std::string &newValue,
-                          const std::string &newValueDbus,
-                          const std::shared_ptr<AsyncResp> &asyncResp)
-    {
-        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
-                         newValue{std::move(newValue)}](
-                            const boost::system::error_code ec) {
-            if (ec)
-            {
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue, messages::internalError(),
-                    "/IPv4Addresses/" + std::to_string(ipIdx) +
-                        "/AddressOrigin");
-            }
-            else
-            {
-                asyncResp->res
-                    .jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] =
-                    newValue;
-            }
-        };
-
-        crow::connections::systemBus->async_method_call(
-            std::move(callback), "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.IP", "Origin",
-            sdbusplus::message::variant<std::string>(newValueDbus));
-    };
-
-    /**
-     * @brief Modifies SubnetMask for given IP
-     *
-     * @param[in] ifaceId      Id of interface whose IP should be modified
-     * @param[in] ipIdx        index of IP in input array that should be
-     * modified
-     * @param[in] ipHash       DBus Hash id of modified IP
-     * @param[in] newValueStr  Mask in dot notation as string
-     * @param[in] newValue     Mask as PrefixLength in bitcount
-     * @param[io] asyncResp   Response object that will be returned to client
-     *
-     * @return None
-     */
-    void changeIPv4SubnetMaskProperty(
-        const std::string &ifaceId, int ipIdx, const std::string &ipHash,
-        const std::string &newValueStr, uint8_t &newValue,
-        const std::shared_ptr<AsyncResp> &asyncResp)
-    {
-        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
-                         newValueStr{std::move(newValueStr)}](
-                            const boost::system::error_code ec) {
-            if (ec)
-            {
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue, messages::internalError(),
-                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/SubnetMask");
-            }
-            else
-            {
-                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] =
-                    newValueStr;
-            }
-        };
-
-        crow::connections::systemBus->async_method_call(
-            std::move(callback), "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.IP", "PrefixLength",
-            sdbusplus::message::variant<uint8_t>(newValue));
-    };
-
-    /**
-     * @brief Disables VLAN with given ifaceId
-     *
-     * @param[in] ifaceId   Id of VLAN interface that should be disabled
-     * @param[in] callback  Function that will be called after the operation
-     *
-     * @return None.
-     */
-    template <typename CallbackFunc>
-    static void disableVlan(const std::string &ifaceId, CallbackFunc &&callback)
-    {
-        crow::connections::systemBus->async_method_call(
-            callback, "xyz.openbmc_project.Network",
-            std::string("/xyz/openbmc_project/network/") + ifaceId,
-            "xyz.openbmc_project.Object.Delete", "Delete");
-    };
-
-    /**
-     * @brief Sets given HostName of the machine through D-Bus
-     *
-     * @param[in] newHostname   New name that HostName will be changed to
-     * @param[in] callback      Function that will be called after the operation
-     *
-     * @return None.
-     */
-    template <typename CallbackFunc>
-    void setHostName(const std::string &newHostname, CallbackFunc &&callback)
-    {
-        crow::connections::systemBus->async_method_call(
-            callback, "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/config",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
-            sdbusplus::message::variant<std::string>(newHostname));
-    };
-
-    /**
-     * @brief Deletes given IPv4
-     *
-     * @param[in] ifaceId     Id of interface whose IP should be deleted
-     * @param[in] ipIdx       index of IP in input array that should be deleted
-     * @param[in] ipHash      DBus Hash id of IP that should be deleted
-     * @param[io] asyncResp   Response object that will be returned to client
-     *
-     * @return None
-     */
-    void deleteIPv4(const std::string &ifaceId, const std::string &ipHash,
-                    unsigned int ipIdx,
-                    const std::shared_ptr<AsyncResp> &asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)}](
-                const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::addMessageToJson(
-                        asyncResp->res.jsonValue, messages::internalError(),
-                        "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
-                }
                 else
                 {
-                    asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr;
+                    firstZeroInByteHit = true;
                 }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-            "xyz.openbmc_project.Object.Delete", "Delete");
+            }
+        }
+
+        previousValue = value;
     }
 
-    /**
-     * @brief Creates IPv4 with given data
-     *
-     * @param[in] ifaceId     Id of interface whose IP should be deleted
-     * @param[in] ipIdx       index of IP in input array that should be deleted
-     * @param[in] ipHash      DBus Hash id of IP that should be deleted
-     * @param[io] asyncResp   Response object that will be returned to client
-     *
-     * @return None
-     */
-    void createIPv4(const std::string &ifaceId, unsigned int ipIdx,
-                    uint8_t subnetMask, const std::string &gateway,
-                    const std::string &address,
-                    const std::shared_ptr<AsyncResp> &asyncResp)
-    {
-        auto createIpHandler = [ipIdx{std::move(ipIdx)},
-                                asyncResp{std::move(asyncResp)}](
-                                   const boost::system::error_code ec) {
+    return true;
+}
+
+/**
+ * @brief Changes IPv4 address type property (Address, Gateway)
+ *
+ * @param[in] ifaceId     Id of interface whose IP should be modified
+ * @param[in] ipIdx       Index of IP in input array that should be modified
+ * @param[in] ipHash      DBus Hash id of modified IP
+ * @param[in] name        Name of field in JSON representation
+ * @param[in] newValue    New value that should be written
+ * @param[io] asyncResp   Response object that will be returned to client
+ *
+ * @return true if give IP is valid and has been sent do D-Bus, false
+ * otherwise
+ */
+inline void changeIPv4AddressProperty(
+    const std::string &ifaceId, int ipIdx, const std::string &ipHash,
+    const std::string &name, const std::string &newValue,
+    const std::shared_ptr<AsyncResp> asyncResp)
+{
+    auto callback = [asyncResp, ipIdx, name{std::string(name)},
+                     newValue{std::move(newValue)}](
+                        const boost::system::error_code ec) {
+        if (ec)
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue, messages::internalError(),
+                "/IPv4Addresses/" + std::to_string(ipIdx) + "/" + name);
+        }
+        else
+        {
+            asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] = newValue;
+        }
+    };
+
+    crow::connections::systemBus->async_method_call(
+        std::move(callback), "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.IP", name,
+        sdbusplus::message::variant<std::string>(newValue));
+}
+
+/**
+ * @brief Changes IPv4 address origin property
+ *
+ * @param[in] ifaceId       Id of interface whose IP should be modified
+ * @param[in] ipIdx         Index of IP in input array that should be
+ * modified
+ * @param[in] ipHash        DBus Hash id of modified IP
+ * @param[in] newValue      New value in Redfish format
+ * @param[in] newValueDbus  New value in D-Bus format
+ * @param[io] asyncResp     Response object that will be returned to client
+ *
+ * @return true if give IP is valid and has been sent do D-Bus, false
+ * otherwise
+ */
+inline void changeIPv4Origin(const std::string &ifaceId, int ipIdx,
+                             const std::string &ipHash,
+                             const std::string &newValue,
+                             const std::string &newValueDbus,
+                             const std::shared_ptr<AsyncResp> asyncResp)
+{
+    auto callback = [asyncResp, ipIdx, newValue{std::move(newValue)}](
+                        const boost::system::error_code ec) {
+        if (ec)
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue, messages::internalError(),
+                "/IPv4Addresses/" + std::to_string(ipIdx) + "/AddressOrigin");
+        }
+        else
+        {
+            asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] =
+                newValue;
+        }
+    };
+
+    crow::connections::systemBus->async_method_call(
+        std::move(callback), "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.IP", "Origin",
+        sdbusplus::message::variant<std::string>(newValueDbus));
+}
+
+/**
+ * @brief Modifies SubnetMask for given IP
+ *
+ * @param[in] ifaceId      Id of interface whose IP should be modified
+ * @param[in] ipIdx        Index of IP in input array that should be
+ * modified
+ * @param[in] ipHash       DBus Hash id of modified IP
+ * @param[in] newValueStr  Mask in dot notation as string
+ * @param[in] newValue     Mask as PrefixLength in bitcount
+ * @param[io] asyncResp   Response object that will be returned to client
+ *
+ * @return None
+ */
+inline void changeIPv4SubnetMaskProperty(const std::string &ifaceId, int ipIdx,
+                                         const std::string &ipHash,
+                                         const std::string &newValueStr,
+                                         uint8_t &newValue,
+                                         std::shared_ptr<AsyncResp> asyncResp)
+{
+    auto callback = [asyncResp, ipIdx, newValueStr{std::move(newValueStr)}](
+                        const boost::system::error_code ec) {
+        if (ec)
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue, messages::internalError(),
+                "/IPv4Addresses/" + std::to_string(ipIdx) + "/SubnetMask");
+        }
+        else
+        {
+            asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] =
+                newValueStr;
+        }
+    };
+
+    crow::connections::systemBus->async_method_call(
+        std::move(callback), "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.IP", "PrefixLength",
+        sdbusplus::message::variant<uint8_t>(newValue));
+}
+
+/**
+ * @brief Sets given HostName of the machine through D-Bus
+ *
+ * @param[in] newHostname   New name that HostName will be changed to
+ * @param[in] callback      Function that will be called after the operation
+ *
+ * @return None.
+ */
+template <typename CallbackFunc>
+void setHostName(const std::string &newHostname, CallbackFunc &&callback)
+{
+    crow::connections::systemBus->async_method_call(
+        callback, "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/config",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+        sdbusplus::message::variant<std::string>(newHostname));
+}
+
+/**
+ * @brief Deletes given IPv4
+ *
+ * @param[in] ifaceId     Id of interface whose IP should be deleted
+ * @param[in] ipIdx       Index of IP in input array that should be deleted
+ * @param[in] ipHash      DBus Hash id of IP that should be deleted
+ * @param[io] asyncResp   Response object that will be returned to client
+ *
+ * @return None
+ */
+inline void deleteIPv4(const std::string &ifaceId, const std::string &ipHash,
+                       unsigned int ipIdx,
+                       const std::shared_ptr<AsyncResp> asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [ipIdx, asyncResp](const boost::system::error_code ec) {
             if (ec)
             {
                 messages::addMessageToJson(
                     asyncResp->res.jsonValue, messages::internalError(),
                     "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
             }
-        };
+            else
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr;
+            }
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+        "xyz.openbmc_project.Object.Delete", "Delete");
+}
 
-        crow::connections::systemBus->async_method_call(
-            std::move(createIpHandler), "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId,
-            "xyz.openbmc_project.Network.IP.Create", "IP",
-            "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask,
-            gateway);
-    }
-
-    /**
-     * @brief Translates Address Origin value from D-Bus to Redfish format and
-     *        vice-versa
-     *
-     * @param[in] inputOrigin Input value that should be translated
-     * @param[in] isIPv4      True for IPv4 origins, False for IPv6
-     * @param[in] isFromDBus  True for DBus->Redfish conversion, false for
-     * reverse
-     *
-     * @return Empty string in case of failure, translated value otherwise
-     */
-    std::string translateAddressOriginBetweenDBusAndRedfish(
-        const std::string *inputOrigin, bool isIPv4, bool isFromDBus)
-    {
-        // Invalid pointer
-        if (inputOrigin == nullptr)
+/**
+ * @brief Creates IPv4 with given data
+ *
+ * @param[in] ifaceId     Id of interface whose IP should be deleted
+ * @param[in] ipIdx       Index of IP in input array that should be deleted
+ * @param[in] ipHash      DBus Hash id of IP that should be deleted
+ * @param[io] asyncResp   Response object that will be returned to client
+ *
+ * @return None
+ */
+inline void createIPv4(const std::string &ifaceId, unsigned int ipIdx,
+                       uint8_t subnetMask, const std::string &gateway,
+                       const std::string &address,
+                       std::shared_ptr<AsyncResp> asyncResp)
+{
+    auto createIpHandler = [ipIdx,
+                            asyncResp](const boost::system::error_code ec) {
+        if (ec)
         {
-            return "";
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue, messages::internalError(),
+                "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
         }
-
-        static const constexpr unsigned int firstIPv4OnlyIdx = 1;
-        static const constexpr unsigned int firstIPv6OnlyIdx = 3;
-
-        std::array<std::pair<const char *, const char *>, 6> translationTable{
-            {{"xyz.openbmc_project.Network.IP.AddressOrigin.Static", "Static"},
-             {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCP"},
-             {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
-              "IPv4LinkLocal"},
-             {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCPv6"},
-             {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
-              "LinkLocal"},
-             {"xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC", "SLAAC"}}};
-
-        for (unsigned int i = 0; i < translationTable.size(); i++)
-        {
-            // Skip unrelated
-            if (isIPv4 && i >= firstIPv6OnlyIdx)
-                break;
-            if (!isIPv4 && i >= firstIPv4OnlyIdx && i < firstIPv6OnlyIdx)
-                continue;
-
-            // When translating D-Bus to Redfish compare input to first element
-            if (isFromDBus && translationTable[i].first == *inputOrigin)
-                return translationTable[i].second;
-
-            // When translating Redfish to D-Bus compare input to second element
-            if (!isFromDBus && translationTable[i].second == *inputOrigin)
-                return translationTable[i].first;
-        }
-
-        // If we are still here, that means that value has not been found
-        return "";
-    }
-
-    /**
-     * Function that retrieves all properties for given Ethernet Interface
-     * Object
-     * from EntityManager Network Manager
-     * @param ethifaceId a eth interface id to query on DBus
-     * @param callback a function that shall be called to convert Dbus output
-     * into JSON
-     */
-    template <typename CallbackFunc>
-    void getEthernetIfaceData(const std::string &ethifaceId,
-                              CallbackFunc &&callback)
-    {
-        crow::connections::systemBus->async_method_call(
-            [this, ethifaceId{std::move(ethifaceId)},
-             callback{std::move(callback)}](
-                const boost::system::error_code error_code,
-                const GetManagedObjectsType &resp) {
-                EthernetInterfaceData ethData{};
-                std::vector<IPv4AddressData> ipv4Data;
-                ipv4Data.reserve(maxIpV4AddressesPerInterface);
-
-                if (error_code)
-                {
-                    // Something wrong on DBus, the error_code is not important
-                    // at this moment, just return success=false, and empty
-                    // output. Since size of vector may vary depending on
-                    // information from Network Manager, and empty output could
-                    // not be treated same way as error.
-                    callback(false, ethData, ipv4Data);
-                    return;
-                }
-
-                // Find interface
-                if (resp.find("/xyz/openbmc_project/network/" + ethifaceId) ==
-                    resp.end())
-                {
-                    // Interface has not been found
-                    callback(false, ethData, ipv4Data);
-                    return;
-                }
-
-                extractEthernetInterfaceData(ethifaceId, resp, ethData);
-                extractIPv4Data(ethifaceId, resp, ipv4Data);
-
-                // Fix global GW
-                for (IPv4AddressData &ipv4 : ipv4Data)
-                {
-                    if ((ipv4.global) && ((ipv4.gateway == nullptr) ||
-                                          (*ipv4.gateway == "0.0.0.0")))
-                    {
-                        ipv4.gateway = ethData.defaultGateway;
-                    }
-                }
-
-                // Finally make a callback with useful data
-                callback(true, ethData, ipv4Data);
-            },
-            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
     };
 
-    /**
-     * Function that retrieves all Ethernet Interfaces available through Network
-     * Manager
-     * @param callback a function that shall be called to convert Dbus output
-     * into JSON.
-     */
-    template <typename CallbackFunc>
-    void getEthernetIfaceList(CallbackFunc &&callback)
-    {
-        crow::connections::systemBus->async_method_call(
-            [this, callback{std::move(callback)}](
-                const boost::system::error_code error_code,
-                GetManagedObjectsType &resp) {
-                // Callback requires vector<string> to retrieve all available
-                // ethernet interfaces
-                std::vector<std::string> ifaceList;
-                ifaceList.reserve(resp.size());
-                if (error_code)
-                {
-                    // Something wrong on DBus, the error_code is not important
-                    // at this moment, just return success=false, and empty
-                    // output. Since size of vector may vary depending on
-                    // information from Network Manager, and empty output could
-                    // not be treated same way as error.
-                    callback(false, ifaceList);
-                    return;
-                }
+    crow::connections::systemBus->async_method_call(
+        std::move(createIpHandler), "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId,
+        "xyz.openbmc_project.Network.IP.Create", "IP",
+        "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask,
+        gateway);
+}
 
-                // Iterate over all retrieved ObjectPaths.
-                for (auto &objpath : resp)
+/**
+ * Function that retrieves all properties for given Ethernet Interface
+ * Object
+ * from EntityManager Network Manager
+ * @param ethiface_id a eth interface id to query on DBus
+ * @param callback a function that shall be called to convert Dbus output
+ * into JSON
+ */
+template <typename CallbackFunc>
+void getEthernetIfaceData(const std::string &ethiface_id,
+                          CallbackFunc &&callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [ethiface_id{std::string{ethiface_id}}, callback{std::move(callback)}](
+            const boost::system::error_code error_code,
+            const GetManagedObjects &resp) {
+            EthernetInterfaceData ethData{};
+            boost::container::flat_set<IPv4AddressData> ipv4Data;
+
+            if (error_code)
+            {
+                callback(false, ethData, ipv4Data);
+                return;
+            }
+
+            extractEthernetInterfaceData(ethiface_id, resp, ethData);
+            extractIPData(ethiface_id, resp, ipv4Data);
+
+            // Fix global GW
+            for (IPv4AddressData &ipv4 : ipv4Data)
+            {
+                if ((ipv4.linktype == LinkType::Global) &&
+                    (ipv4.gateway == "0.0.0.0"))
                 {
-                    // And all interfaces available for certain ObjectPath.
-                    for (auto &interface : objpath.second)
+                    ipv4.gateway = ethData.default_gateway;
+                }
+            }
+
+            // Finally make a callback with usefull data
+            callback(true, ethData, ipv4Data);
+        },
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+};
+
+/**
+ * Function that retrieves all Ethernet Interfaces available through Network
+ * Manager
+ * @param callback a function that shall be called to convert Dbus output
+ * into JSON.
+ */
+template <typename CallbackFunc>
+void getEthernetIfaceList(CallbackFunc &&callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code error_code,
+            GetManagedObjects &resp) {
+            // Callback requires vector<string> to retrieve all available
+            // ethernet interfaces
+            std::vector<std::string> iface_list;
+            iface_list.reserve(resp.size());
+            if (error_code)
+            {
+                callback(false, iface_list);
+                return;
+            }
+
+            // Iterate over all retrieved ObjectPaths.
+            for (const auto &objpath : resp)
+            {
+                // And all interfaces available for certain ObjectPath.
+                for (const auto &interface : objpath.second)
+                {
+                    // If interface is
+                    // xyz.openbmc_project.Network.EthernetInterface, this is
+                    // what we're looking for.
+                    if (interface.first ==
+                        "xyz.openbmc_project.Network.EthernetInterface")
                     {
-                        // If interface is
-                        // xyz.openbmc_project.Network.EthernetInterface, this
-                        // is what we're looking for.
-                        if (interface.first ==
-                            "xyz.openbmc_project.Network.EthernetInterface")
+                        // Cut out everyting until last "/", ...
+                        const std::string &iface_id = objpath.first.str;
+                        std::size_t last_pos = iface_id.rfind("/");
+                        if (last_pos != std::string::npos)
                         {
-                            // Cut out everything until last "/", ...
-                            const std::string &ifaceId =
-                                static_cast<const std::string &>(objpath.first);
-                            std::size_t lastPos = ifaceId.rfind("/");
-                            if (lastPos != std::string::npos)
-                            {
-                                // and put it into output vector.
-                                ifaceList.emplace_back(
-                                    ifaceId.substr(lastPos + 1));
-                            }
+                            // and put it into output vector.
+                            iface_list.emplace_back(
+                                iface_id.substr(last_pos + 1));
                         }
                     }
                 }
-                // Finally make a callback with useful data
-                callback(true, ifaceList);
-            },
-            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-    };
+            }
+            // Finally make a callback with useful data
+            callback(true, iface_list);
+        },
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
 };
 
 /**
@@ -847,19 +772,16 @@
 class EthernetCollection : public Node
 {
   public:
-    // TODO(Pawel) Remove line from below, where we assume that there is only
-    // one manager called openbmc This shall be generic, but requires to update
-    // GetSubroutes method
+    template <typename CrowApp>
     EthernetCollection(CrowApp &app) :
-        Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/")
+        Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
     {
         Node::json["@odata.type"] =
             "#EthernetInterfaceCollection.EthernetInterfaceCollection";
         Node::json["@odata.context"] =
             "/redfish/v1/"
             "$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection";
-        Node::json["@odata.id"] =
-            "/redfish/v1/Managers/openbmc/EthernetInterfaces";
+        Node::json["@odata.id"] = "/redfish/v1/Managers/bmc/EthernetInterfaces";
         Node::json["Name"] = "Ethernet Network Interface Collection";
         Node::json["Description"] =
             "Collection of EthernetInterfaces for this Manager";
@@ -880,45 +802,35 @@
     void doGet(crow::Response &res, const crow::Request &req,
                const std::vector<std::string> &params) override
     {
-        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
-        // for any Manager, not only hardcoded 'openbmc'.
-        std::string managerId = "openbmc";
-
-        // get eth interface list, and call the below callback for JSON
+        res.jsonValue = Node::json;
+        // Get eth interface list, and call the below callback for JSON
         // preparation
-        ethernetProvider.getEthernetIfaceList(
-            [&, managerId{std::move(managerId)}](
-                const bool &success,
-                const std::vector<std::string> &iface_list) {
-                if (success)
-                {
-                    nlohmann::json ifaceArray = nlohmann::json::array();
-                    for (const std::string &ifaceItem : iface_list)
-                    {
-                        ifaceArray.push_back(
-                            {{"@odata.id", "/redfish/v1/Managers/" + managerId +
-                                               "/EthernetInterfaces/" +
-                                               ifaceItem}});
-                    }
-                    Node::json["Members"] = ifaceArray;
-                    Node::json["Members@odata.count"] = ifaceArray.size();
-                    Node::json["@odata.id"] = "/redfish/v1/Managers/" +
-                                              managerId + "/EthernetInterfaces";
-                    res.jsonValue = Node::json;
-                }
-                else
-                {
-                    // No success, best what we can do is return INTERNALL ERROR
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
-                }
+        getEthernetIfaceList([&res](
+                                 const bool &success,
+                                 const std::vector<std::string> &iface_list) {
+            if (!success)
+            {
+                res.result(boost::beast::http::status::internal_server_error);
                 res.end();
-            });
-    }
+                return;
+            }
 
-    // Ethernet Provider object
-    // TODO(Pawel) consider move it to singleton
-    OnDemandEthernetProvider ethernetProvider;
+            nlohmann::json &iface_array = res.jsonValue["Members"];
+            iface_array = nlohmann::json::array();
+            for (const std::string &iface_item : iface_list)
+            {
+                iface_array.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+                          iface_item}});
+            }
+
+            res.jsonValue["Members@odata.count"] = iface_array.size();
+            res.jsonValue["@odata.id"] =
+                "/redfish/v1/Managers/bmc/EthernetInterfaces";
+            res.end();
+        });
+    }
 };
 
 /**
@@ -930,11 +842,9 @@
     /*
      * Default Constructor
      */
-    // TODO(Pawel) Remove line from below, where we assume that there is only
-    // one manager called openbmc This shall be generic, but requires to update
-    // GetSubroutes method
+    template <typename CrowApp>
     EthernetInterface(CrowApp &app) :
-        Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/",
+        Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/",
              std::string())
     {
         Node::json["@odata.type"] =
@@ -956,160 +866,141 @@
     // TODO(kkowalsk) Find a suitable class/namespace for this
     static void handleVlanPatch(const std::string &ifaceId,
                                 const nlohmann::json &input,
-                                const EthernetInterfaceData &eth_data,
-                                const std::string &pathPrefix,
-                                const std::shared_ptr<AsyncResp> &asyncResp)
+                                const EthernetInterfaceData &ethData,
+                                const std::shared_ptr<AsyncResp> asyncResp)
     {
         if (!input.is_object())
         {
             messages::addMessageToJson(
                 asyncResp->res.jsonValue,
-                messages::propertyValueTypeError(input.dump(), "VLAN"),
-                pathPrefix);
+                messages::propertyValueTypeError(input.dump(), "VLAN"), "/");
             return;
         }
 
-        const std::string pathStart = (pathPrefix == "/") ? "" : pathPrefix;
-        nlohmann::json &paramsJson =
-            (pathPrefix == "/")
-                ? asyncResp->res.jsonValue
-                : asyncResp->res
-                      .jsonValue[nlohmann::json_pointer<nlohmann::json>(
-                          pathPrefix)];
-        bool inputVlanEnabled;
-        uint64_t inputVlanId;
-
-        json_util::Result inputVlanEnabledState = json_util::getBool(
-            "VLANEnable", input, inputVlanEnabled,
-            static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-            asyncResp->res.jsonValue, std::string(pathStart + "/VLANEnable"));
-        json_util::Result inputVlanIdState = json_util::getUnsigned(
-            "VLANId", input, inputVlanId,
-            static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-            asyncResp->res.jsonValue, std::string(pathStart + "/VLANId"));
-        bool inputInvalid = false;
-
-        // Do not proceed if fields in VLAN object were of wrong type
-        if (inputVlanEnabledState == json_util::Result::WRONG_TYPE ||
-            inputVlanIdState == json_util::Result::WRONG_TYPE)
+        nlohmann::json::const_iterator vlanEnable = input.find("VLANEnable");
+        if (vlanEnable == input.end())
         {
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::propertyMissing("VLANEnable"),
+                                       "/VLANEnable");
+            return;
+        }
+        const bool *vlanEnableBool = vlanEnable->get_ptr<const bool *>();
+        if (vlanEnableBool == nullptr)
+        {
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::propertyValueTypeError(
+                                           vlanEnable->dump(), "VLANEnable"),
+                                       "/VLANEnable");
             return;
         }
 
-        // Verify input
-        if (eth_data.vlanId == nullptr)
+        nlohmann::json::const_iterator vlanId = input.find("VLANId");
+        if (vlanId == input.end())
+        {
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::propertyMissing("VLANId"),
+                                       "/VLANId");
+            return;
+        }
+        const uint64_t *vlanIdUint = vlanId->get_ptr<const uint64_t *>();
+        if (vlanIdUint == nullptr)
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(vlanId->dump(), "VLANId"),
+                "/VLANId");
+            return;
+        }
+
+        if (!ethData.vlan_id)
         {
             // This interface is not a VLAN. Cannot do anything with it
             // TODO(kkowalsk) Change this message
-            messages::addMessageToJson(asyncResp->res.jsonValue,
-                                       messages::propertyMissing("VLANEnable"),
-                                       pathPrefix);
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyNotWritable("VLANEnable"), "/VLANEnable");
 
-            inputInvalid = true;
-        }
-        else
-        {
-            // Load actual data into field values if they were not provided
-            if (inputVlanEnabledState == json_util::Result::NOT_EXIST)
-            {
-                inputVlanEnabled = true;
-            }
-
-            if (inputVlanIdState == json_util::Result::NOT_EXIST)
-            {
-                inputVlanId = *eth_data.vlanId;
-            }
-        }
-
-        // Do not proceed if input has not been valid
-        if (inputInvalid)
-        {
             return;
         }
 
         // VLAN is configured on the interface
-        if (inputVlanEnabled == true && inputVlanId != *eth_data.vlanId)
+        if (*vlanEnableBool == true)
         {
             // Change VLAN Id
-            paramsJson["VLANId"] = inputVlanId;
-            OnDemandEthernetProvider::changeVlanId(
-                ifaceId, static_cast<uint32_t>(inputVlanId),
-                [&, asyncResp, pathPrefx{std::move(pathPrefix)}](
-                    const boost::system::error_code ec) {
-                    if (ec)
-                    {
-                        messages::addMessageToJson(asyncResp->res.jsonValue,
-                                                   messages::internalError(),
-                                                   pathPrefix);
-                    }
-                    else
-                    {
-                        paramsJson["VLANEnable"] = true;
-                    }
-                });
+            asyncResp->res.jsonValue["VLANId"] = *vlanIdUint;
+            auto callback = [asyncResp](const boost::system::error_code ec) {
+                if (ec)
+                {
+                    messages::addMessageToJson(asyncResp->res.jsonValue,
+                                               messages::internalError(), "/");
+                }
+                else
+                {
+                    asyncResp->res.jsonValue["VLANEnable"] = true;
+                }
+            };
+            crow::connections::systemBus->async_method_call(
+                std::move(callback), "xyz.openbmc_project.Network",
+                "/xyz/openbmc_project/network/" + ifaceId,
+                "org.freedesktop.DBus.Properties", "Set",
+                "xyz.openbmc_project.Network.VLAN", "Id",
+                sdbusplus::message::variant<uint32_t>(*vlanIdUint));
         }
-        else if (inputVlanEnabled == false)
+        else
         {
-            // Disable VLAN
-            OnDemandEthernetProvider::disableVlan(
-                ifaceId, [&, asyncResp, pathPrefx{std::move(pathPrefix)}](
-                             const boost::system::error_code ec) {
-                    if (ec)
-                    {
-                        messages::addMessageToJson(asyncResp->res.jsonValue,
-                                                   messages::internalError(),
-                                                   pathPrefix);
-                    }
-                    else
-                    {
-                        paramsJson["VLANEnable"] = false;
-                    }
-                });
+            auto callback = [asyncResp](const boost::system::error_code ec) {
+                if (ec)
+                {
+                    messages::addMessageToJson(asyncResp->res.jsonValue,
+                                               messages::internalError(), "/");
+                    return;
+                }
+                asyncResp->res.jsonValue["VLANEnable"] = false;
+            };
+
+            crow::connections::systemBus->async_method_call(
+                std::move(callback), "xyz.openbmc_project.Network",
+                "/xyz/openbmc_project/network/" + ifaceId,
+                "xyz.openbmc_project.Object.Delete", "Delete");
         }
     }
 
   private:
     void handleHostnamePatch(const nlohmann::json &input,
-                             const EthernetInterfaceData &eth_data,
-                             const std::shared_ptr<AsyncResp> &asyncResp)
+                             const std::shared_ptr<AsyncResp> asyncResp)
     {
-        if (input.is_string())
-        {
-            std::string newHostname = input.get<std::string>();
-
-            if (eth_data.hostname == nullptr ||
-                newHostname != *eth_data.hostname)
-            {
-                // Change hostname
-                ethernetProvider.setHostName(
-                    newHostname, [asyncResp, newHostname](
-                                     const boost::system::error_code ec) {
-                        if (ec)
-                        {
-                            messages::addMessageToJson(
-                                asyncResp->res.jsonValue,
-                                messages::internalError(), "/HostName");
-                        }
-                        else
-                        {
-                            asyncResp->res.jsonValue["HostName"] = newHostname;
-                        }
-                    });
-            }
-        }
-        else
+        const std::string *newHostname = input.get_ptr<const std::string *>();
+        if (newHostname == nullptr)
         {
             messages::addMessageToJson(
                 asyncResp->res.jsonValue,
                 messages::propertyValueTypeError(input.dump(), "HostName"),
                 "/HostName");
+            return;
         }
+
+        // Change hostname
+        setHostName(
+            *newHostname, [asyncResp, newHostname{std::string(*newHostname)}](
+                              const boost::system::error_code ec) {
+                if (ec)
+                {
+                    messages::addMessageToJson(asyncResp->res.jsonValue,
+                                               messages::internalError(),
+                                               "/HostName");
+                }
+                else
+                {
+                    asyncResp->res.jsonValue["HostName"] = newHostname;
+                }
+            });
     }
 
-    void handleIPv4Patch(const std::string &ifaceId,
-                         const nlohmann::json &input,
-                         const std::vector<IPv4AddressData> &ipv4_data,
-                         const std::shared_ptr<AsyncResp> &asyncResp)
+    void handleIPv4Patch(
+        const std::string &ifaceId, const nlohmann::json &input,
+        const boost::container::flat_set<IPv4AddressData> &ipv4Data,
+        const std::shared_ptr<AsyncResp> asyncResp)
     {
         if (!input.is_array())
         {
@@ -1121,7 +1012,7 @@
         }
 
         // According to Redfish PATCH definition, size must be at least equal
-        if (input.size() < ipv4_data.size())
+        if (input.size() < ipv4Data.size())
         {
             // TODO(kkowalsk) This should be a message indicating that not
             // enough data has been provided
@@ -1131,305 +1022,338 @@
             return;
         }
 
-        json_util::Result addressFieldState;
-        json_util::Result subnetMaskFieldState;
-        json_util::Result addressOriginFieldState;
-        json_util::Result gatewayFieldState;
-        const std::string *addressFieldValue;
-        const std::string *subnetMaskFieldValue;
-        const std::string *addressOriginFieldValue = nullptr;
-        const std::string *gatewayFieldValue;
-        uint8_t subnetMaskAsPrefixLength;
-        std::string addressOriginInDBusFormat;
-
-        bool errorDetected = false;
-        for (unsigned int entryIdx = 0; entryIdx < input.size(); entryIdx++)
+        int entryIdx = 0;
+        boost::container::flat_set<IPv4AddressData>::const_iterator thisData =
+            ipv4Data.begin();
+        for (const nlohmann::json &thisJson : input)
         {
+            std::string pathString =
+                "/IPv4Addresses/" + std::to_string(entryIdx);
             // Check that entry is not of some unexpected type
-            if (!input[entryIdx].is_object() && !input[entryIdx].is_null())
+            if (!thisJson.is_object() && !thisJson.is_null())
             {
-                // Invalid object type
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue,
-                    messages::propertyValueTypeError(input[entryIdx].dump(),
-                                                     "IPv4Address"),
-                    "/IPv4Addresses/" + std::to_string(entryIdx));
+                messages::addMessageToJson(asyncResp->res.jsonValue,
+                                           messages::propertyValueTypeError(
+                                               thisJson.dump(), "IPv4Address"),
+                                           pathString);
 
                 continue;
             }
 
-            // Try to load fields
-            addressFieldState = json_util::getString(
-                "Address", input[entryIdx], addressFieldValue,
-                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-                asyncResp->res.jsonValue,
-                "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-            subnetMaskFieldState = json_util::getString(
-                "SubnetMask", input[entryIdx], subnetMaskFieldValue,
-                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-                asyncResp->res.jsonValue,
-                "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-            addressOriginFieldState = json_util::getString(
-                "AddressOrigin", input[entryIdx], addressOriginFieldValue,
-                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-                asyncResp->res.jsonValue,
-                "/IPv4Addresses/" + std::to_string(entryIdx) +
-                    "/AddressOrigin");
-            gatewayFieldState = json_util::getString(
-                "Gateway", input[entryIdx], gatewayFieldValue,
-                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-                asyncResp->res.jsonValue,
-                "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-
-            if (addressFieldState == json_util::Result::WRONG_TYPE ||
-                subnetMaskFieldState == json_util::Result::WRONG_TYPE ||
-                addressOriginFieldState == json_util::Result::WRONG_TYPE ||
-                gatewayFieldState == json_util::Result::WRONG_TYPE)
+            nlohmann::json::const_iterator addressFieldIt =
+                thisJson.find("Address");
+            const std::string *addressField = nullptr;
+            if (addressFieldIt != thisJson.end())
             {
-                return;
-            }
-
-            if (addressFieldState == json_util::Result::SUCCESS &&
-                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
-                    *addressFieldValue))
-            {
-                errorDetected = true;
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue,
-                    messages::propertyValueFormatError(*addressFieldValue,
-                                                       "Address"),
-                    "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-            }
-
-            if (subnetMaskFieldState == json_util::Result::SUCCESS &&
-                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
-                    *subnetMaskFieldValue, &subnetMaskAsPrefixLength))
-            {
-                errorDetected = true;
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue,
-                    messages::propertyValueFormatError(*subnetMaskFieldValue,
-                                                       "SubnetMask"),
-                    "/IPv4Addresses/" + std::to_string(entryIdx) +
-                        "/SubnetMask");
-            }
-
-            // get Address origin in proper format
-            addressOriginInDBusFormat =
-                ethernetProvider.translateAddressOriginBetweenDBusAndRedfish(
-                    addressOriginFieldValue, true, false);
-
-            if (addressOriginFieldState == json_util::Result::SUCCESS &&
-                addressOriginInDBusFormat.empty())
-            {
-                errorDetected = true;
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue,
-                    messages::propertyValueNotInList(*addressOriginFieldValue,
-                                                     "AddressOrigin"),
-                    "/IPv4Addresses/" + std::to_string(entryIdx) +
-                        "/AddressOrigin");
-            }
-
-            if (gatewayFieldState == json_util::Result::SUCCESS &&
-                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
-                    *gatewayFieldValue))
-            {
-                errorDetected = true;
-                messages::addMessageToJson(
-                    asyncResp->res.jsonValue,
-                    messages::propertyValueFormatError(*gatewayFieldValue,
-                                                       "Gateway"),
-                    "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-            }
-
-            // If any error occured do not proceed with current entry, but do
-            // not end loop
-            if (errorDetected)
-            {
-                errorDetected = false;
-                continue;
-            }
-
-            if (entryIdx >= ipv4_data.size())
-            {
-                asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] =
-                    input[entryIdx];
-
-                // Verify that all field were provided
-                if (addressFieldState == json_util::Result::NOT_EXIST)
+                addressField = addressFieldIt->get_ptr<const std::string *>();
+                if (addressField == nullptr)
                 {
-                    errorDetected = true;
                     messages::addMessageToJson(
                         asyncResp->res.jsonValue,
-                        messages::propertyMissing("Address"),
-                        "/IPv4Addresses/" + std::to_string(entryIdx) +
-                            "/Address");
-                }
-
-                if (subnetMaskFieldState == json_util::Result::NOT_EXIST)
-                {
-                    errorDetected = true;
-                    messages::addMessageToJson(
-                        asyncResp->res.jsonValue,
-                        messages::propertyMissing("SubnetMask"),
-                        "/IPv4Addresses/" + std::to_string(entryIdx) +
-                            "/SubnetMask");
-                }
-
-                if (addressOriginFieldState == json_util::Result::NOT_EXIST)
-                {
-                    errorDetected = true;
-                    messages::addMessageToJson(
-                        asyncResp->res.jsonValue,
-                        messages::propertyMissing("AddressOrigin"),
-                        "/IPv4Addresses/" + std::to_string(entryIdx) +
-                            "/AddressOrigin");
-                }
-
-                if (gatewayFieldState == json_util::Result::NOT_EXIST)
-                {
-                    errorDetected = true;
-                    messages::addMessageToJson(
-                        asyncResp->res.jsonValue,
-                        messages::propertyMissing("Gateway"),
-                        "/IPv4Addresses/" + std::to_string(entryIdx) +
-                            "/Gateway");
-                }
-
-                // If any error occured do not proceed with current entry, but
-                // do not end loop
-                if (errorDetected)
-                {
-                    errorDetected = false;
+                        messages::propertyValueFormatError(
+                            addressFieldIt->dump(), "Address"),
+                        pathString + "/Address");
                     continue;
                 }
-
-                // Create IPv4 with provided data
-                ethernetProvider.createIPv4(
-                    ifaceId, entryIdx, subnetMaskAsPrefixLength,
-                    *gatewayFieldValue, *addressFieldValue, asyncResp);
+                else
+                {
+                    if (!ipv4VerifyIpAndGetBitcount(*addressField))
+                    {
+                        messages::addMessageToJson(
+                            asyncResp->res.jsonValue,
+                            messages::propertyValueFormatError(*addressField,
+                                                               "Address"),
+                            pathString + "/Address");
+                        continue;
+                    }
+                }
             }
-            else
+
+            boost::optional<uint8_t> prefixLength;
+            const std::string *subnetField = nullptr;
+            nlohmann::json::const_iterator subnetFieldIt =
+                thisJson.find("SubnetMask");
+            if (subnetFieldIt != thisJson.end())
+            {
+                subnetField = subnetFieldIt->get_ptr<const std::string *>();
+                if (subnetField == nullptr)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyValueFormatError(*subnetField,
+                                                           "SubnetMask"),
+                        pathString + "/SubnetMask");
+                    continue;
+                }
+                else
+                {
+                    prefixLength = 0;
+                    if (!ipv4VerifyIpAndGetBitcount(*subnetField,
+                                                    &*prefixLength))
+                    {
+                        messages::addMessageToJson(
+                            asyncResp->res.jsonValue,
+                            messages::propertyValueFormatError(*subnetField,
+                                                               "SubnetMask"),
+                            pathString + "/SubnetMask");
+                        continue;
+                    }
+                }
+            }
+
+            std::string addressOriginInDBusFormat;
+            const std::string *addressOriginField = nullptr;
+            nlohmann::json::const_iterator addressOriginFieldIt =
+                thisJson.find("AddressOrigin");
+            if (addressOriginFieldIt != thisJson.end())
+            {
+                const std::string *addressOriginField =
+                    addressOriginFieldIt->get_ptr<const std::string *>();
+                if (addressOriginField == nullptr)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyValueFormatError(*addressOriginField,
+                                                           "AddressOrigin"),
+                        pathString + "/AddressOrigin");
+                    continue;
+                }
+                else
+                {
+                    // Get Address origin in proper format
+                    addressOriginInDBusFormat =
+                        translateAddressOriginRedfishToDbus(
+                            *addressOriginField);
+                    if (addressOriginInDBusFormat.empty())
+                    {
+                        messages::addMessageToJson(
+                            asyncResp->res.jsonValue,
+                            messages::propertyValueNotInList(
+                                *addressOriginField, "AddressOrigin"),
+                            pathString + "/AddressOrigin");
+                        continue;
+                    }
+                }
+            }
+
+            nlohmann::json::const_iterator gatewayFieldIt =
+                thisJson.find("Gateway");
+            const std::string *gatewayField = nullptr;
+            if (gatewayFieldIt != thisJson.end())
+            {
+                const std::string *gatewayField =
+                    gatewayFieldIt->get_ptr<const std::string *>();
+                if (gatewayField == nullptr ||
+                    !ipv4VerifyIpAndGetBitcount(*gatewayField))
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyValueFormatError(*gatewayField,
+                                                           "Gateway"),
+                        pathString + "/Gateway");
+                    continue;
+                }
+            }
+
+            // if a vlan already exists, modify the existing
+            if (thisData != ipv4Data.end())
             {
                 // Existing object that should be modified/deleted/remain
                 // unchanged
-                if (input[entryIdx].is_null())
+                if (thisJson.is_null())
                 {
-                    // Object should be deleted
-                    ethernetProvider.deleteIPv4(ifaceId, ipv4_data[entryIdx].id,
-                                                entryIdx, asyncResp);
+                    auto callback = [entryIdx{std::to_string(entryIdx)},
+                                     asyncResp](
+                                        const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            messages::addMessageToJson(
+                                asyncResp->res.jsonValue,
+                                messages::internalError(),
+                                "/IPv4Addresses/" + entryIdx + "/");
+                            return;
+                        }
+                        asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] =
+                            nullptr;
+                    };
+                    crow::connections::systemBus->async_method_call(
+                        std::move(callback), "xyz.openbmc_project.Network",
+                        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" +
+                            thisData->id,
+                        "xyz.openbmc_project.Object.Delete", "Delete");
                 }
-                else if (input[entryIdx].is_object())
+                else if (thisJson.is_object())
                 {
-                    if (input[entryIdx].size() == 0)
-                    {
-                        // Object shall remain unchanged
-                        continue;
-                    }
-
                     // Apply changes
-                    if (addressFieldState == json_util::Result::SUCCESS &&
-                        ipv4_data[entryIdx].address != nullptr &&
-                        *ipv4_data[entryIdx].address != *addressFieldValue)
+                    if (addressField != nullptr)
                     {
-                        ethernetProvider.changeIPv4AddressProperty(
-                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                            "Address", *addressFieldValue, asyncResp);
+                        auto callback =
+                            [asyncResp, entryIdx,
+                             addressField{std::string(*addressField)}](
+                                const boost::system::error_code ec) {
+                                if (ec)
+                                {
+                                    messages::addMessageToJson(
+                                        asyncResp->res.jsonValue,
+                                        messages::internalError(),
+                                        "/IPv4Addresses/" +
+                                            std::to_string(entryIdx) +
+                                            "/Address");
+                                    return;
+                                }
+                                asyncResp->res
+                                    .jsonValue["IPv4Addresses"][std::to_string(
+                                        entryIdx)]["Address"] = addressField;
+                            };
+
+                        crow::connections::systemBus->async_method_call(
+                            std::move(callback), "xyz.openbmc_project.Network",
+                            "/xyz/openbmc_project/network/" + ifaceId +
+                                "/ipv4/" + thisData->id,
+                            "org.freedesktop.DBus.Properties", "Set",
+                            "xyz.openbmc_project.Network.IP", "Address",
+                            sdbusplus::message::variant<std::string>(
+                                *addressField));
                     }
 
-                    if (subnetMaskFieldState == json_util::Result::SUCCESS &&
-                        ipv4_data[entryIdx].netmask != *subnetMaskFieldValue)
+                    if (prefixLength && subnetField != nullptr)
                     {
-                        ethernetProvider.changeIPv4SubnetMaskProperty(
-                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                            *subnetMaskFieldValue, subnetMaskAsPrefixLength,
-                            asyncResp);
+                        changeIPv4SubnetMaskProperty(ifaceId, entryIdx,
+                                                     thisData->id, *subnetField,
+                                                     *prefixLength, asyncResp);
                     }
 
-                    if (addressOriginFieldState == json_util::Result::SUCCESS &&
-                        ipv4_data[entryIdx].origin != *addressFieldValue)
+                    if (!addressOriginInDBusFormat.empty() &&
+                        addressOriginField != nullptr)
                     {
-                        ethernetProvider.changeIPv4Origin(
-                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                            *addressOriginFieldValue, addressOriginInDBusFormat,
-                            asyncResp);
+                        changeIPv4Origin(ifaceId, entryIdx, thisData->id,
+                                         *addressOriginField,
+                                         addressOriginInDBusFormat, asyncResp);
                     }
 
-                    if (gatewayFieldState == json_util::Result::SUCCESS &&
-                        ipv4_data[entryIdx].gateway != nullptr &&
-                        *ipv4_data[entryIdx].gateway != *gatewayFieldValue)
+                    if (gatewayField != nullptr)
                     {
-                        ethernetProvider.changeIPv4AddressProperty(
-                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                            "Gateway", *gatewayFieldValue, asyncResp);
+                        auto callback =
+                            [asyncResp, entryIdx,
+                             gatewayField{std::string(*gatewayField)}](
+                                const boost::system::error_code ec) {
+                                if (ec)
+                                {
+                                    messages::addMessageToJson(
+                                        asyncResp->res.jsonValue,
+                                        messages::internalError(),
+                                        "/IPv4Addresses/" +
+                                            std::to_string(entryIdx) +
+                                            "/Gateway");
+                                    return;
+                                }
+                                asyncResp->res
+                                    .jsonValue["IPv4Addresses"][std::to_string(
+                                        entryIdx)]["Gateway"] =
+                                    std::move(gatewayField);
+                            };
+
+                        crow::connections::systemBus->async_method_call(
+                            std::move(callback), "xyz.openbmc_project.Network",
+                            "/xyz/openbmc_project/network/" + ifaceId +
+                                "/ipv4/" + thisData->id,
+                            "org.freedesktop.DBus.Properties", "Set",
+                            "xyz.openbmc_project.Network.IP", "Gateway",
+                            sdbusplus::message::variant<std::string>(
+                                *gatewayField));
                     }
                 }
+                thisData++;
             }
+            else
+            {
+                // Create IPv4 with provided data
+                if (gatewayField == nullptr)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("Gateway"),
+                        pathString + "/Gateway");
+                    continue;
+                }
+
+                if (addressField == nullptr)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("Address"),
+                        pathString + "/Address");
+                    continue;
+                }
+
+                if (!prefixLength)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("SubnetMask"),
+                        pathString + "/SubnetMask");
+                    continue;
+                }
+
+                createIPv4(ifaceId, entryIdx, *prefixLength, *gatewayField,
+                           *addressField, asyncResp);
+                asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] = thisJson;
+            }
+            entryIdx++;
         }
     }
 
-    nlohmann::json
-        parseInterfaceData(const std::string &ifaceId,
-                           const EthernetInterfaceData &eth_data,
-                           const std::vector<IPv4AddressData> &ipv4_data)
+    nlohmann::json parseInterfaceData(
+        const std::string &iface_id, const EthernetInterfaceData &ethData,
+        const boost::container::flat_set<IPv4AddressData> &ipv4Data)
     {
         // Copy JSON object to avoid race condition
-        nlohmann::json jsonResponse(Node::json);
+        nlohmann::json json_response(Node::json);
 
-        // Fill out obvious data...
-        jsonResponse["Id"] = ifaceId;
-        jsonResponse["@odata.id"] =
-            "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId;
+        json_response["Id"] = iface_id;
+        json_response["@odata.id"] =
+            "/redfish/v1/Managers/bmc/EthernetInterfaces/" + iface_id;
 
-        // ... then the one from DBus, regarding eth iface...
-        if (eth_data.speed != nullptr)
-            jsonResponse["SpeedMbps"] = *eth_data.speed;
-
-        if (eth_data.macAddress != nullptr)
-            jsonResponse["MACAddress"] = *eth_data.macAddress;
-
-        if (eth_data.hostname != nullptr)
-            jsonResponse["HostName"] = *eth_data.hostname;
-
-        if (eth_data.vlanId != nullptr)
+        json_response["SpeedMbps"] = ethData.speed;
+        json_response["MACAddress"] = ethData.mac_address;
+        if (!ethData.hostname.empty())
         {
-            nlohmann::json &vlanObj = jsonResponse["VLAN"];
+            json_response["HostName"] = ethData.hostname;
+        }
+
+        nlohmann::json &vlanObj = json_response["VLAN"];
+        if (ethData.vlan_id)
+        {
             vlanObj["VLANEnable"] = true;
-            vlanObj["VLANId"] = *eth_data.vlanId;
+            vlanObj["VLANId"] = *ethData.vlan_id;
         }
         else
         {
-            nlohmann::json &vlanObj = jsonResponse["VLANs"];
-            vlanObj["@odata.id"] =
-                "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId +
-                "/VLANs";
+            vlanObj["VLANEnable"] = false;
+            vlanObj["VLANId"] = 0;
         }
 
-        // ... at last, check if there are IPv4 data and prepare appropriate
-        // collection
-        if (ipv4_data.size() > 0)
+        if (ipv4Data.size() > 0)
         {
-            nlohmann::json ipv4Array = nlohmann::json::array();
-            for (auto &ipv4Config : ipv4_data)
+            nlohmann::json &ipv4_array = json_response["IPv4Addresses"];
+            ipv4_array = nlohmann::json::array();
+            for (auto &ipv4_config : ipv4Data)
             {
-                nlohmann::json jsonIpv4;
-                if (ipv4Config.address != nullptr)
+                if (!ipv4_config.address.empty())
                 {
-                    jsonIpv4["Address"] = *ipv4Config.address;
-                    if (ipv4Config.gateway != nullptr)
-                        jsonIpv4["Gateway"] = *ipv4Config.gateway;
+                    ipv4_array.push_back({{"AddressOrigin", ipv4_config.origin},
+                                          {"SubnetMask", ipv4_config.netmask},
+                                          {"Address", ipv4_config.address}});
 
-                    jsonIpv4["AddressOrigin"] = ipv4Config.origin;
-                    jsonIpv4["SubnetMask"] = ipv4Config.netmask;
-
-                    ipv4Array.push_back(std::move(jsonIpv4));
+                    if (!ipv4_config.gateway.empty())
+                    {
+                        ipv4_array.back()["Gateway"] = ipv4_config.gateway;
+                    }
                 }
             }
-            jsonResponse["IPv4Addresses"] = std::move(ipv4Array);
         }
 
-        return jsonResponse;
+        return json_response;
     }
 
     /**
@@ -1438,153 +1362,132 @@
     void doGet(crow::Response &res, const crow::Request &req,
                const std::vector<std::string> &params) override
     {
-        // TODO(Pawel) this shall be parametrized call (two params) to get
-        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-        // Check if there is required param, truly entering this shall be
-        // impossible.
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         if (params.size() != 1)
         {
-            res.result(boost::beast::http::status::internal_server_error);
-            res.end();
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
             return;
         }
 
-        const std::string &ifaceId = params[0];
-
-        // get single eth interface data, and call the below callback for JSON
-        // preparation
-        ethernetProvider.getEthernetIfaceData(
-            ifaceId,
-            [&, ifaceId](const bool &success,
-                         const EthernetInterfaceData &eth_data,
-                         const std::vector<IPv4AddressData> &ipv4_data) {
-                if (success)
+        getEthernetIfaceData(
+            params[0],
+            [this, asyncResp, iface_id{std::string(params[0])}](
+                const bool &success, const EthernetInterfaceData &ethData,
+                const boost::container::flat_set<IPv4AddressData> &ipv4Data) {
+                if (!success)
                 {
-                    res.jsonValue =
-                        parseInterfaceData(ifaceId, eth_data, ipv4_data);
-                }
-                else
-                {
-                    // ... otherwise return error
                     // TODO(Pawel)consider distinguish between non existing
                     // object, and other errors
                     messages::addMessageToErrorJson(
-                        res.jsonValue, messages::resourceNotFound(
-                                           "EthernetInterface", ifaceId));
-                    res.result(boost::beast::http::status::not_found);
+                        asyncResp->res.jsonValue,
+                        messages::resourceNotFound("EthernetInterface",
+                                                   iface_id));
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
                 }
-                res.end();
+                asyncResp->res.jsonValue =
+                    parseInterfaceData(iface_id, ethData, ipv4Data);
             });
     }
 
     void doPatch(crow::Response &res, const crow::Request &req,
                  const std::vector<std::string> &params) override
     {
-        // TODO(Pawel) this shall be parametrized call (two params) to get
-        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-        // Check if there is required param, truly entering this shall be
-        // impossible.
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         if (params.size() != 1)
         {
             res.result(boost::beast::http::status::internal_server_error);
-            res.end();
             return;
         }
 
-        const std::string &ifaceId = params[0];
+        const std::string &iface_id = params[0];
 
         nlohmann::json patchReq;
-
         if (!json_util::processJsonFromRequest(res, req, patchReq))
         {
             return;
         }
 
-        // get single eth interface data, and call the below callback for JSON
+        // Get single eth interface data, and call the below callback for JSON
         // preparation
-        ethernetProvider.getEthernetIfaceData(
-            ifaceId,
-            [&, ifaceId, patchReq = std::move(patchReq)](
-                const bool &success, const EthernetInterfaceData &eth_data,
-                const std::vector<IPv4AddressData> &ipv4_data) {
+        getEthernetIfaceData(
+            iface_id,
+            [this, asyncResp, iface_id, patchReq = std::move(patchReq)](
+                const bool &success, const EthernetInterfaceData &ethData,
+                const boost::container::flat_set<IPv4AddressData> &ipv4Data) {
                 if (!success)
                 {
                     // ... otherwise return error
                     // TODO(Pawel)consider distinguish between non existing
                     // object, and other errors
                     messages::addMessageToErrorJson(
-                        res.jsonValue, messages::resourceNotFound(
-                                           "VLAN Network Interface", ifaceId));
-                    res.result(boost::beast::http::status::not_found);
-                    res.end();
+                        asyncResp->res.jsonValue,
+                        messages::resourceNotFound("VLAN Network Interface",
+                                                   iface_id));
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    asyncResp->res.end();
 
                     return;
                 }
 
-                res.jsonValue =
-                    parseInterfaceData(ifaceId, eth_data, ipv4_data);
+                asyncResp->res.jsonValue =
+                    parseInterfaceData(iface_id, ethData, ipv4Data);
 
-                std::shared_ptr<AsyncResp> asyncResp =
-                    std::make_shared<AsyncResp>(res);
-
-                for (auto propertyIt = patchReq.begin();
-                     propertyIt != patchReq.end(); ++propertyIt)
+                for (auto propertyIt : patchReq.items())
                 {
                     if (propertyIt.key() == "VLAN")
                     {
-                        handleVlanPatch(ifaceId, propertyIt.value(), eth_data,
-                                        "/VLAN", asyncResp);
+                        handleVlanPatch(iface_id, propertyIt.value(), ethData,
+                                        asyncResp);
                     }
                     else if (propertyIt.key() == "HostName")
                     {
-                        handleHostnamePatch(propertyIt.value(), eth_data,
-                                            asyncResp);
+                        handleHostnamePatch(propertyIt.value(), asyncResp);
                     }
                     else if (propertyIt.key() == "IPv4Addresses")
                     {
-                        handleIPv4Patch(ifaceId, propertyIt.value(), ipv4_data,
+                        handleIPv4Patch(iface_id, propertyIt.value(), ipv4Data,
                                         asyncResp);
                     }
                     else if (propertyIt.key() == "IPv6Addresses")
                     {
                         // TODO(kkowalsk) IPv6 Not supported on D-Bus yet
                         messages::addMessageToJsonRoot(
-                            res.jsonValue,
+                            asyncResp->res.jsonValue,
                             messages::propertyNotWritable(propertyIt.key()));
                     }
                     else
                     {
                         auto fieldInJsonIt =
-                            res.jsonValue.find(propertyIt.key());
+                            asyncResp->res.jsonValue.find(propertyIt.key());
 
-                        if (fieldInJsonIt == res.jsonValue.end())
+                        if (fieldInJsonIt == asyncResp->res.jsonValue.end())
                         {
                             // Field not in scope of defined fields
                             messages::addMessageToJsonRoot(
-                                res.jsonValue,
+                                asyncResp->res.jsonValue,
                                 messages::propertyUnknown(propertyIt.key()));
                         }
-                        else if (*fieldInJsonIt != *propertyIt)
+                        else
                         {
                             // User attempted to modify non-writable field
                             messages::addMessageToJsonRoot(
-                                res.jsonValue, messages::propertyNotWritable(
-                                                   propertyIt.key()));
+                                asyncResp->res.jsonValue,
+                                messages::propertyNotWritable(
+                                    propertyIt.key()));
                         }
                     }
                 }
             });
     }
-
-    // Ethernet Provider object
-    // TODO(Pawel) consider move it to singleton
-    OnDemandEthernetProvider ethernetProvider;
 };
 
-class VlanNetworkInterfaceCollection;
-
 /**
- * VlanNetworkInterface derived class for delivering VLANNetworkInterface Schema
+ * VlanNetworkInterface derived class for delivering VLANNetworkInterface
+ * Schema
  */
 class VlanNetworkInterface : public Node
 {
@@ -1594,13 +1497,13 @@
      */
     template <typename CrowApp>
     // TODO(Pawel) Remove line from below, where we assume that there is only
-    // one manager called openbmc This shall be generic, but requires to update
-    // GetSubroutes method
+    // one manager called openbmc.  This shall be generic, but requires to
+    // update GetSubroutes method
     VlanNetworkInterface(CrowApp &app) :
-        Node(
-            app,
-            "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/<str>",
-            std::string(), std::string())
+        Node(app,
+             "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>>/VLANs/"
+             "<str>",
+             std::string(), std::string())
     {
         Node::json["@odata.type"] =
             "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
@@ -1618,25 +1521,26 @@
     }
 
   private:
-    nlohmann::json
-        parseInterfaceData(const std::string &parent_ifaceId,
-                           const std::string &ifaceId,
-                           const EthernetInterfaceData &eth_data,
-                           const std::vector<IPv4AddressData> &ipv4_data)
+    nlohmann::json parseInterfaceData(
+        const std::string &parent_iface_id, const std::string &iface_id,
+        const EthernetInterfaceData &ethData,
+        const boost::container::flat_set<IPv4AddressData> &ipv4Data)
     {
         // Copy JSON object to avoid race condition
-        nlohmann::json jsonResponse(Node::json);
+        nlohmann::json json_response(Node::json);
 
         // Fill out obvious data...
-        jsonResponse["Id"] = ifaceId;
-        jsonResponse["@odata.id"] =
-            "/redfish/v1/Managers/openbmc/EthernetInterfaces/" +
-            parent_ifaceId + "/VLANs/" + ifaceId;
+        json_response["Id"] = iface_id;
+        json_response["@odata.id"] =
+            "/redfish/v1/Managers/bmc/EthernetInterfaces/" + parent_iface_id +
+            "/VLANs/" + iface_id;
 
-        jsonResponse["VLANEnable"] = true;
-        jsonResponse["VLANId"] = *eth_data.vlanId;
-
-        return jsonResponse;
+        json_response["VLANEnable"] = true;
+        if (ethData.vlan_id)
+        {
+            json_response["VLANId"] = *ethData.vlan_id;
+        }
+        return json_response;
     }
 
     bool verifyNames(crow::Response &res, const std::string &parent,
@@ -1664,7 +1568,8 @@
     void doGet(crow::Response &res, const crow::Request &req,
                const std::vector<std::string> &params) override
     {
-        // TODO(Pawel) this shall be parametrized call (two params) to get
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
+        // TODO(Pawel) this shall be parameterized call (two params) to get
         // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
         // Check if there is required param, truly entering this shall be
         // impossible.
@@ -1675,25 +1580,25 @@
             return;
         }
 
-        const std::string &parentIfaceId = params[0];
-        const std::string &ifaceId = params[1];
+        const std::string &parent_iface_id = params[0];
+        const std::string &iface_id = params[1];
 
-        if (!verifyNames(res, parentIfaceId, ifaceId))
+        if (!verifyNames(res, parent_iface_id, iface_id))
         {
             return;
         }
 
         // Get single eth interface data, and call the below callback for JSON
         // preparation
-        ethernetProvider.getEthernetIfaceData(
-            ifaceId, [&, parentIfaceId,
-                      ifaceId](const bool &success,
-                               const EthernetInterfaceData &eth_data,
-                               const std::vector<IPv4AddressData> &ipv4_data) {
-                if (success && eth_data.vlanId != nullptr)
+        getEthernetIfaceData(
+            iface_id,
+            [this, asyncResp, parent_iface_id, iface_id](
+                const bool &success, const EthernetInterfaceData &ethData,
+                const boost::container::flat_set<IPv4AddressData> &ipv4Data) {
+                if (success && ethData.vlan_id)
                 {
-                    res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
-                                                       eth_data, ipv4_data);
+                    asyncResp->res.jsonValue = parseInterfaceData(
+                        parent_iface_id, iface_id, ethData, ipv4Data);
                 }
                 else
                 {
@@ -1701,21 +1606,23 @@
                     // TODO(Pawel)consider distinguish between non existing
                     // object, and other errors
                     messages::addMessageToErrorJson(
-                        res.jsonValue, messages::resourceNotFound(
-                                           "VLAN Network Interface", ifaceId));
-                    res.result(boost::beast::http::status::not_found);
+                        asyncResp->res.jsonValue,
+                        messages::resourceNotFound("VLAN Network Interface",
+                                                   iface_id));
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
                 }
-                res.end();
             });
     }
 
     void doPatch(crow::Response &res, const crow::Request &req,
                  const std::vector<std::string> &params) override
     {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         if (params.size() != 2)
         {
-            res.result(boost::beast::http::status::internal_server_error);
-            res.end();
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
             return;
         }
 
@@ -1728,7 +1635,6 @@
         }
 
         nlohmann::json patchReq;
-
         if (!json_util::processJsonFromRequest(res, req, patchReq))
         {
             return;
@@ -1736,131 +1642,125 @@
 
         // Get single eth interface data, and call the below callback for JSON
         // preparation
-        ethernetProvider.getEthernetIfaceData(
+        getEthernetIfaceData(
             ifaceId,
-            [&, parentIfaceId, ifaceId, patchReq = std::move(patchReq)](
-                const bool &success, const EthernetInterfaceData &eth_data,
-                const std::vector<IPv4AddressData> &ipv4_data) {
+            [this, asyncResp, parentIfaceId, ifaceId,
+             patchReq{std::move(patchReq)}](
+                const bool &success, const EthernetInterfaceData &ethData,
+                const boost::container::flat_set<IPv4AddressData> &ipv4Data) {
                 if (!success)
                 {
-                    // ... otherwise return error
                     // TODO(Pawel)consider distinguish between non existing
                     // object, and other errors
                     messages::addMessageToErrorJson(
-                        res.jsonValue, messages::resourceNotFound(
-                                           "VLAN Network Interface", ifaceId));
-                    res.result(boost::beast::http::status::not_found);
-                    res.end();
+                        asyncResp->res.jsonValue,
+                        messages::resourceNotFound("VLAN Network Interface",
+                                                   ifaceId));
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    asyncResp->res.end();
 
                     return;
                 }
 
-                res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
-                                                   eth_data, ipv4_data);
+                asyncResp->res.jsonValue = parseInterfaceData(
+                    parentIfaceId, ifaceId, ethData, ipv4Data);
 
-                std::shared_ptr<AsyncResp> asyncResp =
-                    std::make_shared<AsyncResp>(res);
-
-                for (auto propertyIt = patchReq.begin();
-                     propertyIt != patchReq.end(); ++propertyIt)
+                for (auto propertyIt : patchReq.items())
                 {
                     if (propertyIt.key() != "VLANEnable" &&
                         propertyIt.key() != "VLANId")
                     {
                         auto fieldInJsonIt =
-                            res.jsonValue.find(propertyIt.key());
-
-                        if (fieldInJsonIt == res.jsonValue.end())
+                            asyncResp->res.jsonValue.find(propertyIt.key());
+                        if (fieldInJsonIt == asyncResp->res.jsonValue.end())
                         {
                             // Field not in scope of defined fields
                             messages::addMessageToJsonRoot(
-                                res.jsonValue,
+                                asyncResp->res.jsonValue,
                                 messages::propertyUnknown(propertyIt.key()));
                         }
-                        else if (*fieldInJsonIt != *propertyIt)
+                        else
                         {
                             // User attempted to modify non-writable field
                             messages::addMessageToJsonRoot(
-                                res.jsonValue, messages::propertyNotWritable(
-                                                   propertyIt.key()));
+                                asyncResp->res.jsonValue,
+                                messages::propertyNotWritable(
+                                    propertyIt.key()));
                         }
                     }
                 }
 
-                EthernetInterface::handleVlanPatch(ifaceId, patchReq, eth_data,
-                                                   "/", asyncResp);
+                EthernetInterface::handleVlanPatch(ifaceId, patchReq, ethData,
+                                                   asyncResp);
             });
     }
 
     void doDelete(crow::Response &res, const crow::Request &req,
                   const std::vector<std::string> &params) override
     {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         if (params.size() != 2)
         {
-            res.result(boost::beast::http::status::internal_server_error);
-            res.end();
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
             return;
         }
 
         const std::string &parentIfaceId = params[0];
         const std::string &ifaceId = params[1];
 
-        if (!verifyNames(res, parentIfaceId, ifaceId))
+        if (!verifyNames(asyncResp->res, parentIfaceId, ifaceId))
         {
             return;
         }
 
         // Get single eth interface data, and call the below callback for JSON
         // preparation
-        ethernetProvider.getEthernetIfaceData(
-            ifaceId, [&, parentIfaceId,
-                      ifaceId](const bool &success,
-                               const EthernetInterfaceData &eth_data,
-                               const std::vector<IPv4AddressData> &ipv4_data) {
-                if (success && eth_data.vlanId != nullptr)
-                {
-                    res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
-                                                       eth_data, ipv4_data);
+        getEthernetIfaceData(ifaceId, [this, asyncResp,
+                                       parentIfaceId{
+                                           std::string(parentIfaceId)},
+                                       ifaceId{std::string(ifaceId)}](
+                                          const bool &success,
+                                          const EthernetInterfaceData &ethData,
+                                          const boost::container::flat_set<
+                                              IPv4AddressData> &ipv4Data) {
+            if (success && ethData.vlan_id)
+            {
+                asyncResp->res.jsonValue = parseInterfaceData(
+                    parentIfaceId, ifaceId, ethData, ipv4Data);
 
-                    // Disable VLAN
-                    OnDemandEthernetProvider::disableVlan(
-                        ifaceId, [&](const boost::system::error_code ec) {
-                            if (ec)
-                            {
-                                res.jsonValue = nlohmann::json::object();
-                                messages::addMessageToErrorJson(
-                                    res.jsonValue, messages::internalError());
-                                res.result(boost::beast::http::status::
-                                               internal_server_error);
-                            }
-                            res.end();
-                        });
-                }
-                else
-                {
-                    // ... otherwise return error
-                    // TODO(Pawel)consider distinguish between non existing
-                    // object, and other errors
-                    messages::addMessageToErrorJson(
-                        res.jsonValue, messages::resourceNotFound(
-                                           "VLAN Network Interface", ifaceId));
-                    res.result(boost::beast::http::status::not_found);
-                    res.end();
-                }
-            });
+                auto callback = [asyncResp](
+                                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        messages::addMessageToErrorJson(
+                            asyncResp->res.jsonValue,
+                            messages::internalError());
+                        asyncResp->res.result(
+                            boost::beast::http::status::internal_server_error);
+                    }
+                };
+                crow::connections::systemBus->async_method_call(
+                    std::move(callback), "xyz.openbmc_project.Network",
+                    std::string("/xyz/openbmc_project/network/") + ifaceId,
+                    "xyz.openbmc_project.Object.Delete", "Delete");
+            }
+            else
+            {
+                // ... otherwise return error
+                // TODO(Pawel)consider distinguish between non existing object,
+                // and
+                // other errors
+                messages::addMessageToErrorJson(
+                    asyncResp->res.jsonValue,
+                    messages::resourceNotFound("VLAN Network Interface",
+                                               ifaceId));
+                asyncResp->res.result(boost::beast::http::status::not_found);
+                asyncResp->res.end();
+            }
+        });
     }
-
-    /**
-     * This allows VlanNetworkInterfaceCollection to reuse this class' doGet
-     * method, to maintain consistency of returned data, as Collection's doPost
-     * should return data for created member which should match member's doGet
-     * result in 100%.
-     */
-    friend VlanNetworkInterfaceCollection;
-
-    // Ethernet Provider object
-    // TODO(Pawel) consider move it to singleton
-    OnDemandEthernetProvider ethernetProvider;
 };
 
 /**
@@ -1872,13 +1772,11 @@
   public:
     template <typename CrowApp>
     // TODO(Pawel) Remove line from below, where we assume that there is only
-    // one manager called openbmc This shall be generic, but requires to update
-    // GetSubroutes method
+    // one manager called openbmc.  This shall be generic, but requires to
+    // update GetSubroutes method
     VlanNetworkInterfaceCollection(CrowApp &app) :
-        Node(app,
-             "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/",
-             std::string()),
-        memberVlan(app)
+        Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/",
+             std::string())
     {
         Node::json["@odata.type"] =
             "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
@@ -1903,182 +1801,118 @@
     void doGet(crow::Response &res, const crow::Request &req,
                const std::vector<std::string> &params) override
     {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         if (params.size() != 1)
         {
             // This means there is a problem with the router
-            res.result(boost::beast::http::status::internal_server_error);
-            res.end();
-
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
             return;
         }
 
-        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
-        // for any Manager, not only hardcoded 'openbmc'.
-        std::string managerId = "openbmc";
-        std::string rootInterfaceName = params[0];
+        const std::string &rootInterfaceName = params[0];
 
-        // get eth interface list, and call the below callback for JSON
+        // Get eth interface list, and call the below callback for JSON
         // preparation
-        ethernetProvider.getEthernetIfaceList(
-            [&, managerId{std::move(managerId)},
-             rootInterfaceName{std::move(rootInterfaceName)}](
-                const bool &success,
-                const std::vector<std::string> &iface_list) {
-                if (success)
-                {
-                    bool rootInterfaceFound = false;
-                    nlohmann::json ifaceArray = nlohmann::json::array();
+        getEthernetIfaceList([this, asyncResp,
+                              rootInterfaceName{
+                                  std::string(rootInterfaceName)}](
+                                 const bool &success,
+                                 const std::vector<std::string> &iface_list) {
+            if (!success)
+            {
+                asyncResp->res.result(
+                    boost::beast::http::status::internal_server_error);
+                return;
+            }
+            asyncResp->res.jsonValue = Node::json;
 
-                    for (const std::string &ifaceItem : iface_list)
-                    {
-                        if (ifaceItem == rootInterfaceName)
-                        {
-                            rootInterfaceFound = true;
-                        }
-                        else if (boost::starts_with(ifaceItem,
-                                                    rootInterfaceName + "_"))
-                        {
-                            ifaceArray.push_back(
-                                {{"@odata.id", "/redfish/v1/Managers/" +
-                                                   managerId +
-                                                   "/EthernetInterfaces/" +
-                                                   rootInterfaceName +
-                                                   "/VLANs/" + ifaceItem}});
-                        }
-                    }
+            nlohmann::json iface_array = nlohmann::json::array();
 
-                    if (rootInterfaceFound)
-                    {
-                        Node::json["Members"] = ifaceArray;
-                        Node::json["Members@odata.count"] = ifaceArray.size();
-                        Node::json["@odata.id"] = "/redfish/v1/Managers/" +
-                                                  managerId +
-                                                  "/EthernetInterfaces/" +
-                                                  rootInterfaceName + "/VLANs";
-                        res.jsonValue = Node::json;
-                    }
-                    else
-                    {
-                        messages::addMessageToErrorJson(
-                            res.jsonValue,
-                            messages::resourceNotFound("EthernetInterface",
-                                                       rootInterfaceName));
-                        res.result(boost::beast::http::status::not_found);
-                        res.end();
-                    }
-                }
-                else
+            for (const std::string &iface_item : iface_list)
+            {
+                if (boost::starts_with(iface_item, rootInterfaceName + "_"))
                 {
-                    // No success, best what we can do is return INTERNALL ERROR
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
+                    iface_array.push_back(
+                        {{"@odata.id",
+                          "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+                              rootInterfaceName + "/VLANs/" + iface_item}});
                 }
-                res.end();
-            });
+            }
+
+            if (iface_array.empty())
+            {
+                messages::addMessageToErrorJson(
+                    asyncResp->res.jsonValue,
+                    messages::resourceNotFound("EthernetInterface",
+                                               rootInterfaceName));
+                asyncResp->res.result(boost::beast::http::status::not_found);
+                return;
+            }
+            asyncResp->res.jsonValue["Members@odata.count"] =
+                iface_array.size();
+            asyncResp->res.jsonValue["Members"] = std::move(iface_array);
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+                rootInterfaceName + "/VLANs";
+        });
     }
 
     void doPost(crow::Response &res, const crow::Request &req,
                 const std::vector<std::string> &params) override
     {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         if (params.size() != 1)
         {
-            // This means there is a problem with the router
-            res.result(boost::beast::http::status::internal_server_error);
-            res.end();
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
             return;
         }
 
         nlohmann::json postReq;
-
         if (!json_util::processJsonFromRequest(res, req, postReq))
         {
             return;
         }
 
-        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
-        // for any Manager, not only hardcoded 'openbmc'.
-        std::string managerId = "openbmc";
-        std::string rootInterfaceName = params[0];
-        uint64_t vlanId;
-        bool errorDetected;
-
-        if (json_util::getUnsigned(
-                "VLANId", postReq, vlanId,
-                static_cast<uint8_t>(json_util::MessageSetting::MISSING) |
-                    static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-                res.jsonValue, "/VLANId") != json_util::Result::SUCCESS)
+        auto vlanIdJson = json.find("VLANId");
+        if (vlanIdJson == json.end())
         {
-            res.end();
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::propertyMissing("VLANId"),
+                                       "/VLANId");
             return;
         }
 
-        // get eth interface list, and call the below callback for JSON
-        // preparation
-        ethernetProvider.getEthernetIfaceList(
-            [&, managerId{std::move(managerId)},
-             rootInterfaceName{std::move(rootInterfaceName)}](
-                const bool &success,
-                const std::vector<std::string> &iface_list) {
-                if (success)
-                {
-                    bool rootInterfaceFound = false;
+        const uint64_t *vlanId = vlanIdJson->get_ptr<const uint64_t *>();
+        if (vlanId == nullptr)
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(vlanIdJson->dump(), "VLANId"),
+                "/VLANId");
+            return;
+        }
+        const std::string &rootInterfaceName = params[0];
 
-                    for (const std::string &ifaceItem : iface_list)
-                    {
-                        if (ifaceItem == rootInterfaceName)
-                        {
-                            rootInterfaceFound = true;
-                            break;
-                        }
-                    }
-
-                    if (rootInterfaceFound)
-                    {
-                        ethernetProvider.createVlan(
-                            rootInterfaceName, vlanId,
-                            [&, vlanId, rootInterfaceName, req{std::move(req)}](
-                                const boost::system::error_code ec) {
-                                if (ec)
-                                {
-                                    messages::addMessageToErrorJson(
-                                        res.jsonValue,
-                                        messages::internalError());
-                                    res.end();
-                                }
-                                else
-                                {
-                                    memberVlan.doGet(
-                                        res, req,
-                                        {rootInterfaceName,
-                                         rootInterfaceName + "_" +
-                                             std::to_string(vlanId)});
-                                }
-                            });
-                    }
-                    else
-                    {
-                        messages::addMessageToErrorJson(
-                            res.jsonValue,
-                            messages::resourceNotFound("EthernetInterface",
-                                                       rootInterfaceName));
-                        res.result(boost::beast::http::status::not_found);
-                        res.end();
-                    }
-                }
-                else
-                {
-                    // No success, best what we can do is return INTERNALL ERROR
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
-                    res.end();
-                }
-            });
+        auto callback = [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                // TODO(ed) make more consistent error messages based on
+                // phosphor-network responses
+                messages::addMessageToErrorJson(asyncResp->res.jsonValue,
+                                                messages::internalError());
+                return;
+            }
+            asyncResp->res.result(boost::beast::http::status::created);
+            messages::addMessageToErrorJson(asyncResp->res.jsonValue,
+                                            messages::created());
+        };
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network",
+            "xyz.openbmc_project.Network.VLAN.Create", "VLAN",
+            rootInterfaceName, static_cast<uint32_t>(*vlanId));
     }
-
-    // Ethernet Provider object
-    // TODO(Pawel) consider move it to singleton
-    OnDemandEthernetProvider ethernetProvider;
-    VlanNetworkInterface memberVlan;
 };
-
 } // namespace redfish
