#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_ETHERNET_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_ETHERNET_H_

/*
// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include <systemd/sd-bus.h>

#include <algorithm>
#include <functional>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <regex>  // NOLINT
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>

#include "boost/algorithm/string/classification.hpp"  // NOLINT
#include "boost/algorithm/string/split.hpp"  // NOLINT
#include "boost/container/flat_set.hpp"  // NOLINT
#include "app.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "http_request.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "ip_utils.hpp"
#include "sdbusplus/asio/property.hpp"
#include "json_utils.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message.hpp"
#include <nlohmann/json.hpp>
#include "sdbusplus/message/native_types.hpp"

#ifdef HEALTH_POPULATE
#include "health.hpp"  // NOLINT
#endif

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"  // NOLINT
#endif

namespace redfish {

enum class LinkType : std::uint8_t { Local, Global };

enum class NetworkType : std::uint8_t { dhcp4, dhcp6 };

/**
 * Structure for keeping IPv4 data required by Redfish
 */
struct IPv4AddressData {
  std::string id;
  std::string address;
  std::string domain;
  std::string gateway;
  std::string netmask;
  std::string origin;
  LinkType linktype;
  bool isActive;

  bool operator<(const IPv4AddressData& obj) const { return id < obj.id; }
};

/**
 * Structure for keeping IPv6 data required by Redfish
 */
struct IPv6AddressData {
  std::string id;
  std::string address;
  std::string origin;
  uint8_t prefixLength;

  bool operator<(const IPv6AddressData& obj) const { return id < obj.id; }
};
/**
 * Structure for keeping basic single Ethernet Interface information
 * available from DBus
 */
struct EthernetInterfaceData {
  uint32_t speed;
  size_t mtuSize;
  bool autoNeg;
  bool dnsv4Enabled;
  bool dnsv6Enabled;
  bool ntpv4Enabled;
  bool ntpv6Enabled;
  bool hostNamev4Enabled;
  bool hostNamev6Enabled;
  bool linkUp;
  bool nicEnabled;
  std::string dhcpEnabled;
  std::string operatingMode;
  std::string hostName;
  std::string defaultGateway;
  std::string ipv6DefaultGateway;
  std::string macAddress;
  std::optional<uint32_t> vlanId;
  std::vector<std::string> nameServers;
  std::vector<std::string> staticNameServers;
  std::vector<std::string> domainnames;
};

struct DHCPParameters {
  std::optional<bool> dhcpv4Enabled;
  std::optional<bool> useDnsServers;
  std::optional<bool> useNtpServers;
  std::optional<bool> useDomainName;
  std::optional<std::string> dhcpv6OperatingMode;
};

// Helper function that changes bits netmask notation (i.e. /24)
// into full dot notation
inline std::string getNetmask(unsigned int bits) {
  uint32_t value = 0xffffffff << (32 - bits);
  std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
                        std::to_string((value >> 16) & 0xff) + "." +
                        std::to_string((value >> 8) & 0xff) + "." +
                        std::to_string(value & 0xff);
  return netmask;
}

inline bool translateDhcpEnabledToBool(const std::string& inputDHCP,
                                       bool isIPv4) {
  if (isIPv4) {
    return ((inputDHCP ==
             "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4") ||
            (inputDHCP ==
             "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"));
  }
  return ((inputDHCP ==
           "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6") ||
          (inputDHCP ==
           "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"));
}

inline std::string getDhcpEnabledEnumeration(bool isIPv4, bool isIPv6) {
  if (isIPv4 && isIPv6) {
    return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both";
  }
  if (isIPv4) {
    return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4";
  }
  if (isIPv6) {
    return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6";
  }
  return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none";
}

inline std::string translateAddressOriginDbusToRedfish(
    const std::string& inputOrigin, bool isIPv4) {
  if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static") {
    return "Static";
  }
  if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal") {
    if (isIPv4) {
      return "IPv4LinkLocal";
    }
    return "LinkLocal";
  }
  if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP") {
    if (isIPv4) {
      return "DHCP";
    }
    return "DHCPv6";
  }
  if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC") {
    return "SLAAC";
  }
  return "";
}

inline void getethData(const auto ifacePair, const std::string_view ethifaceId,
                       const std::string_view dhcp,
                       const sdbusplus::message::object_path& objpath_first,
                       EthernetInterfaceData& ethData) {
  sdbusplus::message::object_path path("/xyz/openbmc_project/network");
  sdbusplus::message::object_path dhcpPath = path / ethifaceId / dhcp;

  if (objpath_first == dhcpPath) {
    if (ifacePair.first == "xyz.openbmc_project.Network.DHCPConfiguration") {
      for (const auto& propertyPair : ifacePair.second) {
        if (propertyPair.first == "DNSEnabled") {
          const bool* dnsEnabled = std::get_if<bool>(&propertyPair.second);
          if (dnsEnabled != nullptr) {
            if (dhcp == "dhcp4") {
              ethData.dnsv4Enabled = *dnsEnabled;
            } else if (dhcp == "dhcp6") {
              ethData.dnsv6Enabled = *dnsEnabled;
            } else {
              BMCWEB_LOG_ERROR << "Got wrong DHCP name:" << dhcp;
              return;
            }
          }
        } else if (propertyPair.first == "NTPEnabled") {
          const bool* ntpEnabled = std::get_if<bool>(&propertyPair.second);
          if (ntpEnabled != nullptr) {
            if (dhcp == "dhcp4") {
              ethData.ntpv4Enabled = *ntpEnabled;
            } else if (dhcp == "dhcp6") {
              ethData.ntpv6Enabled = *ntpEnabled;
            } else {
              BMCWEB_LOG_ERROR << "Got wrong DHCP name:" << dhcp;
              return;
            }
          }
        } else if (propertyPair.first == "HostNameEnabled") {
          const bool* hostNameEnabled = std::get_if<bool>(&propertyPair.second);
          if (hostNameEnabled != nullptr) {
            if (dhcp == "dhcp4") {
              ethData.hostNamev4Enabled = *hostNameEnabled;
            } else if (dhcp == "dhcp6") {
              ethData.hostNamev6Enabled = *hostNameEnabled;
            } else {
              BMCWEB_LOG_ERROR << "Got wrong DHCP name:" << dhcp;
              return;
            }
          }
        }
      }
    }
  }
}
inline bool extractEthernetInterfaceData(
    const std::string& ethifaceId,
    const dbus::utility::ManagedObjectType& dbusData,
    EthernetInterfaceData& ethData) {
  bool idFound = false;
  for (const auto& objpath : dbusData) {
    for (const auto& ifacePair : objpath.second) {
      if (objpath.first == "/xyz/openbmc_project/network/" + ethifaceId) {
        idFound = true;
        if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress") {
          for (const auto& propertyPair : ifacePair.second) {
            if (propertyPair.first == "MACAddress") {
              const std::string* mac =
                  std::get_if<std::string>(&propertyPair.second);
              if (mac != nullptr) {
                ethData.macAddress = *mac;
              }
            }
          }
        } else if (ifacePair.first == "xyz.openbmc_project.Network.VLAN") {
          for (const auto& propertyPair : ifacePair.second) {
            if (propertyPair.first == "Id") {
              const uint32_t* id = std::get_if<uint32_t>(&propertyPair.second);
              if (id != nullptr) {
                ethData.vlanId = *id;
              }
            }
          }
        } else if (ifacePair.first ==
                   "xyz.openbmc_project.Network.EthernetInterface") {
          for (const auto& propertyPair : ifacePair.second) {
            if (propertyPair.first == "AutoNeg") {
              const bool* autoNeg = std::get_if<bool>(&propertyPair.second);
              if (autoNeg != nullptr) {
                ethData.autoNeg = *autoNeg;
              }
            } else if (propertyPair.first == "Speed") {
              const uint32_t* speed =
                  std::get_if<uint32_t>(&propertyPair.second);
              if (speed != nullptr) {
                ethData.speed = *speed;
              }
            } else if (propertyPair.first == "MTU") {
              const size_t* mtuSize = std::get_if<size_t>(&propertyPair.second);
              if (mtuSize != nullptr) {
                ethData.mtuSize = *mtuSize;
              }
            } else if (propertyPair.first == "LinkUp") {
              const bool* linkUp = std::get_if<bool>(&propertyPair.second);
              if (linkUp != nullptr) {
                ethData.linkUp = *linkUp;
              }
            } else if (propertyPair.first == "NICEnabled") {
              const bool* nicEnabled = std::get_if<bool>(&propertyPair.second);
              if (nicEnabled != nullptr) {
                ethData.nicEnabled = *nicEnabled;
              }
            } else if (propertyPair.first == "Nameservers") {
              const std::vector<std::string>* nameservers =
                  std::get_if<std::vector<std::string>>(&propertyPair.second);
              if (nameservers != nullptr) {
                ethData.nameServers = *nameservers;
              }
            } else if (propertyPair.first == "StaticNameServers") {
              const std::vector<std::string>* staticNameServers =
                  std::get_if<std::vector<std::string>>(&propertyPair.second);
              if (staticNameServers != nullptr) {
                ethData.staticNameServers = *staticNameServers;
              }
            } else if (propertyPair.first == "DHCPEnabled") {
              const std::string* dhcpEnabled =
                  std::get_if<std::string>(&propertyPair.second);
              if (dhcpEnabled != nullptr) {
                ethData.dhcpEnabled = *dhcpEnabled;
              }
            } else if (propertyPair.first == "DomainName") {
              const std::vector<std::string>* domainNames =
                  std::get_if<std::vector<std::string>>(&propertyPair.second);
              if (domainNames != nullptr) {
                ethData.domainnames = *domainNames;
              }
            } else if (propertyPair.first == "DefaultGateway") {
              const std::string* defaultGateway =
                  std::get_if<std::string>(&propertyPair.second);
              if (defaultGateway != nullptr) {
                std::string defaultGatewayStr = *defaultGateway;
                if (defaultGatewayStr.empty()) {
                  ethData.defaultGateway = "0.0.0.0";
                } else {
                  ethData.defaultGateway = defaultGatewayStr;
                }
              }
            } else if (propertyPair.first == "DefaultGateway6") {
              const std::string* defaultGateway6 =
                  std::get_if<std::string>(&propertyPair.second);
              if (defaultGateway6 != nullptr) {
                std::string defaultGateway6Str = *defaultGateway6;
                if (defaultGateway6Str.empty()) {
                  ethData.ipv6DefaultGateway = "0:0:0:0:0:0:0:0";
                } else {
                  ethData.ipv6DefaultGateway = defaultGateway6Str;
                }
              }
            }
          }
        }
      }
      getethData(ifacePair, ethifaceId, "dhcp4", objpath.first, ethData);
      getethData(ifacePair, ethifaceId, "dhcp6", objpath.first, ethData);
      // System configuration shows up in the global namespace, so no need
      // to check eth number
      if (ifacePair.first ==
          "xyz.openbmc_project.Network.SystemConfiguration") {
        for (const auto& propertyPair : ifacePair.second) {
          if (propertyPair.first == "HostName") {
            const std::string* hostname =
                std::get_if<std::string>(&propertyPair.second);
            if (hostname != nullptr) {
              ethData.hostName = *hostname;
            }
          }
        }
      }
    }
  }
  return idFound;
}

// Helper function that extracts data for single ethernet ipv6 address
inline void extractIPV6Data(
    const std::string& ethifaceId,
    const dbus::utility::ManagedObjectType& dbusData,
    boost::container::flat_set<IPv6AddressData>& ipv6Config) {
  const std::string ipPathStart = "/xyz/openbmc_project/network/" + ethifaceId;

  // Since there might be several IPv6 configurations aligned with
  // single ethernet interface, loop over all of them
  for (const auto& objpath : dbusData) {
    // Check if proper pattern for object path appears
    if (objpath.first.str.starts_with(ipPathStart + "/")) {
      for (const auto& interface : objpath.second) {
        if (interface.first == "xyz.openbmc_project.Network.IP") {
          auto type = std::find_if(
              interface.second.begin(), interface.second.end(),
              [](const auto& property) { return property.first == "Type"; });
          if (type == interface.second.end()) {
            continue;
          }

          const std::string* typeStr = std::get_if<std::string>(&type->second);

          if (typeStr == nullptr ||
              (*typeStr != "xyz.openbmc_project.Network.IP.Protocol.IPv6")) {
            continue;
          }

          // Instance IPv6AddressData structure, and set as
          // appropriate
          std::pair<boost::container::flat_set<IPv6AddressData>::iterator, bool>
              it = ipv6Config.insert(IPv6AddressData{});
          IPv6AddressData& ipv6Address = *it.first;
          ipv6Address.id = objpath.first.str.substr(ipPathStart.size());
          for (const auto& property : interface.second) {
            if (property.first == "Address") {
              const std::string* address =
                  std::get_if<std::string>(&property.second);
              if (address != nullptr) {
                ipv6Address.address = *address;
              }
            } else if (property.first == "Origin") {
              const std::string* origin =
                  std::get_if<std::string>(&property.second);
              if (origin != nullptr) {
                ipv6Address.origin =
                    translateAddressOriginDbusToRedfish(*origin, false);
              }
            } else if (property.first == "PrefixLength") {
              const uint8_t* prefix = std::get_if<uint8_t>(&property.second);
              if (prefix != nullptr) {
                ipv6Address.prefixLength = *prefix;
              }
            } else if (property.first == "Type" ||
                       property.first == "Gateway") {
              // Type & Gateway is not used
            } else {
              BMCWEB_LOG_ERROR << "Got extra property: " << property.first
                               << " on the " << objpath.first.str << " object";
            }
          }
        }
      }
    }
  }
}

// Helper function that extracts data for single ethernet ipv4 address
inline void extractIPData(
    const std::string& ethifaceId,
    const dbus::utility::ManagedObjectType& dbusData,
    boost::container::flat_set<IPv4AddressData>& ipv4Config) {
  const std::string ipPathStart = "/xyz/openbmc_project/network/" + ethifaceId;

  // Since there might be several IPv4 configurations aligned with
  // single ethernet interface, loop over all of them
  for (const auto& objpath : dbusData) {
    // Check if proper pattern for object path appears
    if (objpath.first.str.starts_with(ipPathStart + "/")) {
      for (const auto& interface : objpath.second) {
        if (interface.first == "xyz.openbmc_project.Network.IP") {
          auto type = std::find_if(
              interface.second.begin(), interface.second.end(),
              [](const auto& property) { return property.first == "Type"; });
          if (type == interface.second.end()) {
            continue;
          }

          const std::string* typeStr = std::get_if<std::string>(&type->second);

          if (typeStr == nullptr ||
              (*typeStr != "xyz.openbmc_project.Network.IP.Protocol.IPv4")) {
            continue;
          }

          // Instance IPv4AddressData structure, and set as
          // appropriate
          std::pair<boost::container::flat_set<IPv4AddressData>::iterator, bool>
              it = ipv4Config.insert(IPv4AddressData{});
          IPv4AddressData& ipv4Address = *it.first;
          ipv4Address.id = objpath.first.str.substr(ipPathStart.size());
          for (const auto& property : interface.second) {
            if (property.first == "Address") {
              const std::string* address =
                  std::get_if<std::string>(&property.second);
              if (address != nullptr) {
                ipv4Address.address = *address;
              }
            } else if (property.first == "Origin") {
              const std::string* origin =
                  std::get_if<std::string>(&property.second);
              if (origin != nullptr) {
                ipv4Address.origin =
                    translateAddressOriginDbusToRedfish(*origin, true);
              }
            } else if (property.first == "PrefixLength") {
              const uint8_t* mask = std::get_if<uint8_t>(&property.second);
              if (mask != nullptr) {
                // convert it to the string
                ipv4Address.netmask = getNetmask(*mask);
              }
            } else if (property.first == "Type" ||
                       property.first == "Gateway") {
              // Type & Gateway is not used
            } else {
              BMCWEB_LOG_ERROR << "Got extra property: " << property.first
                               << " on the " << objpath.first.str << " object";
            }
          }
          // Check if given address is local, or global
          ipv4Address.linktype = ipv4Address.address.starts_with("169.254.")
                                     ? LinkType::Local
                                     : LinkType::Global;
        }
      }
    }
  }
}

/**
 * @brief Deletes given IPv4 interface
 *
 * @param[in] ifaceId     Id of interface whose IP should be deleted
 * @param[in] ipHash      DBus Hash id of IP that should be deleted
 * @param[io] asyncResp   Response object that will be returned to client
 *
 * @return None
 */
inline void deleteIPAddress(
    const std::string& ifaceId, const std::string& ipHash,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          messages::internalError(asyncResp->res);
        }
      },
      "xyz.openbmc_project.Network",
      "/xyz/openbmc_project/network/" + ifaceId + ipHash,
      "xyz.openbmc_project.Object.Delete", "Delete");
}

inline void updateIPv4DefaultGateway(
    const std::string& ifaceId, const std::string& gateway,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          messages::internalError(asyncResp->res);
          return;
        }
        asyncResp->res.result(boost::beast::http::status::no_content);
      },
      "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/" + ifaceId,
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.EthernetInterface", "DefaultGateway",
      dbus::utility::DbusVariantType(gateway));
}
/**
 * @brief Creates a static IPv4 entry
 *
 * @param[in] ifaceId      Id of interface upon which to create the IPv4 entry
 * @param[in] prefixLength IPv4 prefix syntax for the subnet mask
 * @param[in] gateway      IPv4 address of this interfaces gateway
 * @param[in] address      IPv4 address to assign to this interface
 * @param[io] asyncResp    Response object that will be returned to client
 *
 * @return None
 */
inline void createIPv4(const std::string& ifaceId, uint8_t prefixLength,
                       const std::string& gateway, const std::string& address,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  auto createIpHandler = [asyncResp, ifaceId,
                          gateway](const boost::system::error_code& ec) {
    if (ec) {
      messages::internalError(asyncResp->res);
      return;
    }
    updateIPv4DefaultGateway(ifaceId, gateway, asyncResp);
  };

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_, std::move(createIpHandler),
      "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/" + ifaceId,
      "xyz.openbmc_project.Network.IP.Create", "IP",
      "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, prefixLength,
      gateway);
}

/**
 * @brief Deletes the IPv6 entry for this interface and creates a replacement
 * static IPv6 entry
 *
 * @param[in] ifaceId      Id of interface upon which to create the IPv6 entry
 * @param[in] id           The unique hash entry identifying the DBus entry
 * @param[in] prefixLength IPv6 prefix syntax for the subnet mask
 * @param[in] address      IPv6 address to assign to this interface
 * @param[io] asyncResp    Response object that will be returned to client
 *
 * @return None
 */

enum class IpVersion : std::uint8_t { IpV4, IpV6 };

inline void deleteAndCreateIPAddress(
    IpVersion version, const std::string& ifaceId, const std::string& id,
    uint8_t prefixLength, const std::string& address,
    const std::string& gateway,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, version, ifaceId, address, prefixLength,
       gateway](const boost::system::error_code& ec) {
        if (ec) {
          messages::internalError(asyncResp->res);
        }
        std::string protocol = "xyz.openbmc_project.Network.IP.Protocol.";
        protocol += version == IpVersion::IpV4 ? "IPv4" : "IPv6";
        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                asyncResp->strand_,
                [asyncResp](const boost::system::error_code& ec2) {
                  if (ec2) {
                    messages::internalError(asyncResp->res);
                  }
                },
                "xyz.openbmc_project.Network",
                "/xyz/openbmc_project/network/" + ifaceId,
                "xyz.openbmc_project.Network.IP.Create", "IP", protocol,
                address, prefixLength, gateway);
      },
      "xyz.openbmc_project.Network",
      "/xyz/openbmc_project/network/" + ifaceId + id,
      "xyz.openbmc_project.Object.Delete", "Delete");
}

/**
 * @brief Creates IPv6 with given data
 *
 * @param[in] ifaceId      Id of interface whose IP should be added
 * @param[in] prefixLength Prefix length that needs to be added
 * @param[in] address      IP address that needs to be added
 * @param[io] asyncResp    Response object that will be returned to client
 *
 * @return None
 */
inline void createIPv6(const std::string& ifaceId, uint8_t prefixLength,
                       const std::string& address,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  auto createIpHandler = [asyncResp](const boost::system::error_code& ec) {
    if (ec) {
      messages::internalError(asyncResp->res);
    }
  };
  // Passing null for gateway, as per redfish spec IPv6StaticAddresses object
  // does not have associated gateway property
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_, std::move(createIpHandler),
      "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/" + ifaceId,
      "xyz.openbmc_project.Network.IP.Create", "IP",
      "xyz.openbmc_project.Network.IP.Protocol.IPv6", address, prefixLength,
      "");
}

/**
 * Function that retrieves all properties for given Ethernet Interface
 * Object
 * from EntityManager Network Manager
 * @param ethiface_id a eth interface id to query on DBus
 * @param callback a function that shall be called to convert Dbus output
 * into JSON
 */
template <typename CallbackFunc>
void getEthernetIfaceData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& ethifaceId,
                          CallbackFunc&& callback) {
  sdbusplus::message::object_path path("/xyz/openbmc_project/network");

  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getManagedObjects(
      "xyz.openbmc_project.Network", path, context,
      [ethifaceId{std::string{ethifaceId}},
       callback{std::forward<CallbackFunc>(callback)}](
          const boost::system::error_code& errorCode,
          const dbus::utility::ManagedObjectType& resp) {
        EthernetInterfaceData ethData{};
        boost::container::flat_set<IPv4AddressData> ipv4Data;
        boost::container::flat_set<IPv6AddressData> ipv6Data;

        if (errorCode) {
          callback(false, ethData, ipv4Data, ipv6Data);
          return;
        }

        bool found = extractEthernetInterfaceData(ethifaceId, resp, ethData);
        if (!found) {
          callback(false, ethData, ipv4Data, ipv6Data);
          return;
        }

        extractIPData(ethifaceId, resp, ipv4Data);
        // Fix global GW
        for (IPv4AddressData& ipv4 : ipv4Data) {
          if (((ipv4.linktype == LinkType::Global) &&
               (ipv4.gateway == "0.0.0.0")) ||
              (ipv4.origin == "DHCP") || (ipv4.origin == "Static")) {
            ipv4.gateway = ethData.defaultGateway;
          }
        }

        extractIPV6Data(ethifaceId, resp, ipv6Data);
        // Finally make a callback with useful data
        callback(true, ethData, ipv4Data, ipv6Data);
      });
}

/**
 * Function that retrieves all Ethernet Interfaces available through Network
 * Manager
 * @param callback a function that shall be called to convert Dbus output
 * into JSON.
 */
template <typename CallbackFunc>
void getEthernetIfaceList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          CallbackFunc&& callback) {
  sdbusplus::message::object_path path("/xyz/openbmc_project/network");

  managedStore::ManagedObjectStoreContext context(asyncResp);
  dbus_utils::getManagedObjects(
      "xyz.openbmc_project.Network", path, context,
      [callback{std::forward<CallbackFunc>(callback)}](
          const boost::system::error_code& errorCode,
          const dbus::utility::ManagedObjectType& resp) {
        // Callback requires vector<string> to retrieve all available
        // ethernet interfaces
        boost::container::flat_set<std::string> ifaceList;
        ifaceList.reserve(resp.size());
        if (errorCode) {
          callback(false, ifaceList);
          return;
        }

        // Iterate over all retrieved ObjectPaths.
        for (const auto& objpath : resp) {
          // And all interfaces available for certain ObjectPath.
          for (const auto& interface : objpath.second) {
            // If interface is
            // xyz.openbmc_project.Network.EthernetInterface, this is
            // what we're looking for.
            if (interface.first ==
                "xyz.openbmc_project.Network.EthernetInterface") {
              std::string ifaceId = objpath.first.filename();
              if (ifaceId.empty()) {
                continue;
              }
              // and put it into output vector.
              ifaceList.emplace(ifaceId);
            }
          }
        }
        // Finally make a callback with useful data
        callback(true, ifaceList);
      });
}

inline 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)
  static 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 bool isDomainnameValid(const std::string& domainname) {
  // Can have multiple subdomains
  // Top Level Domain's min length is 2 character
  static 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);
}

inline 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;
  }

  // Empty HostName resets to the system default hostname.
  if (!hostname.empty() && !isHostnameValid(hostname)) {
    messages::propertyValueFormatError(asyncResp->res, hostname, "HostName");
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [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",
      dbus::utility::DbusVariantType(hostname));
}

inline void handleMTUSizePatch(
    const std::string& ifaceId, const size_t mtuSize,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  sdbusplus::message::object_path objPath =
      "/xyz/openbmc_project/network/" + ifaceId;
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          messages::internalError(asyncResp->res);
        }
      },
      "xyz.openbmc_project.Network", objPath, "org.freedesktop.DBus.Properties",
      "Set", "xyz.openbmc_project.Network.EthernetInterface", "MTU",
      dbus::utility::DbusVariantType{mtuSize});
}

inline void handleDomainnamePatch(
    const std::string& ifaceId, const std::string& domainname,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!isDomainnameValid(domainname)) {
    messages::propertyValueFormatError(asyncResp->res, domainname,
                                       "DomainName");
    return;
  }

  std::vector<std::string> vectorDomainname = {domainname};
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [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",
      dbus::utility::DbusVariantType(vectorDomainname));
}

inline 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);
}

inline void handleMACAddressPatch(
    const std::string& ifaceId, const std::string& macAddress,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  static constexpr std::string_view dbusNotAllowedError =
      "xyz.openbmc_project.Common.Error.NotAllowed";

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, macAddress](const boost::system::error_code& ec,
                              const sdbusplus::message_t& msg) {
        if (ec) {
          const sd_bus_error* err = msg.get_error();
          if (err == nullptr) {
            messages::internalError(asyncResp->res);
            return;
          }
          if (err->name == dbusNotAllowedError) {
            messages::propertyNotWritable(asyncResp->res, "MACAddress");
            return;
          }
          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",
      dbus::utility::DbusVariantType(macAddress));
}

inline 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);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [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,
      dbus::utility::DbusVariantType{dhcp});
}

inline void setEthernetInterfaceBoolProperty(
    const std::string& ifaceId, const std::string& propertyName,
    const bool& value, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [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,
      dbus::utility::DbusVariantType{value});
}

inline void setDHCPConfig(const std::string& propertyName, const bool& value,
                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& ethifaceId, NetworkType type) {
  BMCWEB_LOG_DEBUG << propertyName << " = " << value;
  auto path = sdbusplus::message::object_path("/xyz/openbmc_project/network/") /
              ethifaceId / (type == NetworkType::dhcp4 ? "dhcp4" : "dhcp6");

  sdbusplus::asio::setProperty(
      *(managedStore::GetManagedObjectStore()
            ->GetDeprecatedThreadUnsafeSystemBus()),
      "xyz.openbmc_project.Network", path,
      "xyz.openbmc_project.Network.DHCPConfiguration", propertyName, value,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
      });
}

inline 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 nextDNSv4 = ethData.dnsv4Enabled;
  bool nextDNSv6 = ethData.dnsv6Enabled;
  if (v4dhcpParms.useDnsServers) {
    nextDNSv4 = *v4dhcpParms.useDnsServers;
  }
  if (v6dhcpParms.useDnsServers) {
    nextDNSv6 = *v6dhcpParms.useDnsServers;
  }

  bool nextNTPv4 = ethData.ntpv4Enabled;
  bool nextNTPv6 = ethData.ntpv6Enabled;
  if (v4dhcpParms.useNtpServers) {
    nextNTPv4 = *v4dhcpParms.useNtpServers;
  }
  if (v6dhcpParms.useNtpServers) {
    nextNTPv6 = *v6dhcpParms.useNtpServers;
  }

  bool nextUsev4Domain = ethData.hostNamev4Enabled;
  bool nextUsev6Domain = ethData.hostNamev6Enabled;
  if (v4dhcpParms.useDomainName) {
    nextUsev4Domain = *v4dhcpParms.useDomainName;
  }
  if (v6dhcpParms.useDomainName) {
    nextUsev6Domain = *v6dhcpParms.useDomainName;
  }

  BMCWEB_LOG_DEBUG << "set DHCPEnabled...";
  setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
                 asyncResp);
  BMCWEB_LOG_DEBUG << "set DNSEnabled...";
  setDHCPConfig("DNSEnabled", nextDNSv4, asyncResp, ifaceId,
                NetworkType::dhcp4);
  BMCWEB_LOG_DEBUG << "set NTPEnabled...";
  setDHCPConfig("NTPEnabled", nextNTPv4, asyncResp, ifaceId,
                NetworkType::dhcp4);
  BMCWEB_LOG_DEBUG << "set HostNameEnabled...";
  setDHCPConfig("HostNameEnabled", nextUsev4Domain, asyncResp, ifaceId,
                NetworkType::dhcp4);
  BMCWEB_LOG_DEBUG << "set DNSEnabled for dhcp6...";
  setDHCPConfig("DNSEnabled", nextDNSv6, asyncResp, ifaceId,
                NetworkType::dhcp6);
  BMCWEB_LOG_DEBUG << "set NTPEnabled for dhcp6...";
  setDHCPConfig("NTPEnabled", nextNTPv6, asyncResp, ifaceId,
                NetworkType::dhcp6);
  BMCWEB_LOG_DEBUG << "set HostNameEnabled for dhcp6...";
  setDHCPConfig("HostNameEnabled", nextUsev6Domain, asyncResp, ifaceId,
                NetworkType::dhcp6);
}

inline 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";
  });
}

inline 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";
  });
}

inline 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 (ip_util::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 (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength)) {
          messages::propertyValueFormatError(asyncResp->res, *subnetMask,
                                             pathString + "/SubnetMask");
          errorInEntry = true;
        }
      } else if (nicIpEntry != ipv4Data.cend()) {
        if (!ip_util::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 (ip_util::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()) {
        deleteAndCreateIPAddress(IpVersion::IpV4, ifaceId, nicIpEntry->id,
                                 prefixLength, *addr, *gw, 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()) {
        deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp);
      }
      if (nicIpEntry != ipv4Data.cend()) {
        nicIpEntry = getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
      }
      entryIdx++;
    }
  }
}

inline void handleStaticNameServersPatch(
    const std::string& ifaceId,
    const std::vector<std::string>& updatedStaticNameServers,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [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",
      dbus::utility::DbusVariantType{updatedStaticNameServers});
}

inline 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 = nullptr;
      uint8_t prefix = 0;

      // 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()) {
        deleteAndCreateIPAddress(IpVersion::IpV6, 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()) {
        deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp);
      }
      if (nicIpEntry != ipv6Data.cend()) {
        nicIpEntry = getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
      }
      entryIdx++;
    }
  }
}

inline 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) {
  nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
  jsonResponse["Id"] = ifaceId;
  jsonResponse["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Managers", "bmc", "EthernetInterfaces", ifaceId);
  jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;

#ifdef HEALTH_POPULATE
  constexpr std::array<std::string_view, 1> inventoryForEthernet = {
      "xyz.openbmc_project.Inventory.Item.Ethernet"};
  auto health = std::make_shared<HealthPopulate>(asyncResp);
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, inventoryForEthernet, requestContext,
      [health](const boost::system::error_code& ec,
               const dbus::utility::MapperGetSubTreePathsResponse& resp) {
        if (ec) {
          return;
        }

        health->inventory = resp;
      });

  health->populate();
#endif

  if (ethData.nicEnabled) {
    jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown";
    jsonResponse["Status"]["State"] = "Enabled";
  } else {
    jsonResponse["LinkStatus"] = "NoLink";
    jsonResponse["Status"]["State"] = "Disabled";
  }

  jsonResponse["SpeedMbps"] = ethData.speed;
  jsonResponse["MTUSize"] = ethData.mtuSize;
  jsonResponse["MACAddress"] = ethData.macAddress;
  jsonResponse["DHCPv4"]["DHCPEnabled"] =
      translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
  jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.ntpv4Enabled;
  jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.dnsv4Enabled;
  jsonResponse["DHCPv4"]["UseDomainName"] = ethData.hostNamev4Enabled;

  jsonResponse["DHCPv6"]["OperatingMode"] =
      translateDhcpEnabledToBool(ethData.dhcpEnabled, false) ? "Stateful"
                                                             : "Disabled";
  jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.ntpv6Enabled;
  jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.dnsv6Enabled;
  jsonResponse["DHCPv6"]["UseDomainName"] = ethData.hostNamev6Enabled;

  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"] =
      crow::utility::urlFromPieces("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 (const auto& ipv4Config : ipv4Data) {
    std::string gatewayStr = ipv4Config.gateway;
    if (gatewayStr.empty()) {
      gatewayStr = "0.0.0.0";
    }
    nlohmann::json::object_t ipv4;
    ipv4["AddressOrigin"] = ipv4Config.origin;
    ipv4["SubnetMask"] = ipv4Config.netmask;
    ipv4["Address"] = ipv4Config.address;
    ipv4["Gateway"] = gatewayStr;

    if (ipv4Config.origin == "Static") {
      ipv4StaticArray.push_back(ipv4);
    }

    ipv4Array.push_back(std::move(ipv4));
  }

  std::string ipv6GatewayStr = ethData.ipv6DefaultGateway;
  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 (const auto& ipv6Config : ipv6Data) {
    nlohmann::json::object_t ipv6;
    ipv6["Address"] = ipv6Config.address;
    ipv6["PrefixLength"] = ipv6Config.prefixLength;
    ipv6["AddressOrigin"] = ipv6Config.origin;

    ipv6Array.push_back(std::move(ipv6));
    if (ipv6Config.origin == "Static") {
      nlohmann::json::object_t ipv6Static;
      ipv6Static["Address"] = ipv6Config.address;
      ipv6Static["PrefixLength"] = ipv6Config.prefixLength;
      ipv6StaticArray.push_back(std::move(ipv6Static));
    }
  }
}

inline bool verifyNames(const std::string& parent, const std::string& iface) {
  return iface.starts_with(parent + "_");
}

inline void handleEthernetInterfaceCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  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,
      [asyncResp](const bool& success,
                  const boost::container::flat_set<std::string>& ifaceList) {
        if (!success) {
          messages::internalError(asyncResp->res);
          return;
        }

        nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
        ifaceArray = nlohmann::json::array();
        std::string tag = "_";
        for (const std::string& ifaceItem : ifaceList) {
          std::size_t found = ifaceItem.find(tag);
          if (found == std::string::npos) {
            nlohmann::json::object_t iface;
            iface["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Managers", "bmc",
                                             "EthernetInterfaces", ifaceItem);
            ifaceArray.push_back(std::move(iface));
          }
        }

        asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size();
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Managers/bmc/EthernetInterfaces";
      });
}

inline void handleEthernetInterfacesGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& ifaceId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  getEthernetIfaceData(
      asyncResp, 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;
        }

        // Keep using the v1.6.0 schema here as currently bmcweb have to use
        // "VLANs" property deprecated in v1.7.0 for VLAN creation/deletion.
        asyncResp->res.jsonValue["@odata.type"] =
            "#EthernetInterface.v1_6_0.EthernetInterface";
        asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface";
        asyncResp->res.jsonValue["Description"] =
            "Management Network Interface";

        parseInterfaceData(asyncResp, ifaceId, ethData, ipv4Data, ipv6Data);
      });
}

inline void handleEthernetInterfacesPatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& ifaceId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  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;
  std::optional<size_t> mtuSize;
  DHCPParameters v4dhcpParms;
  DHCPParameters v6dhcpParms;

  if (!json_util::readJsonPatch(
          req, asyncResp->res, "HostName", hostname, "FQDN", fqdn,
          "IPv4StaticAddresses", ipv4StaticAddresses, "MACAddress", macAddress,
          "StaticNameServers", staticNameServers, "IPv6DefaultGateway",
          ipv6DefaultGateway, "IPv6StaticAddresses", ipv6StaticAddresses,
          "DHCPv4", dhcpv4, "DHCPv6", dhcpv6, "MTUSize", mtuSize,
          "InterfaceEnabled", interfaceEnabled)) {
    return;
  }
  if (dhcpv4) {
    if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled",
                             v4dhcpParms.dhcpv4Enabled, "UseDNSServers",
                             v4dhcpParms.useDnsServers, "UseNTPServers",
                             v4dhcpParms.useNtpServers, "UseDomainName",
                             v4dhcpParms.useDomainName)) {
      return;
    }
  }

  if (dhcpv6) {
    if (!json_util::readJson(*dhcpv6, asyncResp->res, "OperatingMode",
                             v6dhcpParms.dhcpv6OperatingMode, "UseDNSServers",
                             v6dhcpParms.useDnsServers, "UseNTPServers",
                             v6dhcpParms.useNtpServers, "UseDomainName",
                             v6dhcpParms.useDomainName)) {
      return;
    }
  }

  // Get single eth interface data, and call the below callback
  // for JSON preparation
  getEthernetIfaceData(
      asyncResp, 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), mtuSize,
       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, "EthernetInterface",
                                     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) {
          const nlohmann::json& ipv6Static = *ipv6StaticAddresses;
          handleIPv6StaticAddressesPatch(ifaceId, ipv6Static, ipv6Data,
                                         asyncResp);
        }

        if (interfaceEnabled) {
          setEthernetInterfaceBoolProperty(ifaceId, "NICEnabled",
                                           *interfaceEnabled, asyncResp);
        }

        if (mtuSize) {
          handleMTUSizePatch(ifaceId, *mtuSize, asyncResp);
        }
      });
}

inline void handleVLanNetworkInterfaceGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& parentIfaceId, const std::string& ifaceId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  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(
      asyncResp, 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.vlanId) {
          asyncResp->res.jsonValue["Id"] = ifaceId;
          asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
              "redfish", "v1", "Managers", "bmc", "EthernetInterfaces",
              parentIfaceId, "VLANs", ifaceId);

          asyncResp->res.jsonValue["VLANEnable"] = ethData.nicEnabled;
          asyncResp->res.jsonValue["VLANId"] = *ethData.vlanId;
        } else {
          // ... otherwise return error
          // TODO(Pawel) consider distinguish between non
          // existing object, and other errors
          messages::resourceNotFound(asyncResp->res, "VLanNetworkInterface",
                                     ifaceId);
        }
      });
}

inline void handleVLanNetworkInterfacePatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& parentIfaceId, const std::string& ifaceId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (!verifyNames(parentIfaceId, ifaceId)) {
    messages::resourceNotFound(asyncResp->res, "VLanNetworkInterface", ifaceId);
    return;
  }

  std::optional<bool> vlanEnable;
  std::optional<uint32_t> vlanId;

  if (!json_util::readJsonPatch(req, asyncResp->res, "VLANEnable", vlanEnable,
                                "VLANId", vlanId)) {
    return;
  }

  if (vlanId) {
    messages::propertyNotWritable(asyncResp->res, "VLANId");
    return;
  }

  // Get single eth interface data, and call the below callback
  // for JSON preparation
  getEthernetIfaceData(
      asyncResp, ifaceId,
      [asyncResp, parentIfaceId, ifaceId, vlanEnable](
          const bool& success, const EthernetInterfaceData& ethData,
          const boost::container::flat_set<IPv4AddressData>&,
          const boost::container::flat_set<IPv6AddressData>&) {
        if (success && ethData.vlanId) {
          if (vlanEnable) {
            managedStore::GetManagedObjectStore()
                ->PostDbusCallToIoContextThreadSafe(
                    asyncResp->strand_,
                    [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",
                    "NICEnabled", dbus::utility::DbusVariantType(*vlanEnable));
          }
        } else {
          // TODO(Pawel) consider distinguish between non
          // existing object, and other errors
          messages::resourceNotFound(asyncResp->res, "VLanNetworkInterface",
                                     ifaceId);
          return;
        }
      });
}

inline void handleVLanNetworkInterfaceDelete(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& parentIfaceId, const std::string& ifaceId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (!verifyNames(parentIfaceId, ifaceId)) {
    messages::resourceNotFound(asyncResp->res, "VLanNetworkInterface", ifaceId);
    return;
  }

  // Get single eth interface data, and call the below callback
  // for JSON preparation
  getEthernetIfaceData(
      asyncResp, 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.vlanId) {
          auto callback = [asyncResp](const boost::system::error_code& ec) {
            if (ec) {
              messages::internalError(asyncResp->res);
            }
          };
          managedStore::GetManagedObjectStore()
              ->PostDbusCallToIoContextThreadSafe(
                  asyncResp->strand_, 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, "VLanNetworkInterface",
                                     ifaceId);
        }
      });
}

inline void handleVLanNetworkInterfaceCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& rootInterfaceName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  // Get eth interface list, and call the below callback for JSON
  // preparation
  getEthernetIfaceList(
      asyncResp, [asyncResp, rootInterfaceName](
                     const bool& success,
                     const boost::container::flat_set<std::string>& ifaceList) {
        if (!success) {
          messages::internalError(asyncResp->res);
          return;
        }

        if (ifaceList.find(rootInterfaceName) == ifaceList.end()) {
          messages::resourceNotFound(asyncResp->res,
                                     "VLanNetworkInterfaceCollection",
                                     rootInterfaceName);
          return;
        }

        asyncResp->res.jsonValue["@odata.type"] =
            "#VLanNetworkInterfaceCollection."
            "VLanNetworkInterfaceCollection";
        asyncResp->res.jsonValue["Name"] = "VLAN Network Interface Collection";

        nlohmann::json ifaceArray = nlohmann::json::array();

        for (const std::string& ifaceItem : ifaceList) {
          if (ifaceItem.starts_with(rootInterfaceName + "_")) {
            nlohmann::json::object_t iface;
            iface["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Managers", "bmc", "EthernetInterfaces",
                rootInterfaceName, "VLANs", ifaceItem);
            ifaceArray.push_back(std::move(iface));
          }
        }

        asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size();
        asyncResp->res.jsonValue["Members"] = std::move(ifaceArray);
        asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Managers", "bmc", "EthernetInterfaces",
            rootInterfaceName, "VLANs");
      });
}

inline void handleVLanNetworkInterfaceCollectionPost(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& rootInterfaceName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  bool vlanEnable = false;
  uint32_t vlanId = 0;
  if (!json_util::readJsonPatch(req, asyncResp->res, "VLANId", vlanId,
                                "VLANEnable", vlanEnable)) {
    return;
  }
  // Need both vlanId and vlanEnable to service this request
  if (vlanId == 0U) {
    messages::propertyMissing(asyncResp->res, "VLANId");
  }
  if (!vlanEnable) {
    messages::propertyMissing(asyncResp->res, "VLANEnable");
  }
  if (static_cast<bool>(vlanId) ^ vlanEnable) {
    return;
  }

  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);
  };
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_, std::move(callback), "xyz.openbmc_project.Network",
      "/xyz/openbmc_project/network", "xyz.openbmc_project.Network.VLAN.Create",
      "VLAN", rootInterfaceName, vlanId);
}

inline void requestEthernetInterfacesRoutes(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
      .privileges(redfish::privileges::getEthernetInterfaceCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleEthernetInterfaceCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
      .privileges(redfish::privileges::getEthernetInterface)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleEthernetInterfacesGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
      .privileges(redfish::privileges::patchEthernetInterface)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handleEthernetInterfacesPatch, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
      .privileges(redfish::privileges::getVLanNetworkInterface)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleVLanNetworkInterfaceGet, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
      .privileges(redfish::privileges::patchVLanNetworkInterface)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handleVLanNetworkInterfacePatch, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
      .privileges(redfish::privileges::deleteVLanNetworkInterface)
      .methods(boost::beast::http::verb::delete_)(
          std::bind_front(handleVLanNetworkInterfaceDelete, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/")

      .privileges(redfish::privileges::getVLanNetworkInterfaceCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleVLanNetworkInterfaceCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/")
      .privileges(redfish::privileges::postVLanNetworkInterfaceCollection)
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleVLanNetworkInterfaceCollectionPost, std::ref(app)));
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_ETHERNET_H_
