diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 6dff5fd..0f43a36 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -69,8 +69,7 @@
         requestRoutesServiceRoot(app);
         requestRoutesNetworkProtocol(app);
         requestRoutesSession(app);
-        nodes.emplace_back(std::make_unique<EthernetCollection>(app));
-        nodes.emplace_back(std::make_unique<EthernetInterface>(app));
+        requestEthernetInterfacesRoutes(app);
         requestRoutesThermal(app);
         requestRoutesManagerCollection(app);
         requestRoutesManager(app);
@@ -91,9 +90,6 @@
 #endif
         requestRoutesSoftwareInventoryCollection(app);
         requestRoutesSoftwareInventory(app);
-        nodes.emplace_back(
-            std::make_unique<VlanNetworkInterfaceCollection>(app));
-        nodes.emplace_back(std::make_unique<VlanNetworkInterface>(app));
 
         requestRoutesSystemLogServiceCollection(app);
         requestRoutesEventLogService(app);
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 99f452d..d78cb58 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -1024,46 +1024,831 @@
         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
 }
 
-/**
- * EthernetCollection derived class for delivering Ethernet Collection Schema
- */
-class EthernetCollection : public Node
+void handleHostnamePatch(const std::string& hostname,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
-  public:
-    EthernetCollection(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
+    // SHOULD handle host names of up to 255 characters(RFC 1123)
+    if (hostname.length() > 255)
     {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+        messages::propertyValueFormatError(asyncResp->res, hostname,
+                                           "HostName");
+        return;
+    }
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+            }
+        },
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+        std::variant<std::string>(hostname));
+}
+
+void handleDomainnamePatch(const std::string& ifaceId,
+                           const std::string& domainname,
+                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::vector<std::string> vectorDomainname = {domainname};
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+            }
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.EthernetInterface", "DomainName",
+        std::variant<std::vector<std::string>>(vectorDomainname));
+}
+
+bool isHostnameValid(const std::string& hostname)
+{
+    // A valid host name can never have the dotted-decimal form (RFC 1123)
+    if (std::all_of(hostname.begin(), hostname.end(), ::isdigit))
+    {
+        return false;
+    }
+    // Each label(hostname/subdomains) within a valid FQDN
+    // MUST handle host names of up to 63 characters (RFC 1123)
+    // labels cannot start or end with hyphens (RFC 952)
+    // labels can start with numbers (RFC 1123)
+    const std::regex pattern(
+        "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
+
+    return std::regex_match(hostname, pattern);
+}
+
+bool isDomainnameValid(const std::string& domainname)
+{
+    // Can have multiple subdomains
+    // Top Level Domain's min length is 2 character
+    const std::regex pattern("^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]"
+                             "{1,30}\\.)*[a-zA-Z]{2,}$");
+
+    return std::regex_match(domainname, pattern);
+}
+
+void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    // Total length of FQDN must not exceed 255 characters(RFC 1035)
+    if (fqdn.length() > 255)
+    {
+        messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
+        return;
     }
 
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
+    size_t pos = fqdn.find('.');
+    if (pos == std::string::npos)
     {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#EthernetInterfaceCollection.EthernetInterfaceCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/EthernetInterfaces";
-        asyncResp->res.jsonValue["Name"] =
-            "Ethernet Network Interface Collection";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of EthernetInterfaces for this Manager";
+        messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
+        return;
+    }
 
-        // Get eth interface list, and call the below callback for JSON
-        // preparation
-        getEthernetIfaceList(
-            [asyncResp](
-                const bool& success,
-                const boost::container::flat_set<std::string>& ifaceList) {
+    std::string hostname;
+    std::string domainname;
+    domainname = (fqdn).substr(pos + 1);
+    hostname = (fqdn).substr(0, pos);
+
+    if (!isHostnameValid(hostname) || !isDomainnameValid(domainname))
+    {
+        messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
+        return;
+    }
+
+    handleHostnamePatch(hostname, asyncResp);
+    handleDomainnamePatch(ifaceId, domainname, asyncResp);
+}
+
+void handleMACAddressPatch(const std::string& ifaceId,
+                           const std::string& macAddress,
+                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, macAddress](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.MACAddress", "MACAddress",
+        std::variant<std::string>(macAddress));
+}
+
+void setDHCPEnabled(const std::string& ifaceId, const std::string& propertyName,
+                    const bool v4Value, const bool v6Value,
+                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value);
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            messages::success(asyncResp->res);
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.EthernetInterface", propertyName,
+        std::variant<std::string>{dhcp});
+}
+
+void setEthernetInterfaceBoolProperty(
+    const std::string& ifaceId, const std::string& propertyName,
+    const bool& value, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.EthernetInterface", propertyName,
+        std::variant<bool>{value});
+}
+
+void setDHCPv4Config(const std::string& propertyName, const bool& value,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    BMCWEB_LOG_DEBUG << propertyName << " = " << value;
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/config/dhcp",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.DHCPConfiguration", propertyName,
+        std::variant<bool>{value});
+}
+
+void handleDHCPPatch(const std::string& ifaceId,
+                     const EthernetInterfaceData& ethData,
+                     const DHCPParameters& v4dhcpParms,
+                     const DHCPParameters& v6dhcpParms,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    bool ipv4Active = translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
+    bool ipv6Active = translateDHCPEnabledToBool(ethData.DHCPEnabled, false);
+
+    bool nextv4DHCPState =
+        v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active;
+
+    bool nextv6DHCPState{};
+    if (v6dhcpParms.dhcpv6OperatingMode)
+    {
+        if ((*v6dhcpParms.dhcpv6OperatingMode != "Stateful") &&
+            (*v6dhcpParms.dhcpv6OperatingMode != "Stateless") &&
+            (*v6dhcpParms.dhcpv6OperatingMode != "Disabled"))
+        {
+            messages::propertyValueFormatError(asyncResp->res,
+                                               *v6dhcpParms.dhcpv6OperatingMode,
+                                               "OperatingMode");
+            return;
+        }
+        nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Stateful");
+    }
+    else
+    {
+        nextv6DHCPState = ipv6Active;
+    }
+
+    bool nextDNS{};
+    if (v4dhcpParms.useDNSServers && v6dhcpParms.useDNSServers)
+    {
+        if (*v4dhcpParms.useDNSServers != *v6dhcpParms.useDNSServers)
+        {
+            messages::generalError(asyncResp->res);
+            return;
+        }
+        nextDNS = *v4dhcpParms.useDNSServers;
+    }
+    else if (v4dhcpParms.useDNSServers)
+    {
+        nextDNS = *v4dhcpParms.useDNSServers;
+    }
+    else if (v6dhcpParms.useDNSServers)
+    {
+        nextDNS = *v6dhcpParms.useDNSServers;
+    }
+    else
+    {
+        nextDNS = ethData.DNSEnabled;
+    }
+
+    bool nextNTP{};
+    if (v4dhcpParms.useNTPServers && v6dhcpParms.useNTPServers)
+    {
+        if (*v4dhcpParms.useNTPServers != *v6dhcpParms.useNTPServers)
+        {
+            messages::generalError(asyncResp->res);
+            return;
+        }
+        nextNTP = *v4dhcpParms.useNTPServers;
+    }
+    else if (v4dhcpParms.useNTPServers)
+    {
+        nextNTP = *v4dhcpParms.useNTPServers;
+    }
+    else if (v6dhcpParms.useNTPServers)
+    {
+        nextNTP = *v6dhcpParms.useNTPServers;
+    }
+    else
+    {
+        nextNTP = ethData.NTPEnabled;
+    }
+
+    bool nextUseDomain{};
+    if (v4dhcpParms.useUseDomainName && v6dhcpParms.useUseDomainName)
+    {
+        if (*v4dhcpParms.useUseDomainName != *v6dhcpParms.useUseDomainName)
+        {
+            messages::generalError(asyncResp->res);
+            return;
+        }
+        nextUseDomain = *v4dhcpParms.useUseDomainName;
+    }
+    else if (v4dhcpParms.useUseDomainName)
+    {
+        nextUseDomain = *v4dhcpParms.useUseDomainName;
+    }
+    else if (v6dhcpParms.useUseDomainName)
+    {
+        nextUseDomain = *v6dhcpParms.useUseDomainName;
+    }
+    else
+    {
+        nextUseDomain = ethData.HostNameEnabled;
+    }
+
+    BMCWEB_LOG_DEBUG << "set DHCPEnabled...";
+    setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
+                   asyncResp);
+    BMCWEB_LOG_DEBUG << "set DNSEnabled...";
+    setDHCPv4Config("DNSEnabled", nextDNS, asyncResp);
+    BMCWEB_LOG_DEBUG << "set NTPEnabled...";
+    setDHCPv4Config("NTPEnabled", nextNTP, asyncResp);
+    BMCWEB_LOG_DEBUG << "set HostNameEnabled...";
+    setDHCPv4Config("HostNameEnabled", nextUseDomain, asyncResp);
+}
+
+boost::container::flat_set<IPv4AddressData>::const_iterator
+    getNextStaticIpEntry(
+        const boost::container::flat_set<IPv4AddressData>::const_iterator& head,
+        const boost::container::flat_set<IPv4AddressData>::const_iterator& end)
+{
+    return std::find_if(head, end, [](const IPv4AddressData& value) {
+        return value.origin == "Static";
+    });
+}
+
+boost::container::flat_set<IPv6AddressData>::const_iterator
+    getNextStaticIpEntry(
+        const boost::container::flat_set<IPv6AddressData>::const_iterator& head,
+        const boost::container::flat_set<IPv6AddressData>::const_iterator& end)
+{
+    return std::find_if(head, end, [](const IPv6AddressData& value) {
+        return value.origin == "Static";
+    });
+}
+
+void handleIPv4StaticPatch(
+    const std::string& ifaceId, nlohmann::json& input,
+    const boost::container::flat_set<IPv4AddressData>& ipv4Data,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if ((!input.is_array()) || input.empty())
+    {
+        messages::propertyValueTypeError(
+            asyncResp->res,
+            input.dump(2, ' ', true, nlohmann::json::error_handler_t::replace),
+            "IPv4StaticAddresses");
+        return;
+    }
+
+    unsigned entryIdx = 1;
+    // Find the first static IP address currently active on the NIC and
+    // match it to the first JSON element in the IPv4StaticAddresses array.
+    // Match each subsequent JSON element to the next static IP programmed
+    // into the NIC.
+    boost::container::flat_set<IPv4AddressData>::const_iterator niciPentry =
+        getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend());
+
+    for (nlohmann::json& thisJson : input)
+    {
+        std::string pathString =
+            "IPv4StaticAddresses/" + std::to_string(entryIdx);
+
+        if (!thisJson.is_null() && !thisJson.empty())
+        {
+            std::optional<std::string> address;
+            std::optional<std::string> subnetMask;
+            std::optional<std::string> gateway;
+
+            if (!json_util::readJson(thisJson, asyncResp->res, "Address",
+                                     address, "SubnetMask", subnetMask,
+                                     "Gateway", gateway))
+            {
+                messages::propertyValueFormatError(
+                    asyncResp->res,
+                    thisJson.dump(2, ' ', true,
+                                  nlohmann::json::error_handler_t::replace),
+                    pathString);
+                return;
+            }
+
+            // Find the address/subnet/gateway values. Any values that are
+            // not explicitly provided are assumed to be unmodified from the
+            // current state of the interface. Merge existing state into the
+            // current request.
+            const std::string* addr = nullptr;
+            const std::string* gw = nullptr;
+            uint8_t prefixLength = 0;
+            bool errorInEntry = false;
+            if (address)
+            {
+                if (ipv4VerifyIpAndGetBitcount(*address))
+                {
+                    addr = &(*address);
+                }
+                else
+                {
+                    messages::propertyValueFormatError(asyncResp->res, *address,
+                                                       pathString + "/Address");
+                    errorInEntry = true;
+                }
+            }
+            else if (niciPentry != ipv4Data.cend())
+            {
+                addr = &(niciPentry->address);
+            }
+            else
+            {
+                messages::propertyMissing(asyncResp->res,
+                                          pathString + "/Address");
+                errorInEntry = true;
+            }
+
+            if (subnetMask)
+            {
+                if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength))
+                {
+                    messages::propertyValueFormatError(
+                        asyncResp->res, *subnetMask,
+                        pathString + "/SubnetMask");
+                    errorInEntry = true;
+                }
+            }
+            else if (niciPentry != ipv4Data.cend())
+            {
+                if (!ipv4VerifyIpAndGetBitcount(niciPentry->netmask,
+                                                &prefixLength))
+                {
+                    messages::propertyValueFormatError(
+                        asyncResp->res, niciPentry->netmask,
+                        pathString + "/SubnetMask");
+                    errorInEntry = true;
+                }
+            }
+            else
+            {
+                messages::propertyMissing(asyncResp->res,
+                                          pathString + "/SubnetMask");
+                errorInEntry = true;
+            }
+
+            if (gateway)
+            {
+                if (ipv4VerifyIpAndGetBitcount(*gateway))
+                {
+                    gw = &(*gateway);
+                }
+                else
+                {
+                    messages::propertyValueFormatError(asyncResp->res, *gateway,
+                                                       pathString + "/Gateway");
+                    errorInEntry = true;
+                }
+            }
+            else if (niciPentry != ipv4Data.cend())
+            {
+                gw = &niciPentry->gateway;
+            }
+            else
+            {
+                messages::propertyMissing(asyncResp->res,
+                                          pathString + "/Gateway");
+                errorInEntry = true;
+            }
+
+            if (errorInEntry)
+            {
+                return;
+            }
+
+            if (niciPentry != ipv4Data.cend())
+            {
+                deleteAndCreateIPv4(ifaceId, niciPentry->id, prefixLength, *gw,
+                                    *addr, asyncResp);
+                niciPentry =
+                    getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
+            }
+            else
+            {
+                createIPv4(ifaceId, prefixLength, *gateway, *address,
+                           asyncResp);
+            }
+            entryIdx++;
+        }
+        else
+        {
+            if (niciPentry == ipv4Data.cend())
+            {
+                // Requesting a DELETE/DO NOT MODIFY action for an item
+                // that isn't present on the eth(n) interface. Input JSON is
+                // in error, so bail out.
+                if (thisJson.is_null())
+                {
+                    messages::resourceCannotBeDeleted(asyncResp->res);
+                    return;
+                }
+                messages::propertyValueFormatError(
+                    asyncResp->res,
+                    thisJson.dump(2, ' ', true,
+                                  nlohmann::json::error_handler_t::replace),
+                    pathString);
+                return;
+            }
+
+            if (thisJson.is_null())
+            {
+                deleteIPv4(ifaceId, niciPentry->id, asyncResp);
+            }
+            if (niciPentry != ipv4Data.cend())
+            {
+                niciPentry =
+                    getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
+            }
+            entryIdx++;
+        }
+    }
+}
+
+void handleStaticNameServersPatch(
+    const std::string& ifaceId,
+    const std::vector<std::string>& updatedStaticNameServers,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Network",
+        "/xyz/openbmc_project/network/" + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.EthernetInterface", "StaticNameServers",
+        std::variant<std::vector<std::string>>{updatedStaticNameServers});
+}
+
+void handleIPv6StaticAddressesPatch(
+    const std::string& ifaceId, const nlohmann::json& input,
+    const boost::container::flat_set<IPv6AddressData>& ipv6Data,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!input.is_array() || input.empty())
+    {
+        messages::propertyValueTypeError(
+            asyncResp->res,
+            input.dump(2, ' ', true, nlohmann::json::error_handler_t::replace),
+            "IPv6StaticAddresses");
+        return;
+    }
+    size_t entryIdx = 1;
+    boost::container::flat_set<IPv6AddressData>::const_iterator niciPentry =
+        getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend());
+    for (const nlohmann::json& thisJson : input)
+    {
+        std::string pathString =
+            "IPv6StaticAddresses/" + std::to_string(entryIdx);
+
+        if (!thisJson.is_null() && !thisJson.empty())
+        {
+            std::optional<std::string> address;
+            std::optional<uint8_t> prefixLength;
+            nlohmann::json thisJsonCopy = thisJson;
+            if (!json_util::readJson(thisJsonCopy, asyncResp->res, "Address",
+                                     address, "PrefixLength", prefixLength))
+            {
+                messages::propertyValueFormatError(
+                    asyncResp->res,
+                    thisJson.dump(2, ' ', true,
+                                  nlohmann::json::error_handler_t::replace),
+                    pathString);
+                return;
+            }
+
+            const std::string* addr;
+            uint8_t prefix;
+
+            // Find the address and prefixLength values. Any values that are
+            // not explicitly provided are assumed to be unmodified from the
+            // current state of the interface. Merge existing state into the
+            // current request.
+            if (address)
+            {
+                addr = &(*address);
+            }
+            else if (niciPentry != ipv6Data.end())
+            {
+                addr = &(niciPentry->address);
+            }
+            else
+            {
+                messages::propertyMissing(asyncResp->res,
+                                          pathString + "/Address");
+                return;
+            }
+
+            if (prefixLength)
+            {
+                prefix = *prefixLength;
+            }
+            else if (niciPentry != ipv6Data.end())
+            {
+                prefix = niciPentry->prefixLength;
+            }
+            else
+            {
+                messages::propertyMissing(asyncResp->res,
+                                          pathString + "/PrefixLength");
+                return;
+            }
+
+            if (niciPentry != ipv6Data.end())
+            {
+                deleteAndCreateIPv6(ifaceId, niciPentry->id, prefix, *addr,
+                                    asyncResp);
+                niciPentry =
+                    getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
+            }
+            else
+            {
+                createIPv6(ifaceId, *prefixLength, *addr, asyncResp);
+            }
+            entryIdx++;
+        }
+        else
+        {
+            if (niciPentry == ipv6Data.end())
+            {
+                // Requesting a DELETE/DO NOT MODIFY action for an item
+                // that isn't present on the eth(n) interface. Input JSON is
+                // in error, so bail out.
+                if (thisJson.is_null())
+                {
+                    messages::resourceCannotBeDeleted(asyncResp->res);
+                    return;
+                }
+                messages::propertyValueFormatError(
+                    asyncResp->res,
+                    thisJson.dump(2, ' ', true,
+                                  nlohmann::json::error_handler_t::replace),
+                    pathString);
+                return;
+            }
+
+            if (thisJson.is_null())
+            {
+                deleteIPv6(ifaceId, niciPentry->id, asyncResp);
+            }
+            if (niciPentry != ipv6Data.cend())
+            {
+                niciPentry =
+                    getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
+            }
+            entryIdx++;
+        }
+    }
+}
+
+void parseInterfaceData(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& ifaceId, const EthernetInterfaceData& ethData,
+    const boost::container::flat_set<IPv4AddressData>& ipv4Data,
+    const boost::container::flat_set<IPv6AddressData>& ipv6Data)
+{
+    constexpr const std::array<const char*, 1> inventoryForEthernet = {
+        "xyz.openbmc_project.Inventory.Item.Ethernet"};
+
+    nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
+    jsonResponse["Id"] = ifaceId;
+    jsonResponse["@odata.id"] =
+        "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId;
+    jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
+
+    auto health = std::make_shared<HealthPopulate>(asyncResp);
+
+    crow::connections::systemBus->async_method_call(
+        [health](const boost::system::error_code ec,
+                 std::vector<std::string>& resp) {
+            if (ec)
+            {
+                return;
+            }
+
+            health->inventory = std::move(resp);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", int32_t(0),
+        inventoryForEthernet);
+
+    health->populate();
+
+    if (ethData.nicEnabled)
+    {
+        jsonResponse["LinkStatus"] = "LinkUp";
+        jsonResponse["Status"]["State"] = "Enabled";
+    }
+    else
+    {
+        jsonResponse["LinkStatus"] = "NoLink";
+        jsonResponse["Status"]["State"] = "Disabled";
+    }
+
+    jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown";
+    jsonResponse["SpeedMbps"] = ethData.speed;
+    jsonResponse["MACAddress"] = ethData.mac_address;
+    jsonResponse["DHCPv4"]["DHCPEnabled"] =
+        translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
+    jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.NTPEnabled;
+    jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.DNSEnabled;
+    jsonResponse["DHCPv4"]["UseDomainName"] = ethData.HostNameEnabled;
+
+    jsonResponse["DHCPv6"]["OperatingMode"] =
+        translateDHCPEnabledToBool(ethData.DHCPEnabled, false) ? "Stateful"
+                                                               : "Disabled";
+    jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.NTPEnabled;
+    jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.DNSEnabled;
+    jsonResponse["DHCPv6"]["UseDomainName"] = ethData.HostNameEnabled;
+
+    if (!ethData.hostname.empty())
+    {
+        jsonResponse["HostName"] = ethData.hostname;
+
+        // When domain name is empty then it means, that it is a network
+        // without domain names, and the host name itself must be treated as
+        // FQDN
+        std::string fqdn = ethData.hostname;
+        if (!ethData.domainnames.empty())
+        {
+            fqdn += "." + ethData.domainnames[0];
+        }
+        jsonResponse["FQDN"] = fqdn;
+    }
+
+    jsonResponse["VLANs"] = {
+        {"@odata.id",
+         "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId + "/VLANs"}};
+
+    jsonResponse["NameServers"] = ethData.nameServers;
+    jsonResponse["StaticNameServers"] = ethData.staticNameServers;
+
+    nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
+    nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
+    ipv4Array = nlohmann::json::array();
+    ipv4StaticArray = nlohmann::json::array();
+    for (auto& ipv4Config : ipv4Data)
+    {
+
+        std::string gatewayStr = ipv4Config.gateway;
+        if (gatewayStr.empty())
+        {
+            gatewayStr = "0.0.0.0";
+        }
+
+        ipv4Array.push_back({{"AddressOrigin", ipv4Config.origin},
+                             {"SubnetMask", ipv4Config.netmask},
+                             {"Address", ipv4Config.address},
+                             {"Gateway", gatewayStr}});
+        if (ipv4Config.origin == "Static")
+        {
+            ipv4StaticArray.push_back({{"AddressOrigin", ipv4Config.origin},
+                                       {"SubnetMask", ipv4Config.netmask},
+                                       {"Address", ipv4Config.address},
+                                       {"Gateway", gatewayStr}});
+        }
+    }
+
+    std::string ipv6GatewayStr = ethData.ipv6_default_gateway;
+    if (ipv6GatewayStr.empty())
+    {
+        ipv6GatewayStr = "0:0:0:0:0:0:0:0";
+    }
+
+    jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr;
+
+    nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"];
+    nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"];
+    ipv6Array = nlohmann::json::array();
+    ipv6StaticArray = nlohmann::json::array();
+    nlohmann::json& ipv6AddrPolicyTable =
+        jsonResponse["IPv6AddressPolicyTable"];
+    ipv6AddrPolicyTable = nlohmann::json::array();
+    for (auto& ipv6Config : ipv6Data)
+    {
+        ipv6Array.push_back({{"Address", ipv6Config.address},
+                             {"PrefixLength", ipv6Config.prefixLength},
+                             {"AddressOrigin", ipv6Config.origin},
+                             {"AddressState", nullptr}});
+        if (ipv6Config.origin == "Static")
+        {
+            ipv6StaticArray.push_back(
+                {{"Address", ipv6Config.address},
+                 {"PrefixLength", ipv6Config.prefixLength},
+                 {"AddressOrigin", ipv6Config.origin},
+                 {"AddressState", nullptr}});
+        }
+    }
+}
+
+void parseInterfaceData(nlohmann::json& jsonResponse,
+                        const std::string& parentIfaceId,
+                        const std::string& ifaceId,
+                        const EthernetInterfaceData& ethData)
+{
+    // Fill out obvious data...
+    jsonResponse["Id"] = ifaceId;
+    jsonResponse["@odata.id"] = "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+                                parentIfaceId + "/VLANs/" + ifaceId;
+
+    jsonResponse["VLANEnable"] = true;
+    if (!ethData.vlan_id.empty())
+    {
+        jsonResponse["VLANId"] = ethData.vlan_id.back();
+    }
+}
+
+bool verifyNames(const std::string& parent, const std::string& iface)
+{
+    if (!boost::starts_with(iface, parent + "_"))
+    {
+        return false;
+    }
+    return true;
+}
+
+inline void requestEthernetInterfacesRoutes(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#EthernetInterfaceCollection.EthernetInterfaceCollection";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Managers/bmc/EthernetInterfaces";
+            asyncResp->res.jsonValue["Name"] =
+                "Ethernet Network Interface Collection";
+            asyncResp->res.jsonValue["Description"] =
+                "Collection of EthernetInterfaces for this Manager";
+
+            // Get eth interface list, and call the below callback for JSON
+            // preparation
+            getEthernetIfaceList([asyncResp](const bool& success,
+                                             const boost::container::flat_set<
+                                                 std::string>& ifaceList) {
                 if (!success)
                 {
                     messages::internalError(asyncResp->res);
@@ -1091,1293 +1876,381 @@
                 asyncResp->res.jsonValue["@odata.id"] =
                     "/redfish/v1/Managers/bmc/EthernetInterfaces";
             });
-    }
-};
-
-/**
- * EthernetInterface derived class for delivering Ethernet Schema
- */
-class EthernetInterface : public Node
-{
-  public:
-    /*
-     * Default Constructor
-     */
-    EthernetInterface(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void
-        handleHostnamePatch(const std::string& hostname,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        // SHOULD handle host names of up to 255 characters(RFC 1123)
-        if (hostname.length() > 255)
-        {
-            messages::propertyValueFormatError(asyncResp->res, hostname,
-                                               "HostName");
-            return;
-        }
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/config",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
-            std::variant<std::string>(hostname));
-    }
-
-    void handleDomainnamePatch(
-        const std::string& ifaceId, const std::string& domainname,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        std::vector<std::string> vectorDomainname = {domainname};
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.EthernetInterface", "DomainName",
-            std::variant<std::vector<std::string>>(vectorDomainname));
-    }
-
-    void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
-                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        // Total length of FQDN must not exceed 255 characters(RFC 1035)
-        if (fqdn.length() > 255)
-        {
-            messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
-            return;
-        }
-
-        size_t pos = fqdn.find('.');
-        if (pos == std::string::npos)
-        {
-            messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
-            return;
-        }
-
-        std::string hostname;
-        std::string domainname;
-        domainname = (fqdn).substr(pos + 1);
-        hostname = (fqdn).substr(0, pos);
-
-        if (!isHostnameValid(hostname) || !isDomainnameValid(domainname))
-        {
-            messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
-            return;
-        }
-
-        handleHostnamePatch(hostname, asyncResp);
-        handleDomainnamePatch(ifaceId, domainname, asyncResp);
-    }
-
-    bool isHostnameValid(const std::string& hostname)
-    {
-        // A valid host name can never have the dotted-decimal form (RFC 1123)
-        if (std::all_of(hostname.begin(), hostname.end(), ::isdigit))
-        {
-            return false;
-        }
-        // Each label(hostname/subdomains) within a valid FQDN
-        // MUST handle host names of up to 63 characters (RFC 1123)
-        // labels cannot start or end with hyphens (RFC 952)
-        // labels can start with numbers (RFC 1123)
-        const std::regex pattern(
-            "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
-
-        return std::regex_match(hostname, pattern);
-    }
-
-    bool isDomainnameValid(const std::string& domainname)
-    {
-        // Can have multiple subdomains
-        // Top Level Domain's min length is 2 character
-        const std::regex pattern("^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]"
-                                 "{1,30}\\.)*[a-zA-Z]{2,}$");
-
-        return std::regex_match(domainname, pattern);
-    }
-
-    void handleMACAddressPatch(
-        const std::string& ifaceId, const std::string& macAddress,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, macAddress](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.MACAddress", "MACAddress",
-            std::variant<std::string>(macAddress));
-    }
-
-    void setDHCPEnabled(const std::string& ifaceId,
-                        const std::string& propertyName, const bool v4Value,
-                        const bool v6Value,
-                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value);
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                messages::success(asyncResp->res);
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.EthernetInterface", propertyName,
-            std::variant<std::string>{dhcp});
-    }
-
-    void setEthernetInterfaceBoolProperty(
-        const std::string& ifaceId, const std::string& propertyName,
-        const bool& value, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.EthernetInterface", propertyName,
-            std::variant<bool>{value});
-    }
-
-    void setDHCPv4Config(const std::string& propertyName, const bool& value,
-                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        BMCWEB_LOG_DEBUG << propertyName << " = " << value;
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/config/dhcp",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.DHCPConfiguration", propertyName,
-            std::variant<bool>{value});
-    }
-
-    void handleDHCPPatch(const std::string& ifaceId,
-                         const EthernetInterfaceData& ethData,
-                         const DHCPParameters& v4dhcpParms,
-                         const DHCPParameters& v6dhcpParms,
-                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        bool ipv4Active = translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
-        bool ipv6Active =
-            translateDHCPEnabledToBool(ethData.DHCPEnabled, false);
-
-        bool nextv4DHCPState =
-            v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active;
-
-        bool nextv6DHCPState{};
-        if (v6dhcpParms.dhcpv6OperatingMode)
-        {
-            if ((*v6dhcpParms.dhcpv6OperatingMode != "Stateful") &&
-                (*v6dhcpParms.dhcpv6OperatingMode != "Stateless") &&
-                (*v6dhcpParms.dhcpv6OperatingMode != "Disabled"))
-            {
-                messages::propertyValueFormatError(
-                    asyncResp->res, *v6dhcpParms.dhcpv6OperatingMode,
-                    "OperatingMode");
-                return;
-            }
-            nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Stateful");
-        }
-        else
-        {
-            nextv6DHCPState = ipv6Active;
-        }
-
-        bool nextDNS{};
-        if (v4dhcpParms.useDNSServers && v6dhcpParms.useDNSServers)
-        {
-            if (*v4dhcpParms.useDNSServers != *v6dhcpParms.useDNSServers)
-            {
-                messages::generalError(asyncResp->res);
-                return;
-            }
-            nextDNS = *v4dhcpParms.useDNSServers;
-        }
-        else if (v4dhcpParms.useDNSServers)
-        {
-            nextDNS = *v4dhcpParms.useDNSServers;
-        }
-        else if (v6dhcpParms.useDNSServers)
-        {
-            nextDNS = *v6dhcpParms.useDNSServers;
-        }
-        else
-        {
-            nextDNS = ethData.DNSEnabled;
-        }
-
-        bool nextNTP{};
-        if (v4dhcpParms.useNTPServers && v6dhcpParms.useNTPServers)
-        {
-            if (*v4dhcpParms.useNTPServers != *v6dhcpParms.useNTPServers)
-            {
-                messages::generalError(asyncResp->res);
-                return;
-            }
-            nextNTP = *v4dhcpParms.useNTPServers;
-        }
-        else if (v4dhcpParms.useNTPServers)
-        {
-            nextNTP = *v4dhcpParms.useNTPServers;
-        }
-        else if (v6dhcpParms.useNTPServers)
-        {
-            nextNTP = *v6dhcpParms.useNTPServers;
-        }
-        else
-        {
-            nextNTP = ethData.NTPEnabled;
-        }
-
-        bool nextUseDomain{};
-        if (v4dhcpParms.useUseDomainName && v6dhcpParms.useUseDomainName)
-        {
-            if (*v4dhcpParms.useUseDomainName != *v6dhcpParms.useUseDomainName)
-            {
-                messages::generalError(asyncResp->res);
-                return;
-            }
-            nextUseDomain = *v4dhcpParms.useUseDomainName;
-        }
-        else if (v4dhcpParms.useUseDomainName)
-        {
-            nextUseDomain = *v4dhcpParms.useUseDomainName;
-        }
-        else if (v6dhcpParms.useUseDomainName)
-        {
-            nextUseDomain = *v6dhcpParms.useUseDomainName;
-        }
-        else
-        {
-            nextUseDomain = ethData.HostNameEnabled;
-        }
-
-        BMCWEB_LOG_DEBUG << "set DHCPEnabled...";
-        setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
-                       asyncResp);
-        BMCWEB_LOG_DEBUG << "set DNSEnabled...";
-        setDHCPv4Config("DNSEnabled", nextDNS, asyncResp);
-        BMCWEB_LOG_DEBUG << "set NTPEnabled...";
-        setDHCPv4Config("NTPEnabled", nextNTP, asyncResp);
-        BMCWEB_LOG_DEBUG << "set HostNameEnabled...";
-        setDHCPv4Config("HostNameEnabled", nextUseDomain, asyncResp);
-    }
-
-    boost::container::flat_set<IPv4AddressData>::const_iterator
-        getNextStaticIpEntry(
-            const boost::container::flat_set<IPv4AddressData>::const_iterator&
-                head,
-            const boost::container::flat_set<IPv4AddressData>::const_iterator&
-                end)
-    {
-        return std::find_if(head, end, [](const IPv4AddressData& value) {
-            return value.origin == "Static";
         });
-    }
 
-    boost::container::flat_set<IPv6AddressData>::const_iterator
-        getNextStaticIpEntry(
-            const boost::container::flat_set<IPv6AddressData>::const_iterator&
-                head,
-            const boost::container::flat_set<IPv6AddressData>::const_iterator&
-                end)
-    {
-        return std::find_if(head, end, [](const IPv6AddressData& value) {
-            return value.origin == "Static";
-        });
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& ifaceId) {
+                getEthernetIfaceData(
+                    ifaceId,
+                    [asyncResp,
+                     ifaceId](const bool& success,
+                              const EthernetInterfaceData& ethData,
+                              const boost::container::flat_set<IPv4AddressData>&
+                                  ipv4Data,
+                              const boost::container::flat_set<IPv6AddressData>&
+                                  ipv6Data) {
+                        if (!success)
+                        {
+                            // TODO(Pawel)consider distinguish between non
+                            // existing object, and other errors
+                            messages::resourceNotFound(
+                                asyncResp->res, "EthernetInterface", ifaceId);
+                            return;
+                        }
 
-    void handleIPv4StaticPatch(
-        const std::string& ifaceId, nlohmann::json& input,
-        const boost::container::flat_set<IPv4AddressData>& ipv4Data,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        if ((!input.is_array()) || input.empty())
-        {
-            messages::propertyValueTypeError(
-                asyncResp->res,
-                input.dump(2, ' ', true,
-                           nlohmann::json::error_handler_t::replace),
-                "IPv4StaticAddresses");
-            return;
-        }
+                        asyncResp->res.jsonValue["@odata.type"] =
+                            "#EthernetInterface.v1_4_1.EthernetInterface";
+                        asyncResp->res.jsonValue["Name"] =
+                            "Manager Ethernet Interface";
+                        asyncResp->res.jsonValue["Description"] =
+                            "Management Network Interface";
 
-        unsigned entryIdx = 1;
-        // Find the first static IP address currently active on the NIC and
-        // match it to the first JSON element in the IPv4StaticAddresses array.
-        // Match each subsequent JSON element to the next static IP programmed
-        // into the NIC.
-        boost::container::flat_set<IPv4AddressData>::const_iterator niciPentry =
-            getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend());
+                        parseInterfaceData(asyncResp, ifaceId, ethData,
+                                           ipv4Data, ipv6Data);
+                    });
+            });
 
-        for (nlohmann::json& thisJson : input)
-        {
-            std::string pathString =
-                "IPv4StaticAddresses/" + std::to_string(entryIdx);
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& ifaceId) {
+                std::optional<std::string> hostname;
+                std::optional<std::string> fqdn;
+                std::optional<std::string> macAddress;
+                std::optional<std::string> ipv6DefaultGateway;
+                std::optional<nlohmann::json> ipv4StaticAddresses;
+                std::optional<nlohmann::json> ipv6StaticAddresses;
+                std::optional<std::vector<std::string>> staticNameServers;
+                std::optional<nlohmann::json> dhcpv4;
+                std::optional<nlohmann::json> dhcpv6;
+                std::optional<bool> interfaceEnabled;
+                DHCPParameters v4dhcpParms;
+                DHCPParameters v6dhcpParms;
 
-            if (!thisJson.is_null() && !thisJson.empty())
-            {
-                std::optional<std::string> address;
-                std::optional<std::string> subnetMask;
-                std::optional<std::string> gateway;
-
-                if (!json_util::readJson(thisJson, asyncResp->res, "Address",
-                                         address, "SubnetMask", subnetMask,
-                                         "Gateway", gateway))
-                {
-                    messages::propertyValueFormatError(
-                        asyncResp->res,
-                        thisJson.dump(2, ' ', true,
-                                      nlohmann::json::error_handler_t::replace),
-                        pathString);
-                    return;
-                }
-
-                // Find the address/subnet/gateway values. Any values that are
-                // not explicitly provided are assumed to be unmodified from the
-                // current state of the interface. Merge existing state into the
-                // current request.
-                const std::string* addr = nullptr;
-                const std::string* gw = nullptr;
-                uint8_t prefixLength = 0;
-                bool errorInEntry = false;
-                if (address)
-                {
-                    if (ipv4VerifyIpAndGetBitcount(*address))
-                    {
-                        addr = &(*address);
-                    }
-                    else
-                    {
-                        messages::propertyValueFormatError(
-                            asyncResp->res, *address, pathString + "/Address");
-                        errorInEntry = true;
-                    }
-                }
-                else if (niciPentry != ipv4Data.cend())
-                {
-                    addr = &(niciPentry->address);
-                }
-                else
-                {
-                    messages::propertyMissing(asyncResp->res,
-                                              pathString + "/Address");
-                    errorInEntry = true;
-                }
-
-                if (subnetMask)
-                {
-                    if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength))
-                    {
-                        messages::propertyValueFormatError(
-                            asyncResp->res, *subnetMask,
-                            pathString + "/SubnetMask");
-                        errorInEntry = true;
-                    }
-                }
-                else if (niciPentry != ipv4Data.cend())
-                {
-                    if (!ipv4VerifyIpAndGetBitcount(niciPentry->netmask,
-                                                    &prefixLength))
-                    {
-                        messages::propertyValueFormatError(
-                            asyncResp->res, niciPentry->netmask,
-                            pathString + "/SubnetMask");
-                        errorInEntry = true;
-                    }
-                }
-                else
-                {
-                    messages::propertyMissing(asyncResp->res,
-                                              pathString + "/SubnetMask");
-                    errorInEntry = true;
-                }
-
-                if (gateway)
-                {
-                    if (ipv4VerifyIpAndGetBitcount(*gateway))
-                    {
-                        gw = &(*gateway);
-                    }
-                    else
-                    {
-                        messages::propertyValueFormatError(
-                            asyncResp->res, *gateway, pathString + "/Gateway");
-                        errorInEntry = true;
-                    }
-                }
-                else if (niciPentry != ipv4Data.cend())
-                {
-                    gw = &niciPentry->gateway;
-                }
-                else
-                {
-                    messages::propertyMissing(asyncResp->res,
-                                              pathString + "/Gateway");
-                    errorInEntry = true;
-                }
-
-                if (errorInEntry)
+                if (!json_util::readJson(
+                        req, asyncResp->res, "HostName", hostname, "FQDN", fqdn,
+                        "IPv4StaticAddresses", ipv4StaticAddresses,
+                        "MACAddress", macAddress, "StaticNameServers",
+                        staticNameServers, "IPv6DefaultGateway",
+                        ipv6DefaultGateway, "IPv6StaticAddresses",
+                        ipv6StaticAddresses, "DHCPv4", dhcpv4, "DHCPv6", dhcpv6,
+                        "InterfaceEnabled", interfaceEnabled))
                 {
                     return;
                 }
-
-                if (niciPentry != ipv4Data.cend())
+                if (dhcpv4)
                 {
-                    deleteAndCreateIPv4(ifaceId, niciPentry->id, prefixLength,
-                                        *gw, *addr, asyncResp);
-                    niciPentry =
-                        getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
-                }
-                else
-                {
-                    createIPv4(ifaceId, prefixLength, *gateway, *address,
-                               asyncResp);
-                }
-                entryIdx++;
-            }
-            else
-            {
-                if (niciPentry == ipv4Data.cend())
-                {
-                    // Requesting a DELETE/DO NOT MODIFY action for an item
-                    // that isn't present on the eth(n) interface. Input JSON is
-                    // in error, so bail out.
-                    if (thisJson.is_null())
+                    if (!json_util::readJson(
+                            *dhcpv4, asyncResp->res, "DHCPEnabled",
+                            v4dhcpParms.dhcpv4Enabled, "UseDNSServers",
+                            v4dhcpParms.useDNSServers, "UseNTPServers",
+                            v4dhcpParms.useNTPServers, "UseDomainName",
+                            v4dhcpParms.useUseDomainName))
                     {
-                        messages::resourceCannotBeDeleted(asyncResp->res);
                         return;
                     }
-                    messages::propertyValueFormatError(
-                        asyncResp->res,
-                        thisJson.dump(2, ' ', true,
-                                      nlohmann::json::error_handler_t::replace),
-                        pathString);
-                    return;
                 }
 
-                if (thisJson.is_null())
+                if (dhcpv6)
                 {
-                    deleteIPv4(ifaceId, niciPentry->id, asyncResp);
-                }
-                if (niciPentry != ipv4Data.cend())
-                {
-                    niciPentry =
-                        getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
-                }
-                entryIdx++;
-            }
-        }
-    }
-
-    void handleStaticNameServersPatch(
-        const std::string& ifaceId,
-        const std::vector<std::string>& updatedStaticNameServers,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/" + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.EthernetInterface",
-            "StaticNameServers",
-            std::variant<std::vector<std::string>>{updatedStaticNameServers});
-    }
-
-    void handleIPv6StaticAddressesPatch(
-        const std::string& ifaceId, const nlohmann::json& input,
-        const boost::container::flat_set<IPv6AddressData>& ipv6Data,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        if (!input.is_array() || input.empty())
-        {
-            messages::propertyValueTypeError(
-                asyncResp->res,
-                input.dump(2, ' ', true,
-                           nlohmann::json::error_handler_t::replace),
-                "IPv6StaticAddresses");
-            return;
-        }
-        size_t entryIdx = 1;
-        boost::container::flat_set<IPv6AddressData>::const_iterator niciPentry =
-            getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend());
-        for (const nlohmann::json& thisJson : input)
-        {
-            std::string pathString =
-                "IPv6StaticAddresses/" + std::to_string(entryIdx);
-
-            if (!thisJson.is_null() && !thisJson.empty())
-            {
-                std::optional<std::string> address;
-                std::optional<uint8_t> prefixLength;
-                nlohmann::json thisJsonCopy = thisJson;
-                if (!json_util::readJson(thisJsonCopy, asyncResp->res,
-                                         "Address", address, "PrefixLength",
-                                         prefixLength))
-                {
-                    messages::propertyValueFormatError(
-                        asyncResp->res,
-                        thisJson.dump(2, ' ', true,
-                                      nlohmann::json::error_handler_t::replace),
-                        pathString);
-                    return;
-                }
-
-                const std::string* addr;
-                uint8_t prefix;
-
-                // Find the address and prefixLength values. Any values that are
-                // not explicitly provided are assumed to be unmodified from the
-                // current state of the interface. Merge existing state into the
-                // current request.
-                if (address)
-                {
-                    addr = &(*address);
-                }
-                else if (niciPentry != ipv6Data.end())
-                {
-                    addr = &(niciPentry->address);
-                }
-                else
-                {
-                    messages::propertyMissing(asyncResp->res,
-                                              pathString + "/Address");
-                    return;
-                }
-
-                if (prefixLength)
-                {
-                    prefix = *prefixLength;
-                }
-                else if (niciPentry != ipv6Data.end())
-                {
-                    prefix = niciPentry->prefixLength;
-                }
-                else
-                {
-                    messages::propertyMissing(asyncResp->res,
-                                              pathString + "/PrefixLength");
-                    return;
-                }
-
-                if (niciPentry != ipv6Data.end())
-                {
-                    deleteAndCreateIPv6(ifaceId, niciPentry->id, prefix, *addr,
-                                        asyncResp);
-                    niciPentry =
-                        getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
-                }
-                else
-                {
-                    createIPv6(ifaceId, *prefixLength, *addr, asyncResp);
-                }
-                entryIdx++;
-            }
-            else
-            {
-                if (niciPentry == ipv6Data.end())
-                {
-                    // Requesting a DELETE/DO NOT MODIFY action for an item
-                    // that isn't present on the eth(n) interface. Input JSON is
-                    // in error, so bail out.
-                    if (thisJson.is_null())
+                    if (!json_util::readJson(
+                            *dhcpv6, asyncResp->res, "OperatingMode",
+                            v6dhcpParms.dhcpv6OperatingMode, "UseDNSServers",
+                            v6dhcpParms.useDNSServers, "UseNTPServers",
+                            v6dhcpParms.useNTPServers, "UseDomainName",
+                            v6dhcpParms.useUseDomainName))
                     {
-                        messages::resourceCannotBeDeleted(asyncResp->res);
                         return;
                     }
-                    messages::propertyValueFormatError(
-                        asyncResp->res,
-                        thisJson.dump(2, ' ', true,
-                                      nlohmann::json::error_handler_t::replace),
-                        pathString);
-                    return;
                 }
 
-                if (thisJson.is_null())
-                {
-                    deleteIPv6(ifaceId, niciPentry->id, asyncResp);
-                }
-                if (niciPentry != ipv6Data.cend())
-                {
-                    niciPentry =
-                        getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
-                }
-                entryIdx++;
-            }
-        }
-    }
+                // Get single eth interface data, and call the below callback
+                // for JSON preparation
+                getEthernetIfaceData(
+                    ifaceId,
+                    [asyncResp, ifaceId, hostname = std::move(hostname),
+                     fqdn = std::move(fqdn), macAddress = std::move(macAddress),
+                     ipv4StaticAddresses = std::move(ipv4StaticAddresses),
+                     ipv6DefaultGateway = std::move(ipv6DefaultGateway),
+                     ipv6StaticAddresses = std::move(ipv6StaticAddresses),
+                     staticNameServers = std::move(staticNameServers),
+                     dhcpv4 = std::move(dhcpv4), dhcpv6 = std::move(dhcpv6),
+                     v4dhcpParms = std::move(v4dhcpParms),
+                     v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
+                        const bool& success,
+                        const EthernetInterfaceData& ethData,
+                        const boost::container::flat_set<IPv4AddressData>&
+                            ipv4Data,
+                        const boost::container::flat_set<IPv6AddressData>&
+                            ipv6Data) {
+                        if (!success)
+                        {
+                            // ... otherwise return error
+                            // TODO(Pawel)consider distinguish between non
+                            // existing object, and other errors
+                            messages::resourceNotFound(
+                                asyncResp->res, "Ethernet Interface", ifaceId);
+                            return;
+                        }
 
-    void parseInterfaceData(
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        const std::string& ifaceId, const EthernetInterfaceData& ethData,
-        const boost::container::flat_set<IPv4AddressData>& ipv4Data,
-        const boost::container::flat_set<IPv6AddressData>& ipv6Data)
-    {
-        constexpr const std::array<const char*, 1> inventoryForEthernet = {
-            "xyz.openbmc_project.Inventory.Item.Ethernet"};
+                        if (dhcpv4 || dhcpv6)
+                        {
+                            handleDHCPPatch(ifaceId, ethData, v4dhcpParms,
+                                            v6dhcpParms, asyncResp);
+                        }
 
-        nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
-        jsonResponse["Id"] = ifaceId;
-        jsonResponse["@odata.id"] =
-            "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId;
-        jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
+                        if (hostname)
+                        {
+                            handleHostnamePatch(*hostname, asyncResp);
+                        }
 
-        auto health = std::make_shared<HealthPopulate>(asyncResp);
+                        if (fqdn)
+                        {
+                            handleFqdnPatch(ifaceId, *fqdn, asyncResp);
+                        }
 
-        crow::connections::systemBus->async_method_call(
-            [health](const boost::system::error_code ec,
-                     std::vector<std::string>& resp) {
-                if (ec)
-                {
-                    return;
-                }
+                        if (macAddress)
+                        {
+                            handleMACAddressPatch(ifaceId, *macAddress,
+                                                  asyncResp);
+                        }
 
-                health->inventory = std::move(resp);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
-            int32_t(0), inventoryForEthernet);
+                        if (ipv4StaticAddresses)
+                        {
+                            // TODO(ed) for some reason the capture of
+                            // ipv4Addresses above is returning a const value,
+                            // not a non-const value. This doesn't really work
+                            // for us, as we need to be able to efficiently move
+                            // out the intermedia nlohmann::json objects. This
+                            // makes a copy of the structure, and operates on
+                            // that, but could be done more efficiently
+                            nlohmann::json ipv4Static = *ipv4StaticAddresses;
+                            handleIPv4StaticPatch(ifaceId, ipv4Static, ipv4Data,
+                                                  asyncResp);
+                        }
 
-        health->populate();
+                        if (staticNameServers)
+                        {
+                            handleStaticNameServersPatch(
+                                ifaceId, *staticNameServers, asyncResp);
+                        }
 
-        if (ethData.nicEnabled)
-        {
-            jsonResponse["LinkStatus"] = "LinkUp";
-            jsonResponse["Status"]["State"] = "Enabled";
-        }
-        else
-        {
-            jsonResponse["LinkStatus"] = "NoLink";
-            jsonResponse["Status"]["State"] = "Disabled";
-        }
+                        if (ipv6DefaultGateway)
+                        {
+                            messages::propertyNotWritable(asyncResp->res,
+                                                          "IPv6DefaultGateway");
+                        }
 
-        jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown";
-        jsonResponse["SpeedMbps"] = ethData.speed;
-        jsonResponse["MACAddress"] = ethData.mac_address;
-        jsonResponse["DHCPv4"]["DHCPEnabled"] =
-            translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
-        jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.NTPEnabled;
-        jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.DNSEnabled;
-        jsonResponse["DHCPv4"]["UseDomainName"] = ethData.HostNameEnabled;
+                        if (ipv6StaticAddresses)
+                        {
+                            nlohmann::json ipv6Static = *ipv6StaticAddresses;
+                            handleIPv6StaticAddressesPatch(ifaceId, ipv6Static,
+                                                           ipv6Data, asyncResp);
+                        }
 
-        jsonResponse["DHCPv6"]["OperatingMode"] =
-            translateDHCPEnabledToBool(ethData.DHCPEnabled, false) ? "Stateful"
-                                                                   : "Disabled";
-        jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.NTPEnabled;
-        jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.DNSEnabled;
-        jsonResponse["DHCPv6"]["UseDomainName"] = ethData.HostNameEnabled;
+                        if (interfaceEnabled)
+                        {
+                            setEthernetInterfaceBoolProperty(
+                                ifaceId, "NICEnabled", *interfaceEnabled,
+                                asyncResp);
+                        }
+                    });
+            });
 
-        if (!ethData.hostname.empty())
-        {
-            jsonResponse["HostName"] = ethData.hostname;
-
-            // When domain name is empty then it means, that it is a network
-            // without domain names, and the host name itself must be treated as
-            // FQDN
-            std::string fqdn = ethData.hostname;
-            if (!ethData.domainnames.empty())
-            {
-                fqdn += "." + ethData.domainnames[0];
-            }
-            jsonResponse["FQDN"] = fqdn;
-        }
-
-        jsonResponse["VLANs"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
-                              ifaceId + "/VLANs"}};
-
-        jsonResponse["NameServers"] = ethData.nameServers;
-        jsonResponse["StaticNameServers"] = ethData.staticNameServers;
-
-        nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
-        nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
-        ipv4Array = nlohmann::json::array();
-        ipv4StaticArray = nlohmann::json::array();
-        for (auto& ipv4Config : ipv4Data)
-        {
-
-            std::string gatewayStr = ipv4Config.gateway;
-            if (gatewayStr.empty())
-            {
-                gatewayStr = "0.0.0.0";
-            }
-
-            ipv4Array.push_back({{"AddressOrigin", ipv4Config.origin},
-                                 {"SubnetMask", ipv4Config.netmask},
-                                 {"Address", ipv4Config.address},
-                                 {"Gateway", gatewayStr}});
-            if (ipv4Config.origin == "Static")
-            {
-                ipv4StaticArray.push_back({{"AddressOrigin", ipv4Config.origin},
-                                           {"SubnetMask", ipv4Config.netmask},
-                                           {"Address", ipv4Config.address},
-                                           {"Gateway", gatewayStr}});
-            }
-        }
-
-        std::string ipv6GatewayStr = ethData.ipv6_default_gateway;
-        if (ipv6GatewayStr.empty())
-        {
-            ipv6GatewayStr = "0:0:0:0:0:0:0:0";
-        }
-
-        jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr;
-
-        nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"];
-        nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"];
-        ipv6Array = nlohmann::json::array();
-        ipv6StaticArray = nlohmann::json::array();
-        nlohmann::json& ipv6AddrPolicyTable =
-            jsonResponse["IPv6AddressPolicyTable"];
-        ipv6AddrPolicyTable = nlohmann::json::array();
-        for (auto& ipv6Config : ipv6Data)
-        {
-            ipv6Array.push_back({{"Address", ipv6Config.address},
-                                 {"PrefixLength", ipv6Config.prefixLength},
-                                 {"AddressOrigin", ipv6Config.origin},
-                                 {"AddressState", nullptr}});
-            if (ipv6Config.origin == "Static")
-            {
-                ipv6StaticArray.push_back(
-                    {{"Address", ipv6Config.address},
-                     {"PrefixLength", ipv6Config.prefixLength},
-                     {"AddressOrigin", ipv6Config.origin},
-                     {"AddressState", nullptr}});
-            }
-        }
-    }
-
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        getEthernetIfaceData(
-            params[0],
-            [this, asyncResp, ifaceId{std::string(params[0])}](
-                const bool& success, const EthernetInterfaceData& ethData,
-                const boost::container::flat_set<IPv4AddressData>& ipv4Data,
-                const boost::container::flat_set<IPv6AddressData>& ipv6Data) {
-                if (!success)
-                {
-                    // TODO(Pawel)consider distinguish between non existing
-                    // object, and other errors
-                    messages::resourceNotFound(asyncResp->res,
-                                               "EthernetInterface", ifaceId);
-                    return;
-                }
-
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& /* req */,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& parentIfaceId, const std::string& ifaceId) {
                 asyncResp->res.jsonValue["@odata.type"] =
-                    "#EthernetInterface.v1_4_1.EthernetInterface";
-                asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface";
-                asyncResp->res.jsonValue["Description"] =
-                    "Management Network Interface";
+                    "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
+                asyncResp->res.jsonValue["Name"] = "VLAN Network Interface";
 
-                parseInterfaceData(asyncResp, ifaceId, ethData, ipv4Data,
-                                   ipv6Data);
-            });
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& ifaceId = params[0];
-
-        std::optional<std::string> hostname;
-        std::optional<std::string> fqdn;
-        std::optional<std::string> macAddress;
-        std::optional<std::string> ipv6DefaultGateway;
-        std::optional<nlohmann::json> ipv4StaticAddresses;
-        std::optional<nlohmann::json> ipv6StaticAddresses;
-        std::optional<std::vector<std::string>> staticNameServers;
-        std::optional<nlohmann::json> dhcpv4;
-        std::optional<nlohmann::json> dhcpv6;
-        std::optional<bool> interfaceEnabled;
-        DHCPParameters v4dhcpParms;
-        DHCPParameters v6dhcpParms;
-
-        if (!json_util::readJson(
-                req, asyncResp->res, "HostName", hostname, "FQDN", fqdn,
-                "IPv4StaticAddresses", ipv4StaticAddresses, "MACAddress",
-                macAddress, "StaticNameServers", staticNameServers,
-                "IPv6DefaultGateway", ipv6DefaultGateway, "IPv6StaticAddresses",
-                ipv6StaticAddresses, "DHCPv4", dhcpv4, "DHCPv6", dhcpv6,
-                "InterfaceEnabled", interfaceEnabled))
-        {
-            return;
-        }
-        if (dhcpv4)
-        {
-            if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled",
-                                     v4dhcpParms.dhcpv4Enabled, "UseDNSServers",
-                                     v4dhcpParms.useDNSServers, "UseNTPServers",
-                                     v4dhcpParms.useNTPServers, "UseDomainName",
-                                     v4dhcpParms.useUseDomainName))
-            {
-                return;
-            }
-        }
-
-        if (dhcpv6)
-        {
-            if (!json_util::readJson(*dhcpv6, asyncResp->res, "OperatingMode",
-                                     v6dhcpParms.dhcpv6OperatingMode,
-                                     "UseDNSServers", v6dhcpParms.useDNSServers,
-                                     "UseNTPServers", v6dhcpParms.useNTPServers,
-                                     "UseDomainName",
-                                     v6dhcpParms.useUseDomainName))
-            {
-                return;
-            }
-        }
-
-        // Get single eth interface data, and call the below callback for
-        // JSON preparation
-        getEthernetIfaceData(
-            ifaceId,
-            [this, asyncResp, ifaceId, hostname = std::move(hostname),
-             fqdn = std::move(fqdn), macAddress = std::move(macAddress),
-             ipv4StaticAddresses = std::move(ipv4StaticAddresses),
-             ipv6DefaultGateway = std::move(ipv6DefaultGateway),
-             ipv6StaticAddresses = std::move(ipv6StaticAddresses),
-             staticNameServers = std::move(staticNameServers),
-             dhcpv4 = std::move(dhcpv4), dhcpv6 = std::move(dhcpv6),
-             v4dhcpParms = std::move(v4dhcpParms),
-             v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
-                const bool& success, const EthernetInterfaceData& ethData,
-                const boost::container::flat_set<IPv4AddressData>& ipv4Data,
-                const boost::container::flat_set<IPv6AddressData>& ipv6Data) {
-                if (!success)
+                if (!verifyNames(parentIfaceId, ifaceId))
                 {
-                    // ... otherwise return error
-                    // TODO(Pawel)consider distinguish between non existing
-                    // object, and other errors
-                    messages::resourceNotFound(asyncResp->res,
-                                               "Ethernet Interface", ifaceId);
                     return;
                 }
 
-                if (dhcpv4 || dhcpv6)
-                {
-                    handleDHCPPatch(ifaceId, ethData, v4dhcpParms, v6dhcpParms,
-                                    asyncResp);
-                }
-
-                if (hostname)
-                {
-                    handleHostnamePatch(*hostname, asyncResp);
-                }
-
-                if (fqdn)
-                {
-                    handleFqdnPatch(ifaceId, *fqdn, asyncResp);
-                }
-
-                if (macAddress)
-                {
-                    handleMACAddressPatch(ifaceId, *macAddress, asyncResp);
-                }
-
-                if (ipv4StaticAddresses)
-                {
-                    // TODO(ed) for some reason the capture of ipv4Addresses
-                    // above is returning a const value, not a non-const
-                    // value. This doesn't really work for us, as we need to
-                    // be able to efficiently move out the intermedia
-                    // nlohmann::json objects. This makes a copy of the
-                    // structure, and operates on that, but could be done
-                    // more efficiently
-                    nlohmann::json ipv4Static = *ipv4StaticAddresses;
-                    handleIPv4StaticPatch(ifaceId, ipv4Static, ipv4Data,
-                                          asyncResp);
-                }
-
-                if (staticNameServers)
-                {
-                    handleStaticNameServersPatch(ifaceId, *staticNameServers,
-                                                 asyncResp);
-                }
-
-                if (ipv6DefaultGateway)
-                {
-                    messages::propertyNotWritable(asyncResp->res,
-                                                  "IPv6DefaultGateway");
-                }
-
-                if (ipv6StaticAddresses)
-                {
-                    nlohmann::json ipv6Static = *ipv6StaticAddresses;
-                    handleIPv6StaticAddressesPatch(ifaceId, ipv6Static,
-                                                   ipv6Data, asyncResp);
-                }
-
-                if (interfaceEnabled)
-                {
-                    setEthernetInterfaceBoolProperty(
-                        ifaceId, "NICEnabled", *interfaceEnabled, asyncResp);
-                }
+                // Get single eth interface data, and call the below callback
+                // for JSON preparation
+                getEthernetIfaceData(
+                    ifaceId,
+                    [asyncResp, parentIfaceId, ifaceId](
+                        const bool& success,
+                        const EthernetInterfaceData& ethData,
+                        const boost::container::flat_set<IPv4AddressData>&,
+                        const boost::container::flat_set<IPv6AddressData>&) {
+                        if (success && ethData.vlan_id.size() != 0)
+                        {
+                            parseInterfaceData(asyncResp->res.jsonValue,
+                                               parentIfaceId, ifaceId, ethData);
+                        }
+                        else
+                        {
+                            // ... otherwise return error
+                            // TODO(Pawel)consider distinguish between non
+                            // existing object, and other errors
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "VLAN Network Interface",
+                                                       ifaceId);
+                        }
+                    });
             });
-    }
-};
 
-/**
- * VlanNetworkInterface derived class for delivering VLANNetworkInterface
- * Schema
- */
-class VlanNetworkInterface : public Node
-{
-  public:
-    /*
-     * Default Constructor
-     */
-    VlanNetworkInterface(App& app) :
-        Node(app,
-             "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/",
-             std::string(), std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void parseInterfaceData(nlohmann::json& jsonResponse,
-                            const std::string& parentIfaceId,
-                            const std::string& ifaceId,
-                            const EthernetInterfaceData& ethData)
-    {
-        // Fill out obvious data...
-        jsonResponse["Id"] = ifaceId;
-        jsonResponse["@odata.id"] =
-            "/redfish/v1/Managers/bmc/EthernetInterfaces/" + parentIfaceId +
-            "/VLANs/" + ifaceId;
-
-        jsonResponse["VLANEnable"] = true;
-        if (!ethData.vlan_id.empty())
-        {
-            jsonResponse["VLANId"] = ethData.vlan_id.back();
-        }
-    }
-
-    bool verifyNames(const std::string& parent, const std::string& iface)
-    {
-        if (!boost::starts_with(iface, parent + "_"))
-        {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        // 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.
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& parentIfaceId = params[0];
-        const std::string& ifaceId = params[1];
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
-        asyncResp->res.jsonValue["Name"] = "VLAN Network Interface";
-
-        if (!verifyNames(parentIfaceId, ifaceId))
-        {
-            return;
-        }
-
-        // Get single eth interface data, and call the below callback for
-        // JSON preparation
-        getEthernetIfaceData(
-            params[1],
-            [this, asyncResp, parentIfaceId{std::string(params[0])},
-             ifaceId{std::string(params[1])}](
-                const bool& success, const EthernetInterfaceData& ethData,
-                const boost::container::flat_set<IPv4AddressData>&,
-                const boost::container::flat_set<IPv6AddressData>&) {
-                if (success && ethData.vlan_id.size() != 0)
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& parentIfaceId, const std::string& ifaceId) {
+                if (!verifyNames(parentIfaceId, ifaceId))
                 {
-                    parseInterfaceData(asyncResp->res.jsonValue, parentIfaceId,
-                                       ifaceId, ethData);
-                }
-                else
-                {
-                    // ... otherwise return error
-                    // TODO(Pawel)consider distinguish between non existing
-                    // object, and other errors
-                    messages::resourceNotFound(
-                        asyncResp->res, "VLAN Network Interface", ifaceId);
-                }
-            });
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& parentIfaceId = params[0];
-        const std::string& ifaceId = params[1];
-
-        if (!verifyNames(parentIfaceId, ifaceId))
-        {
-            messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
-                                       ifaceId);
-            return;
-        }
-
-        bool vlanEnable = false;
-        uint32_t vlanId = 0;
-
-        if (!json_util::readJson(req, asyncResp->res, "VLANEnable", vlanEnable,
-                                 "VLANId", vlanId))
-        {
-            return;
-        }
-
-        // Get single eth interface data, and call the below callback for
-        // JSON preparation
-        getEthernetIfaceData(
-            params[1],
-            [asyncResp, parentIfaceId{std::string(params[0])},
-             ifaceId{std::string(params[1])}, &vlanEnable,
-             &vlanId](const bool& success, const EthernetInterfaceData& ethData,
-                      const boost::container::flat_set<IPv4AddressData>&,
-                      const boost::container::flat_set<IPv6AddressData>&) {
-                if (success && !ethData.vlan_id.empty())
-                {
-                    auto callback =
-                        [asyncResp](const boost::system::error_code ec) {
-                            if (ec)
-                            {
-                                messages::internalError(asyncResp->res);
-                            }
-                        };
-
-                    if (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",
-                            std::variant<uint32_t>(vlanId));
-                    }
-                    else
-                    {
-                        BMCWEB_LOG_DEBUG << "vlanEnable is false. Deleting the "
-                                            "vlan interface";
-                        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
-                {
-                    // TODO(Pawel)consider distinguish between non existing
-                    // object, and other errors
                     messages::resourceNotFound(
                         asyncResp->res, "VLAN Network Interface", ifaceId);
                     return;
                 }
-            });
-    }
 
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+                bool vlanEnable = false;
+                uint32_t vlanId = 0;
 
-        const std::string& parentIfaceId = params[0];
-        const std::string& ifaceId = params[1];
-
-        if (!verifyNames(parentIfaceId, ifaceId))
-        {
-            messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
-                                       ifaceId);
-            return;
-        }
-
-        // Get single eth interface data, and call the below callback for
-        // JSON preparation
-        getEthernetIfaceData(
-            params[1],
-            [asyncResp, parentIfaceId{std::string(params[0])},
-             ifaceId{std::string(params[1])}](
-                const bool& success, const EthernetInterfaceData& ethData,
-                const boost::container::flat_set<IPv4AddressData>&,
-                const boost::container::flat_set<IPv6AddressData>&) {
-                if (success && !ethData.vlan_id.empty())
+                if (!json_util::readJson(req, asyncResp->res, "VLANEnable",
+                                         vlanEnable, "VLANId", vlanId))
                 {
-                    auto callback =
-                        [asyncResp](const boost::system::error_code ec) {
-                            if (ec)
-                            {
-                                messages::internalError(asyncResp->res);
-                            }
-                        };
-                    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");
+                    return;
                 }
-                else
+
+                // Get single eth interface data, and call the below callback
+                // for JSON preparation
+                getEthernetIfaceData(
+                    ifaceId,
+                    [asyncResp, parentIfaceId, ifaceId, &vlanEnable, &vlanId](
+                        const bool& success,
+                        const EthernetInterfaceData& ethData,
+                        const boost::container::flat_set<IPv4AddressData>&,
+                        const boost::container::flat_set<IPv6AddressData>&) {
+                        if (success && !ethData.vlan_id.empty())
+                        {
+                            auto callback =
+                                [asyncResp](
+                                    const boost::system::error_code ec) {
+                                    if (ec)
+                                    {
+                                        messages::internalError(asyncResp->res);
+                                    }
+                                };
+
+                            if (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",
+                                    std::variant<uint32_t>(vlanId));
+                            }
+                            else
+                            {
+                                BMCWEB_LOG_DEBUG
+                                    << "vlanEnable is false. Deleting the "
+                                       "vlan interface";
+                                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
+                        {
+                            // TODO(Pawel)consider distinguish between non
+                            // existing object, and other errors
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "VLAN Network Interface",
+                                                       ifaceId);
+                            return;
+                        }
+                    });
+            });
+
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request& /* req */,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& parentIfaceId, const std::string& ifaceId) {
+                if (!verifyNames(parentIfaceId, ifaceId))
                 {
-                    // ... otherwise return error
-                    // TODO(Pawel)consider distinguish between non existing
-                    // object, and other errors
                     messages::resourceNotFound(
                         asyncResp->res, "VLAN Network Interface", ifaceId);
+                    return;
                 }
+
+                // Get single eth interface data, and call the below callback
+                // for JSON preparation
+                getEthernetIfaceData(
+                    ifaceId,
+                    [asyncResp, parentIfaceId, ifaceId](
+                        const bool& success,
+                        const EthernetInterfaceData& ethData,
+                        const boost::container::flat_set<IPv4AddressData>&,
+                        const boost::container::flat_set<IPv6AddressData>&) {
+                        if (success && !ethData.vlan_id.empty())
+                        {
+                            auto callback =
+                                [asyncResp](
+                                    const boost::system::error_code ec) {
+                                    if (ec)
+                                    {
+                                        messages::internalError(asyncResp->res);
+                                    }
+                                };
+                            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::resourceNotFound(asyncResp->res,
+                                                       "VLAN Network Interface",
+                                                       ifaceId);
+                        }
+                    });
             });
-    }
-};
 
-/**
- * VlanNetworkInterfaceCollection derived class for delivering
- * VLANNetworkInterface Collection Schema
- */
-class VlanNetworkInterfaceCollection : public Node
-{
-  public:
-    VlanNetworkInterfaceCollection(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            // This means there is a problem with the router
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& rootInterfaceName = params[0];
-
-        // Get eth interface list, and call the below callback for JSON
-        // preparation
-        getEthernetIfaceList(
-            [asyncResp, rootInterfaceName{std::string(rootInterfaceName)}](
-                const bool& success,
-                const boost::container::flat_set<std::string>& ifaceList) {
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request& /* req */,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                        const std::string& rootInterfaceName) {
+            // Get eth interface list, and call the below callback for JSON
+            // preparation
+            getEthernetIfaceList([asyncResp, rootInterfaceName](
+                                     const bool& success,
+                                     const boost::container::flat_set<
+                                         std::string>& ifaceList) {
                 if (!success)
                 {
                     messages::internalError(asyncResp->res);
@@ -2420,54 +2293,53 @@
                     "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
                     rootInterfaceName + "/VLANs";
             });
-    }
+        });
 
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        bool vlanEnable = false;
-        uint32_t vlanId = 0;
-        if (!json_util::readJson(req, asyncResp->res, "VLANId", vlanId,
-                                 "VLANEnable", vlanEnable))
-        {
-            return;
-        }
-        // Need both vlanId and vlanEnable to service this request
-        if (!vlanId)
-        {
-            messages::propertyMissing(asyncResp->res, "VLANId");
-        }
-        if (!vlanEnable)
-        {
-            messages::propertyMissing(asyncResp->res, "VLANEnable");
-        }
-        if (static_cast<bool>(vlanId) ^ vlanEnable)
-        {
-            return;
-        }
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& rootInterfaceName) {
+                bool vlanEnable = false;
+                uint32_t vlanId = 0;
+                if (!json_util::readJson(req, asyncResp->res, "VLANId", vlanId,
+                                         "VLANEnable", vlanEnable))
+                {
+                    return;
+                }
+                // Need both vlanId and vlanEnable to service this request
+                if (!vlanId)
+                {
+                    messages::propertyMissing(asyncResp->res, "VLANId");
+                }
+                if (!vlanEnable)
+                {
+                    messages::propertyMissing(asyncResp->res, "VLANEnable");
+                }
+                if (static_cast<bool>(vlanId) ^ vlanEnable)
+                {
+                    return;
+                }
 
-        const std::string& rootInterfaceName = params[0];
-        auto callback = [asyncResp](const boost::system::error_code ec) {
-            if (ec)
-            {
-                // TODO(ed) make more consistent error messages based on
-                // phosphor-network responses
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            messages::created(asyncResp->res);
-        };
-        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, vlanId);
-    }
-};
+                auto callback =
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            // TODO(ed) make more consistent error messages
+                            // based on phosphor-network responses
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        messages::created(asyncResp->res);
+                    };
+                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, vlanId);
+            });
+}
+
 } // namespace redfish
diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp
index db6c0c2..0e0629d 100644
--- a/redfish-core/lib/hypervisor_system.hpp
+++ b/redfish-core/lib/hypervisor_system.hpp
@@ -673,21 +673,6 @@
     }
 }
 
-inline bool isHostnameValid(const std::string& hostName)
-{
-    // As per RFC 1123
-    // Allow up to 255 characters
-    if (hostName.length() > 255)
-    {
-        return false;
-    }
-    // Validate the regex
-    const std::regex pattern(
-        "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
-
-    return std::regex_match(hostName, pattern);
-}
-
 inline void
     handleHostnamePatch(const std::string& hostName,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
