diff --git a/app/channel.cpp b/app/channel.cpp
index 7006c92..1fa5b52 100644
--- a/app/channel.cpp
+++ b/app/channel.cpp
@@ -1,6 +1,5 @@
 #include "channel.hpp"
 
-#include "transporthandler.hpp"
 #include "user_channel/channel_layer.hpp"
 
 #include <arpa/inet.h>
diff --git a/apphandler.cpp b/apphandler.cpp
index 0c8eb92..e06a999 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -31,7 +31,6 @@
 #include <sdbusplus/message/types.hpp>
 #include <string>
 #include <sys_info_param.hpp>
-#include <transporthandler.hpp>
 #include <tuple>
 #include <vector>
 #include <xyz/openbmc_project/Common/error.hpp>
diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
index fcc635c..e2f80c0 100644
--- a/include/ipmid/types.hpp
+++ b/include/ipmid/types.hpp
@@ -215,12 +215,7 @@
 
 namespace network
 {
-using ChannelEthMap = std::map<int, std::string>;
-
 constexpr auto MAC_ADDRESS_FORMAT = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
-constexpr auto IP_ADDRESS_FORMAT = "%u.%u.%u.%u";
-constexpr auto PREFIX_FORMAT = "%hhd";
-constexpr auto ADDR_TYPE_FORMAT = "%hhx";
 
 constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4;
 constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16;
@@ -228,20 +223,6 @@
 constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
 constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
 
-constexpr auto MAC_ADDRESS_SIZE_BYTE = 6;
-constexpr auto VLAN_SIZE_BYTE = 2;
-constexpr auto IPSRC_SIZE_BYTE = 1;
-constexpr auto BITS_32 = 32;
-constexpr auto MASK_32_BIT = 0xFFFFFFFF;
-constexpr auto VLAN_ID_MASK = 0x00000FFF;
-constexpr auto VLAN_ENABLE_MASK = 0x8000;
-
-enum class IPOrigin : uint8_t
-{
-    UNSPECIFIED = 0,
-    STATIC = 1,
-    DHCP = 2,
-};
-
 } // namespace network
+
 } // namespace ipmi
diff --git a/include/ipmid/utils.hpp b/include/ipmid/utils.hpp
index 45c9c1a..3515eb6 100644
--- a/include/ipmid/utils.hpp
+++ b/include/ipmid/utils.hpp
@@ -113,20 +113,6 @@
                              const std::string& subtreePath = ROOT,
                              const std::string& match = {});
 
-/** @brief Get the ipObject of first dbus IP object of Non-LinkLocalIPAddress
- *         type from the given subtree, if not available gets IP object of
- *         LinkLocalIPAddress type.
- *  @param[in] bus - DBUS Bus Object.
- *  @param[in] interface - Dbus interface.
- *  @param[in] subtreePath - subtree from where the search should start.
- *  @param[in] match - identifier for object.
- *  @return On success returns the object having objectpath and servicename.
- */
-DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
-                           const std::string& interface,
-                           const std::string& subtreePath,
-                           const std::string& match);
-
 /** @brief Gets the value associated with the given object
  *         and the interface.
  *  @param[in] bus - DBUS Bus Object.
@@ -251,62 +237,6 @@
 
 } // namespace method_no_args
 
-namespace network
-{
-
-constexpr auto ROOT = "/xyz/openbmc_project/network";
-constexpr auto SERVICE = "xyz.openbmc_project.Network";
-constexpr auto IP_TYPE = "ipv4";
-constexpr auto IPV4_PREFIX = "169.254";
-constexpr auto IPV6_PREFIX = "fe80";
-constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
-constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
-constexpr auto SYSTEMCONFIG_INTERFACE =
-    "xyz.openbmc_project.Network.SystemConfiguration";
-constexpr auto ETHERNET_INTERFACE =
-    "xyz.openbmc_project.Network.EthernetInterface";
-constexpr auto IP_CREATE_INTERFACE = "xyz.openbmc_project.Network.IP.Create";
-constexpr auto VLAN_CREATE_INTERFACE =
-    "xyz.openbmc_project.Network.VLAN.Create";
-constexpr auto VLAN_INTERFACE = "xyz.openbmc_project.Network.VLAN";
-
-/* @brief converts the given subnet into prefix notation.
- * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
- * @param[in] mask - Subnet Mask.
- * @returns prefix.
- */
-uint8_t toPrefix(int addressFamily, const std::string& subnetMask);
-
-/** @brief Sets the ip on the system.
- *  @param[in] bus - DBUS Bus Object.
- *  @param[in] service - Dbus service name.
- *  @param[in] objPath - Dbus object path.
- *  @param[in] protocolType - Protocol type
- *  @param[in] ipaddress - IPaddress.
- *  @param[in] prefix - Prefix length.
- */
-void createIP(sdbusplus::bus::bus& bus, const std::string& service,
-              const std::string& objPath, const std::string& protocolType,
-              const std::string& ipaddress, uint8_t prefix);
-
-/** @brief Creates the VLAN on the given interface.
- *  @param[in] bus - DBUS Bus Object.
- *  @param[in] service - Dbus service name.
- *  @param[in] objPath - Dbus object path.
- *  @param[in] interface - EthernetInterface.
- *  @param[in] vlanID - Vlan ID.
- */
-void createVLAN(sdbusplus::bus::bus& bus, const std::string& service,
-                const std::string& objPath, const std::string& interface,
-                uint32_t vlanID);
-
-/** @brief Gets the vlan id from the given object path.
- *  @param[in] path - Dbus object path.
- */
-uint32_t getVLAN(const std::string& path);
-
-} // namespace network
-
 /** @brief Perform the low-level i2c bus write-read.
  *  @param[in] i2cBus - i2c bus device node name, such as /dev/i2c-2.
  *  @param[in] slaveAddr - i2c device slave address.
diff --git a/libipmid/utils.cpp b/libipmid/utils.cpp
index cc4b763..ed493d6 100644
--- a/libipmid/utils.cpp
+++ b/libipmid/utils.cpp
@@ -98,43 +98,6 @@
     return make_pair(found->first, std::move(found->second.begin()->first));
 }
 
-DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
-                           const std::string& interface,
-                           const std::string& serviceRoot,
-                           const std::string& match)
-{
-    auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
-
-    if (objectTree.empty())
-    {
-        log<level::ERR>("No Object has implemented the IP interface",
-                        entry("INTERFACE=%s", interface.c_str()));
-        elog<InternalFailure>();
-    }
-
-    DbusObjectInfo objectInfo;
-
-    for (auto& object : objectTree)
-    {
-        auto variant = ipmi::getDbusProperty(
-            bus, object.second.begin()->first, object.first,
-            ipmi::network::IP_INTERFACE, "Address");
-
-        objectInfo = std::make_pair(object.first, object.second.begin()->first);
-
-        // if LinkLocalIP found look for Non-LinkLocalIP
-        if (ipmi::network::isLinkLocalIP(std::get<std::string>(variant)))
-        {
-            continue;
-        }
-        else
-        {
-            break;
-        }
-    }
-    return objectInfo;
-}
-
 Value getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
                       const std::string& objPath, const std::string& interface,
                       const std::string& property,
@@ -437,117 +400,6 @@
 }
 
 } // namespace method_no_args
-
-namespace network
-{
-
-bool isLinkLocalIP(const std::string& address)
-{
-    return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
-}
-
-void createIP(sdbusplus::bus::bus& bus, const std::string& service,
-              const std::string& objPath, const std::string& protocolType,
-              const std::string& ipaddress, uint8_t prefix)
-{
-    std::string gateway = "";
-
-    auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                         IP_CREATE_INTERFACE, "IP");
-
-    busMethod.append(protocolType, ipaddress, prefix, gateway);
-
-    auto reply = bus.call(busMethod);
-
-    if (reply.is_method_error())
-    {
-        log<level::ERR>("Failed to execute method", entry("METHOD=%s", "IP"),
-                        entry("PATH=%s", objPath.c_str()));
-        elog<InternalFailure>();
-    }
-}
-
-void createVLAN(sdbusplus::bus::bus& bus, const std::string& service,
-                const std::string& objPath, const std::string& interfaceName,
-                uint32_t vlanID)
-{
-    auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                         VLAN_CREATE_INTERFACE, "VLAN");
-
-    busMethod.append(interfaceName, vlanID);
-
-    auto reply = bus.call(busMethod);
-
-    if (reply.is_method_error())
-    {
-        log<level::ERR>("Failed to execute method", entry("METHOD=%s", "VLAN"),
-                        entry("PATH=%s", objPath.c_str()));
-        elog<InternalFailure>();
-    }
-}
-
-uint8_t toPrefix(int addressFamily, const std::string& subnetMask)
-{
-    if (addressFamily == AF_INET6)
-    {
-        return 0;
-    }
-
-    uint32_t buff{};
-
-    auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
-    if (rc <= 0)
-    {
-        log<level::ERR>("inet_pton failed:",
-                        entry("SUBNETMASK=%s", subnetMask.c_str()));
-        return 0;
-    }
-
-    buff = be32toh(buff);
-    // total no of bits - total no of leading zero == total no of ones
-    if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) ==
-        __builtin_popcount(buff))
-    {
-        return __builtin_popcount(buff);
-    }
-    else
-    {
-        log<level::ERR>("Invalid Mask",
-                        entry("SUBNETMASK=%s", subnetMask.c_str()));
-        return 0;
-    }
-}
-
-uint32_t getVLAN(const std::string& path)
-{
-    // Path would be look like
-    // /xyz/openbmc_project/network/eth0_443/ipv4
-
-    uint32_t vlanID = 0;
-    try
-    {
-        auto intfObjectPath = path.substr(0, path.find(IP_TYPE) - 1);
-
-        auto intfName = intfObjectPath.substr(intfObjectPath.rfind("/") + 1);
-
-        auto index = intfName.find("_");
-        if (index != std::string::npos)
-        {
-            auto str = intfName.substr(index + 1);
-            vlanID = std::stoul(str);
-        }
-    }
-    catch (std::exception& e)
-    {
-        log<level::ERR>("Exception occurred during getVLAN",
-                        entry("PATH=%s", path.c_str()),
-                        entry("EXCEPTION=%s", e.what()));
-    }
-    return vlanID;
-}
-
-} // namespace network
-
 ipmi::Cc i2cWriteRead(std::string i2cBus, const uint8_t slaveAddr,
                       std::vector<uint8_t> writeData,
                       std::vector<uint8_t>& readBuf)
diff --git a/transporthandler.cpp b/transporthandler.cpp
index acff251..e88eb63 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1,1023 +1,1181 @@
-#include "transporthandler.hpp"
-
-#include "app/channel.hpp"
-#include "user_channel/channel_layer.hpp"
-
 #include <arpa/inet.h>
+#include <netinet/ether.h>
 
-#include <chrono>
-#include <filesystem>
-#include <fstream>
+#include <array>
+#include <bitset>
+#include <cinttypes>
+#include <cstdint>
+#include <cstring>
+#include <functional>
 #include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+#include <ipmid/message/types.hpp>
+#include <ipmid/types.hpp>
 #include <ipmid/utils.hpp>
+#include <optional>
 #include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
 #include <phosphor-logging/log.hpp>
-#include <sdbusplus/message/types.hpp>
-#include <sdbusplus/timer.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/exception.hpp>
 #include <string>
+#include <string_view>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <user_channel/channel_layer.hpp>
+#include <utility>
+#include <vector>
 #include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/Network/IP/server.hpp>
 
-#define SYSTEMD_NETWORKD_DBUS 1
-
-#ifdef SYSTEMD_NETWORKD_DBUS
-#include <mapper.h>
-#include <systemd/sd-bus.h>
-#endif
-
-// timer for network changes
-std::unique_ptr<phosphor::Timer> networkTimer = nullptr;
-
-const int SIZE_MAC = 18; // xx:xx:xx:xx:xx:xx
-constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
-
-std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig;
-
-using namespace phosphor::logging;
-using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-
-namespace fs = std::filesystem;
-
-void register_netfn_transport_functions() __attribute__((constructor));
-
-struct ChannelConfig_t* getChannelConfig(int channel)
+namespace ipmi
 {
-    auto item = channelConfig.find(channel);
-    if (item == channelConfig.end())
-    {
-        channelConfig[channel] = std::make_unique<struct ChannelConfig_t>();
-    }
+namespace transport
+{
 
-    return channelConfig[channel].get();
+using phosphor::logging::commit;
+using phosphor::logging::elog;
+using phosphor::logging::entry;
+using phosphor::logging::level;
+using phosphor::logging::log;
+using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using sdbusplus::xyz::openbmc_project::Network::server::IP;
+
+// LAN Handler specific response codes
+constexpr Cc ccParamNotSupported = 0x80;
+constexpr Cc ccParamSetLocked = 0x81;
+constexpr Cc ccParamReadOnly = 0x82;
+
+// VLANs are a 12-bit value
+constexpr uint16_t VLAN_VALUE_MASK = 0x0fff;
+constexpr uint16_t VLAN_ENABLE_FLAG = 0x8000;
+
+// D-Bus Network Daemon definitions
+constexpr auto PATH_ROOT = "/xyz/openbmc_project/network";
+constexpr auto PATH_SYSTEMCONFIG = "/xyz/openbmc_project/network/config";
+
+constexpr auto INTF_SYSTEMCONFIG =
+    "xyz.openbmc_project.Network.SystemConfiguration";
+constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface";
+constexpr auto INTF_IP = "xyz.openbmc_project.Network.IP";
+constexpr auto INTF_IP_CREATE = "xyz.openbmc_project.Network.IP.Create";
+constexpr auto INTF_MAC = "xyz.openbmc_project.Network.MACAddress";
+constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN";
+constexpr auto INTF_VLAN_CREATE = "xyz.openbmc_project.Network.VLAN.Create";
+
+/** @brief Generic paramters for different address families */
+template <int family>
+struct AddrFamily
+{
+};
+
+/** @brief Parameter specialization for IPv4 */
+template <>
+struct AddrFamily<AF_INET>
+{
+    using addr = in_addr;
+    static constexpr auto protocol = IP::Protocol::IPv4;
+    static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
+    static constexpr uint8_t defaultPrefix = 32;
+    static constexpr char propertyGateway[] = "DefaultGateway";
+};
+
+/** @brief Valid address origins for IPv4 */
+const std::unordered_set<IP::AddressOrigin> originsV4 = {
+    IP::AddressOrigin::Static,
+    IP::AddressOrigin::DHCP,
+};
+
+/** @brief Interface IP Address configuration parameters */
+template <int family>
+struct IfAddr
+{
+    std::string path;
+    typename AddrFamily<family>::addr address;
+    IP::AddressOrigin origin;
+    uint8_t prefix;
+};
+
+/** @brief IPMI LAN Parameters */
+enum class LanParam : uint8_t
+{
+    SetStatus = 0,
+    AuthSupport = 1,
+    AuthEnables = 2,
+    IP = 3,
+    IPSrc = 4,
+    MAC = 5,
+    SubnetMask = 6,
+    Gateway1 = 12,
+    VLANId = 20,
+    CiphersuiteSupport = 22,
+    CiphersuiteEntries = 23,
+};
+
+/** @brief IPMI IP Origin Types */
+enum class IPSrc : uint8_t
+{
+    Unspecified = 0,
+    Static = 1,
+    DHCP = 2,
+    BIOS = 3,
+    BMC = 4,
+};
+
+/** @brief IPMI Set Status */
+enum class SetStatus : uint8_t
+{
+    Complete = 0,
+    InProgress = 1,
+    Commit = 2,
+};
+
+/** @brief Copies bytes from an array into a trivially copyable container
+ *
+ *  @params[out] t     - The container receiving the data
+ *  @params[in]  bytes - The data to copy
+ */
+template <size_t N, typename T>
+void copyInto(T& t, const std::array<uint8_t, N>& bytes)
+{
+    static_assert(std::is_trivially_copyable_v<T>);
+    static_assert(N == sizeof(T));
+    std::memcpy(&t, bytes.data(), bytes.size());
 }
 
-// Helper Function to get IP Address/NetMask/Gateway/MAC Address from Network
-// Manager or Cache based on Set-In-Progress State
-ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data, int channel)
+/** @brief Gets a generic view of the bytes in the input container
+ *
+ *  @params[in] t - The data to reference
+ *  @return A string_view referencing the bytes in the container
+ */
+template <typename T>
+std::string_view dataRef(const T& t)
 {
-    ipmi_ret_t rc = IPMI_CC_OK;
-    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+    static_assert(std::is_trivially_copyable_v<T>);
+    return {reinterpret_cast<const char*>(&t), sizeof(T)};
+}
 
-    auto ethdevice = ipmi::getChannelName(channel);
-    // if ethdevice is an empty string they weren't expecting this channel.
-    if (ethdevice.empty())
+/** @brief The dbus parameters for the interface corresponding to a channel
+ *         This helps reduce the number of mapper lookups we need for each
+ *         query and simplifies finding the VLAN interface if needed.
+ */
+struct ChannelParams
+{
+    /** @brief The channel ID */
+    int id;
+    /** @brief channel name for the interface */
+    std::string ifname;
+    /** @brief Name of the service on the bus */
+    std::string service;
+    /** @brief Lower level adapter path that is guaranteed to not be a VLAN */
+    std::string ifPath;
+    /** @brief Logical adapter path used for address assignment */
+    std::string logicalPath;
+};
+
+/** @brief Determines the ethernet interface name corresponding to a channel
+ *         Tries to map a VLAN object first so that the address information
+ *         is accurate. Otherwise it gets the standard ethernet interface.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  @return Ethernet interface service and object path if it exists
+ */
+std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus::bus& bus,
+                                                   uint8_t channel)
+{
+    auto ifname = getChannelName(channel);
+    if (ifname.empty())
     {
-        // TODO: return error from getNetworkData()
-        return IPMI_CC_INVALID_FIELD_REQUEST;
+        return std::nullopt;
     }
-    auto ethIP = ethdevice + "/" + ipmi::network::IP_TYPE;
-    auto channelConf = getChannelConfig(channel);
 
+    // Enumerate all VLAN + ETHERNET interfaces
+    auto req = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
+                                   "GetSubTree");
+    req.append(PATH_ROOT, 0,
+               std::vector<std::string>{INTF_VLAN, INTF_ETHERNET});
+    auto reply = bus.call(req);
+    ObjectTree objs;
+    reply.read(objs);
+
+    ChannelParams params;
+    for (const auto& [path, impls] : objs)
+    {
+        if (path.find(ifname) == path.npos)
+        {
+            continue;
+        }
+        for (const auto& [service, intfs] : impls)
+        {
+            bool vlan = false;
+            bool ethernet = false;
+            for (const auto& intf : intfs)
+            {
+                if (intf == INTF_VLAN)
+                {
+                    vlan = true;
+                }
+                else if (intf == INTF_ETHERNET)
+                {
+                    ethernet = true;
+                }
+            }
+            if (params.service.empty() && (vlan || ethernet))
+            {
+                params.service = service;
+            }
+            if (params.ifPath.empty() && !vlan && ethernet)
+            {
+                params.ifPath = path;
+            }
+            if (params.logicalPath.empty() && vlan)
+            {
+                params.logicalPath = path;
+            }
+        }
+    }
+
+    // We must have a path for the underlying interface
+    if (params.ifPath.empty())
+    {
+        return std::nullopt;
+    }
+    // We don't have a VLAN so the logical path is the same
+    if (params.logicalPath.empty())
+    {
+        params.logicalPath = params.ifPath;
+    }
+
+    params.id = channel;
+    params.ifname = std::move(ifname);
+    return std::move(params);
+}
+
+/** @brief A trivial helper around maybeGetChannelParams() that throws an
+ *         exception when it is unable to acquire parameters for the channel.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  @return Ethernet interface service and object path
+ */
+ChannelParams getChannelParams(sdbusplus::bus::bus& bus, uint8_t channel)
+{
+    auto params = maybeGetChannelParams(bus, channel);
+    if (!params)
+    {
+        log<level::ERR>("Failed to get channel params",
+                        entry("CHANNEL=%" PRIu8, channel));
+        elog<InternalFailure>();
+    }
+    return std::move(*params);
+}
+
+/** @brief Wraps the phosphor logging method to insert some additional metadata
+ *
+ *  @param[in] params - The parameters for the channel
+ *  ...
+ */
+template <auto level, typename... Args>
+auto logWithChannel(const ChannelParams& params, Args&&... args)
+{
+    return log<level>(std::forward<Args>(args)...,
+                      entry("CHANNEL=%d", params.id),
+                      entry("IFNAME=%s", params.ifname.c_str()));
+}
+template <auto level, typename... Args>
+auto logWithChannel(const std::optional<ChannelParams>& params, Args&&... args)
+{
+    if (params)
+    {
+        return logWithChannel<level>(*params, std::forward<Args>(args)...);
+    }
+    return log<level>(std::forward<Args>(args)...);
+}
+
+/** @brief Trivializes using parameter getter functions by providing a bus
+ *         and channel parameters automatically.
+ *
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  ...
+ */
+template <auto func, typename... Args>
+auto channelCall(uint8_t channel, Args&&... args)
+{
+    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+    auto params = getChannelParams(bus, channel);
+    return std::invoke(func, bus, params, std::forward<Args>(args)...);
+}
+
+/** @brief Determines if the ethernet interface is using DHCP
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return True if DHCP is enabled, false otherwise
+ */
+bool getDHCPProperty(sdbusplus::bus::bus& bus, const ChannelParams& params)
+{
+    return std::get<bool>(getDbusProperty(
+        bus, params.service, params.logicalPath, INTF_ETHERNET, "DHCPEnabled"));
+}
+
+/** @brief Sets the system value for DHCP on the given interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] on     - Whether or not to enable DHCP
+ */
+void setDHCPProperty(sdbusplus::bus::bus& bus, const ChannelParams& params,
+                     bool on)
+{
+    setDbusProperty(bus, params.service, params.logicalPath, INTF_ETHERNET,
+                    "DHCPEnabled", on);
+}
+
+/** @brief Converts a human readable MAC string into MAC bytes
+ *
+ *  @param[in] mac - The MAC string
+ *  @return MAC in bytes
+ */
+ether_addr stringToMAC(const char* mac)
+{
+    const ether_addr* ret = ether_aton(mac);
+    if (ret == nullptr)
+    {
+        log<level::ERR>("Invalid MAC Address", entry("MAC=%s", mac));
+        elog<InternalFailure>();
+    }
+    return *ret;
+}
+
+/** @brief Determines the MAC of the ethernet interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return The configured mac address
+ */
+ether_addr getMACProperty(sdbusplus::bus::bus& bus, const ChannelParams& params)
+{
+    auto macStr = std::get<std::string>(getDbusProperty(
+        bus, params.service, params.ifPath, INTF_MAC, "MACAddress"));
+    return stringToMAC(macStr.c_str());
+}
+
+/** @brief Sets the system value for MAC address on the given interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] mac    - MAC address to apply
+ */
+void setMACProperty(sdbusplus::bus::bus& bus, const ChannelParams& params,
+                    const ether_addr& mac)
+{
+    std::string macStr = ether_ntoa(&mac);
+    setDbusProperty(bus, params.service, params.ifPath, INTF_MAC, "MACAddress",
+                    macStr);
+}
+
+/** @brief Turns an IP address string into the network byte order form
+ *         NOTE: This version strictly validates family matches
+ *
+ *  @param[in] address - The string form of the address
+ *  @return A network byte order address or none if conversion failed
+ */
+template <int family>
+std::optional<typename AddrFamily<family>::addr>
+    maybeStringToAddr(const char* address)
+{
+    typename AddrFamily<family>::addr ret;
+    if (inet_pton(family, address, &ret) == 1)
+    {
+        return ret;
+    }
+    return std::nullopt;
+}
+
+/** @brief Turns an IP address string into the network byte order form
+ *         NOTE: This version strictly validates family matches
+ *
+ *  @param[in] address - The string form of the address
+ *  @return A network byte order address
+ */
+template <int family>
+typename AddrFamily<family>::addr stringToAddr(const char* address)
+{
+    auto ret = maybeStringToAddr<family>(address);
+    if (!ret)
+    {
+        log<level::ERR>("Failed to convert IP Address",
+                        entry("FAMILY=%d", family),
+                        entry("ADDRESS=%s", address));
+        elog<InternalFailure>();
+    }
+    return *ret;
+}
+
+/** @brief Turns an IP address in network byte order into a string
+ *
+ *  @param[in] address - The string form of the address
+ *  @return A network byte order address
+ */
+template <int family>
+std::string addrToString(const typename AddrFamily<family>::addr& address)
+{
+    std::string ret(AddrFamily<family>::maxStrLen, '\0');
+    inet_ntop(family, &address, ret.data(), ret.size());
+    ret.resize(strlen(ret.c_str()));
+    return ret;
+}
+
+/** @brief Retrieves the current gateway for the address family on the system
+ *         NOTE: The gateway is currently system wide and not per channel
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return An address representing the gateway address if it exists
+ */
+template <int family>
+std::optional<typename AddrFamily<family>::addr>
+    getGatewayProperty(sdbusplus::bus::bus& bus, const ChannelParams& params)
+{
+    auto gatewayStr = std::get<std::string>(getDbusProperty(
+        bus, params.service, PATH_SYSTEMCONFIG, INTF_SYSTEMCONFIG,
+        AddrFamily<family>::propertyGateway));
+    if (gatewayStr.empty())
+    {
+        return std::nullopt;
+    }
+    return stringToAddr<family>(gatewayStr.c_str());
+}
+
+/** @brief Sets the system wide value for the default gateway
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] gateway - Gateway address to apply
+ */
+template <int family>
+void setGatewayProperty(sdbusplus::bus::bus& bus, const ChannelParams& params,
+                        const typename AddrFamily<family>::addr& address)
+{
+    setDbusProperty(bus, params.service, PATH_SYSTEMCONFIG, INTF_SYSTEMCONFIG,
+                    AddrFamily<family>::propertyGateway,
+                    addrToString<family>(address));
+}
+
+/** @brief A lazy lookup mechanism for iterating over object properties stored
+ *         in DBus. This will only perform the object lookup when needed, and
+ *         retains a cache of previous lookups to speed up future iterations.
+ */
+class ObjectLookupCache
+{
+  public:
+    using PropertiesCache = std::unordered_map<std::string, PropertyMap>;
+
+    /** @brief Creates a new ObjectLookupCache for the interface on the bus
+     *         NOTE: The inputs to this object must outlive the object since
+     *         they are only referenced by it.
+     *
+     *  @param[in] bus    - The bus object used for lookups
+     *  @param[in] params - The parameters for the channel
+     *  @param[in] intf   - The interface we are looking up
+     */
+    ObjectLookupCache(sdbusplus::bus::bus& bus, const ChannelParams& params,
+                      const char* intf) :
+        bus(bus),
+        params(params), intf(intf),
+        objs(getAllDbusObjects(bus, params.logicalPath, intf, ""))
+    {
+    }
+
+    class iterator : public ObjectTree::const_iterator
+    {
+      public:
+        using value_type = PropertiesCache::value_type;
+
+        iterator(ObjectTree::const_iterator it, ObjectLookupCache& container) :
+            ObjectTree::const_iterator(it), container(container),
+            ret(container.cache.end())
+        {
+        }
+        value_type& operator*()
+        {
+            ret = container.get(ObjectTree::const_iterator::operator*().first);
+            return *ret;
+        }
+        value_type* operator->()
+        {
+            return &operator*();
+        }
+
+      private:
+        ObjectLookupCache& container;
+        PropertiesCache::iterator ret;
+    };
+
+    iterator begin() noexcept
+    {
+        return iterator(objs.begin(), *this);
+    }
+
+    iterator end() noexcept
+    {
+        return iterator(objs.end(), *this);
+    }
+
+  private:
+    sdbusplus::bus::bus& bus;
+    const ChannelParams& params;
+    const char* const intf;
+    const ObjectTree objs;
+    PropertiesCache cache;
+
+    /** @brief Gets a cached copy of the object properties if possible
+     *         Otherwise performs a query on DBus to look them up
+     *
+     *  @param[in] path - The object path to lookup
+     *  @return An iterator for the specified object path + properties
+     */
+    PropertiesCache::iterator get(const std::string& path)
+    {
+        auto it = cache.find(path);
+        if (it != cache.end())
+        {
+            return it;
+        }
+        auto properties = getAllDbusProperties(bus, params.service, path, intf);
+        return cache.insert({path, std::move(properties)}).first;
+    }
+};
+
+/** @brief Searches the ip object lookup cache for an address matching
+ *         the input parameters. NOTE: The index lacks stability across address
+ *         changes since the network daemon has no notion of stable indicies.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The index of the desired address on the interface
+ *  @param[in] origins - The allowed origins for the address objects
+ *  @param[in] ips     - The object lookup cache holding all of the address info
+ *  @return The address and prefix if it was found
+ */
+template <int family>
+std::optional<IfAddr<family>>
+    findIfAddr(sdbusplus::bus::bus& bus, const ChannelParams& params,
+               uint8_t idx,
+               const std::unordered_set<IP::AddressOrigin>& origins,
+               ObjectLookupCache& ips)
+{
+    for (const auto& [path, properties] : ips)
+    {
+        const auto& addrStr = std::get<std::string>(properties.at("Address"));
+        auto addr = maybeStringToAddr<family>(addrStr.c_str());
+        if (!addr)
+        {
+            continue;
+        }
+
+        IP::AddressOrigin origin = IP::convertAddressOriginFromString(
+            std::get<std::string>(properties.at("Origin")));
+        if (origins.find(origin) == origins.end())
+        {
+            continue;
+        }
+
+        if (idx > 0)
+        {
+            idx--;
+            continue;
+        }
+
+        IfAddr<family> ifaddr;
+        ifaddr.path = path;
+        ifaddr.address = *addr;
+        ifaddr.prefix = std::get<uint8_t>(properties.at("PrefixLength"));
+        ifaddr.origin = origin;
+        return std::move(ifaddr);
+    }
+
+    return std::nullopt;
+}
+
+/** @brief Trivial helper around findIfAddr that simplifies calls
+ *         for one off lookups. Don't use this if you intend to do multiple
+ *         lookups at a time.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] idx     - The index of the desired address on the interface
+ *  @param[in] origins - The allowed origins for the address objects
+ *  @return The address and prefix if it was found
+ */
+template <int family>
+auto getIfAddr(sdbusplus::bus::bus& bus, const ChannelParams& params,
+               uint8_t idx,
+               const std::unordered_set<IP::AddressOrigin>& origins)
+{
+    ObjectLookupCache ips(bus, params, INTF_IP);
+    return findIfAddr<family>(bus, params, idx, origins, ips);
+}
+
+/** @brief Deletes the dbus object. Ignores empty objects or objects that are
+ *         missing from the bus.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] service - The name of the service
+ *  @param[in] path    - The path of the object to delete
+ */
+void deleteObjectIfExists(sdbusplus::bus::bus& bus, const std::string& service,
+                          const std::string& path)
+{
+    if (path.empty())
+    {
+        return;
+    }
     try
     {
-        switch (static_cast<LanParam>(lan_param))
+        auto req = bus.new_method_call(service.c_str(), path.c_str(),
+                                       ipmi::DELETE_INTERFACE, "Delete");
+        bus.call_noreply(req);
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        if (strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0)
         {
-            case LanParam::IP:
-            {
-                std::string ipaddress;
-                if (channelConf->lan_set_in_progress == SET_COMPLETE)
-                {
-                    try
-                    {
-                        auto ipObjectInfo =
-                            ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
-                                              ipmi::network::ROOT, ethIP);
-
-                        auto properties = ipmi::getAllDbusProperties(
-                            bus, ipObjectInfo.second, ipObjectInfo.first,
-                            ipmi::network::IP_INTERFACE);
-
-                        ipaddress =
-                            std::get<std::string>(properties["Address"]);
-                    }
-                    // ignore the exception, as it is a valid condition that
-                    // the system is not configured with any IP.
-                    catch (InternalFailure& e)
-                    {
-                        // nothing to do.
-                    }
-                }
-                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
-                {
-                    ipaddress = channelConf->ipaddr;
-                }
-
-                inet_pton(AF_INET, ipaddress.c_str(),
-                          reinterpret_cast<void*>(data));
-            }
-            break;
-
-            case LanParam::IPSRC:
-            {
-                std::string networkInterfacePath;
-
-                if (channelConf->lan_set_in_progress == SET_COMPLETE)
-                {
-                    try
-                    {
-                        ipmi::ObjectTree ancestorMap;
-                        // if the system is having ip object,then
-                        // get the IP object.
-                        auto ipObject = ipmi::getDbusObject(
-                            bus, ipmi::network::IP_INTERFACE,
-                            ipmi::network::ROOT, ethIP);
-
-                        // Get the parent interface of the IP object.
-                        try
-                        {
-                            ipmi::InterfaceList interfaces;
-                            interfaces.emplace_back(
-                                ipmi::network::ETHERNET_INTERFACE);
-
-                            ancestorMap = ipmi::getAllAncestors(
-                                bus, ipObject.first, std::move(interfaces));
-                        }
-                        catch (InternalFailure& e)
-                        {
-                            // if unable to get the parent interface
-                            // then commit the error and return.
-                            log<level::ERR>(
-                                "Unable to get the parent interface",
-                                entry("PATH=%s", ipObject.first.c_str()),
-                                entry("INTERFACE=%s",
-                                      ipmi::network::ETHERNET_INTERFACE));
-                            break;
-                        }
-                        // for an ip object there would be single parent
-                        // interface.
-                        networkInterfacePath = ancestorMap.begin()->first;
-                    }
-                    catch (InternalFailure& e)
-                    {
-                        // if there is no ip configured on the system,then
-                        // get the network interface object.
-                        auto networkInterfaceObject = ipmi::getDbusObject(
-                            bus, ipmi::network::ETHERNET_INTERFACE,
-                            ipmi::network::ROOT, ethdevice);
-
-                        networkInterfacePath = networkInterfaceObject.first;
-                    }
-
-                    auto variant = ipmi::getDbusProperty(
-                        bus, ipmi::network::SERVICE, networkInterfacePath,
-                        ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled");
-
-                    auto dhcpEnabled = std::get<bool>(variant);
-                    // As per IPMI spec 2=>DHCP, 1=STATIC
-                    auto ipsrc = dhcpEnabled ? ipmi::network::IPOrigin::DHCP
-                                             : ipmi::network::IPOrigin::STATIC;
-
-                    std::memcpy(data, &ipsrc, ipmi::network::IPSRC_SIZE_BYTE);
-                }
-                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
-                {
-                    std::memcpy(data, &(channelConf->ipsrc),
-                                ipmi::network::IPSRC_SIZE_BYTE);
-                }
-            }
-            break;
-
-            case LanParam::SUBNET:
-            {
-                unsigned long mask{};
-                if (channelConf->lan_set_in_progress == SET_COMPLETE)
-                {
-                    try
-                    {
-                        auto ipObjectInfo =
-                            ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
-                                              ipmi::network::ROOT, ethIP);
-
-                        auto properties = ipmi::getAllDbusProperties(
-                            bus, ipObjectInfo.second, ipObjectInfo.first,
-                            ipmi::network::IP_INTERFACE);
-
-                        auto prefix =
-                            std::get<uint8_t>(properties["PrefixLength"]);
-                        mask = ipmi::network::MASK_32_BIT;
-                        mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
-                    }
-                    // ignore the exception, as it is a valid condition that
-                    // the system is not configured with any IP.
-                    catch (InternalFailure& e)
-                    {
-                        // nothing to do
-                    }
-                    std::memcpy(data, &mask,
-                                ipmi::network::IPV4_ADDRESS_SIZE_BYTE);
-                }
-                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
-                {
-                    inet_pton(AF_INET, channelConf->netmask.c_str(),
-                              reinterpret_cast<void*>(data));
-                }
-            }
-            break;
-
-            case LanParam::GATEWAY:
-            {
-                std::string gateway;
-
-                if (channelConf->lan_set_in_progress == SET_COMPLETE)
-                {
-                    try
-                    {
-                        auto systemObject = ipmi::getDbusObject(
-                            bus, ipmi::network::SYSTEMCONFIG_INTERFACE,
-                            ipmi::network::ROOT);
-
-                        auto systemProperties = ipmi::getAllDbusProperties(
-                            bus, systemObject.second, systemObject.first,
-                            ipmi::network::SYSTEMCONFIG_INTERFACE);
-
-                        gateway = std::get<std::string>(
-                            systemProperties["DefaultGateway"]);
-                    }
-                    // ignore the exception, as it is a valid condition that
-                    // the system is not configured with any IP.
-                    catch (InternalFailure& e)
-                    {
-                        // nothing to do
-                    }
-                }
-                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
-                {
-                    gateway = channelConf->gateway;
-                }
-
-                inet_pton(AF_INET, gateway.c_str(),
-                          reinterpret_cast<void*>(data));
-            }
-            break;
-
-            case LanParam::MAC:
-            {
-                std::string macAddress;
-                if (channelConf->lan_set_in_progress == SET_COMPLETE)
-                {
-                    auto macObjectInfo =
-                        ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
-                                            ipmi::network::ROOT, ethdevice);
-
-                    auto variant = ipmi::getDbusProperty(
-                        bus, macObjectInfo.second, macObjectInfo.first,
-                        ipmi::network::MAC_INTERFACE, "MACAddress");
-
-                    macAddress = std::get<std::string>(variant);
-                }
-                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
-                {
-                    macAddress = channelConf->macAddress;
-                }
-
-                sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
-                       (data), (data + 1), (data + 2), (data + 3), (data + 4),
-                       (data + 5));
-            }
-            break;
-
-            case LanParam::VLAN:
-            {
-                uint16_t vlanID{};
-                if (channelConf->lan_set_in_progress == SET_COMPLETE)
-                {
-                    try
-                    {
-                        auto ipObjectInfo = ipmi::getIPObject(
-                            bus, ipmi::network::IP_INTERFACE,
-                            ipmi::network::ROOT, ipmi::network::IP_TYPE);
-
-                        vlanID = static_cast<uint16_t>(
-                            ipmi::network::getVLAN(ipObjectInfo.first));
-
-                        vlanID = htole16(vlanID);
-
-                        if (vlanID)
-                        {
-                            // Enable the 16th bit
-                            vlanID |= htole16(ipmi::network::VLAN_ENABLE_MASK);
-                        }
-                    }
-                    // ignore the exception, as it is a valid condition that
-                    // the system is not configured with any IP.
-                    catch (InternalFailure& e)
-                    {
-                        // nothing to do
-                    }
-
-                    std::memcpy(data, &vlanID, ipmi::network::VLAN_SIZE_BYTE);
-                }
-                else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
-                {
-                    std::memcpy(data, &(channelConf->vlanID),
-                                ipmi::network::VLAN_SIZE_BYTE);
-                }
-            }
-            break;
-
-            default:
-                rc = IPMI_CC_PARM_OUT_OF_RANGE;
+            // We want to rethrow real errors
+            throw;
         }
     }
-    catch (InternalFailure& e)
-    {
-        commit<InternalFailure>();
-        rc = IPMI_CC_UNSPECIFIED_ERROR;
-        return rc;
-    }
-    return rc;
 }
 
-namespace cipher
+/** @brief Sets the address info configured for the interface
+ *         If a previous address path exists then it will be removed
+ *         before the new address is added.
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] address - The address of the new IP
+ *  @param[in] prefix  - The prefix of the new IP
+ */
+template <int family>
+void createIfAddr(sdbusplus::bus::bus& bus, const ChannelParams& params,
+                  const typename AddrFamily<family>::addr& address,
+                  uint8_t prefix)
 {
+    auto newreq =
+        bus.new_method_call(params.service.c_str(), params.logicalPath.c_str(),
+                            INTF_IP_CREATE, "IP");
+    std::string protocol =
+        sdbusplus::xyz::openbmc_project::Network::server::convertForMessage(
+            AddrFamily<family>::protocol);
+    newreq.append(protocol, addrToString<family>(address), prefix, "");
+    bus.call_noreply(newreq);
+}
 
-std::vector<uint8_t> getCipherList()
+/** @brief Trivial helper for getting the IPv4 address from getIfAddrs()
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return The address and prefix if found
+ */
+auto getIfAddr4(sdbusplus::bus::bus& bus, const ChannelParams& params)
 {
-    std::vector<uint8_t> cipherList;
+    return getIfAddr<AF_INET>(bus, params, 0, originsV4);
+}
 
-    std::ifstream jsonFile(configFile);
-    if (!jsonFile.is_open())
+/** @brief Reconfigures the IPv4 address info configured for the interface
+ *
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] address - The new address if specified
+ *  @param[in] prefix  - The new address prefix if specified
+ */
+void reconfigureIfAddr4(sdbusplus::bus::bus& bus, const ChannelParams& params,
+                        const std::optional<in_addr>& address,
+                        std::optional<uint8_t> prefix)
+{
+    auto ifaddr = getIfAddr4(bus, params);
+    if (!ifaddr && !address)
     {
-        log<level::ERR>("Channel Cipher suites file not found");
+        log<level::ERR>("Missing address for IPv4 assignment");
         elog<InternalFailure>();
     }
-
-    auto data = Json::parse(jsonFile, nullptr, false);
-    if (data.is_discarded())
+    uint8_t fallbackPrefix = AddrFamily<AF_INET>::defaultPrefix;
+    if (ifaddr)
     {
-        log<level::ERR>("Parsing channel cipher suites JSON failed");
+        fallbackPrefix = ifaddr->prefix;
+        deleteObjectIfExists(bus, params.service, ifaddr->path);
+    }
+    createIfAddr<AF_INET>(bus, params, address.value_or(ifaddr->address),
+                          prefix.value_or(fallbackPrefix));
+}
+
+/** @brief Gets the vlan ID configured on the interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @return VLAN id or the standard 0 for no VLAN
+ */
+uint16_t getVLANProperty(sdbusplus::bus::bus& bus, const ChannelParams& params)
+{
+    // VLAN devices will always have a separate logical object
+    if (params.ifPath == params.logicalPath)
+    {
+        return 0;
+    }
+
+    auto vlan = std::get<uint32_t>(getDbusProperty(
+        bus, params.service, params.logicalPath, INTF_VLAN, "Id"));
+    if ((vlan & VLAN_VALUE_MASK) != vlan)
+    {
+        logWithChannel<level::ERR>(params, "networkd returned an invalid vlan",
+                                   entry("VLAN=%" PRIu32, vlan));
         elog<InternalFailure>();
     }
-
-    // Byte 1 is reserved
-    cipherList.push_back(0x00);
-
-    for (const auto& record : data)
-    {
-        cipherList.push_back(record.value(cipher, 0));
-    }
-
-    return cipherList;
+    return vlan;
 }
 
-} // namespace cipher
-
-ipmi_ret_t ipmi_transport_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                                   ipmi_request_t request,
-                                   ipmi_response_t response,
-                                   ipmi_data_len_t data_len,
-                                   ipmi_context_t context)
+/** @brief Deletes all of the possible configuration parameters for a channel
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ */
+void deconfigureChannel(sdbusplus::bus::bus& bus, ChannelParams& params)
 {
-    // Status code.
-    ipmi_ret_t rc = IPMI_CC_INVALID;
-    *data_len = 0;
-    return rc;
+    // Delete all objects associated with the interface
+    auto objreq = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF,
+                                      "GetSubTree");
+    objreq.append(PATH_ROOT, 0, std::vector<std::string>{DELETE_INTERFACE});
+    auto objreply = bus.call(objreq);
+    ObjectTree objs;
+    objreply.read(objs);
+    for (const auto& [path, impls] : objs)
+    {
+        if (path.find(params.ifname) == path.npos)
+        {
+            continue;
+        }
+        for (const auto& [service, intfs] : impls)
+        {
+            deleteObjectIfExists(bus, service, path);
+        }
+        // Update params to reflect the deletion of vlan
+        if (path == params.logicalPath)
+        {
+            params.logicalPath = params.ifPath;
+        }
+    }
+
+    // Clear out any settings on the lower physical interface
+    setDHCPProperty(bus, params, false);
 }
 
-struct set_lan_t
+/** @brief Creates a new VLAN on the specified interface
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] vlan   - The id of the new vlan
+ */
+void createVLAN(sdbusplus::bus::bus& bus, ChannelParams& params, uint16_t vlan)
 {
-    uint8_t channel;
-    uint8_t parameter;
-    uint8_t data[8]; // Per IPMI spec, not expecting more than this size
-} __attribute__((packed));
-
-ipmi_ret_t checkAndUpdateNetwork(int channel)
-{
-    auto channelConf = getChannelConfig(channel);
-    using namespace std::chrono_literals;
-    // time to wait before applying the network changes.
-    constexpr auto networkTimeout = 10000000us; // 10 sec
-
-    // Skip the timer. Expecting more update as we are in SET_IN_PROGRESS
-    if (channelConf->lan_set_in_progress == SET_IN_PROGRESS)
+    if (vlan == 0)
     {
-        return IPMI_CC_OK;
+        return;
     }
 
-    // Start the timer, if it is direct single param update without
-    // SET_IN_PROGRESS or many params updated through SET_IN_PROGRESS to
-    // SET_COMPLETE Note: Even for update with SET_IN_PROGRESS, don't apply the
-    // changes immediately, as ipmitool sends each param individually
-    // through SET_IN_PROGRESS to SET_COMPLETE.
-    channelConf->flush = true;
-    if (!networkTimer)
-    {
-        log<level::ERR>("Network timer is not instantiated");
-        return IPMI_CC_UNSPECIFIED_ERROR;
-    }
-    // start the timer.
-    networkTimer->start(networkTimeout);
-    return IPMI_CC_OK;
+    auto req = bus.new_method_call(params.service.c_str(), PATH_ROOT,
+                                   INTF_VLAN_CREATE, "VLAN");
+    req.append(params.ifname, static_cast<uint32_t>(vlan));
+    auto reply = bus.call(req);
+    sdbusplus::message::object_path newPath;
+    reply.read(newPath);
+    params.logicalPath = std::move(newPath);
 }
 
-ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                                  ipmi_request_t request,
-                                  ipmi_response_t response,
-                                  ipmi_data_len_t data_len,
-                                  ipmi_context_t context)
+/** @brief Performs the necessary reconfiguration to change the VLAN
+ *
+ *  @param[in] bus    - The bus object used for lookups
+ *  @param[in] params - The parameters for the channel
+ *  @param[in] vlan   - The new vlan id to use
+ */
+void reconfigureVLAN(sdbusplus::bus::bus& bus, ChannelParams& params,
+                     uint16_t vlan)
 {
-    ipmi_ret_t rc = IPMI_CC_OK;
+    // Unfortunatetly we don't have built-in functions to migrate our interface
+    // customizations to new VLAN interfaces, or have some kind of decoupling.
+    // We therefore must retain all of our old information, setup the new VLAN
+    // configuration, then restore the old info.
 
-    char ipaddr[INET_ADDRSTRLEN];
-    char netmask[INET_ADDRSTRLEN];
-    char gateway[INET_ADDRSTRLEN];
+    // Save info from the old logical interface
+    ObjectLookupCache ips(bus, params, INTF_IP);
+    auto ifaddr4 = findIfAddr<AF_INET>(bus, params, 0, originsV4, ips);
+    auto dhcp = getDHCPProperty(bus, params);
 
-    auto reqptr = reinterpret_cast<const set_lan_t*>(request);
-    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+    deconfigureChannel(bus, params);
+    createVLAN(bus, params, vlan);
 
-    size_t reqLen = *data_len;
-    *data_len = 0;
-
-    // channel number is the lower nibble
-    int channel = reqptr->channel & CHANNEL_MASK;
-    auto ethdevice = ipmi::getChannelName(channel);
-    ipmi::ChannelInfo chInfo;
-    ipmi::getChannelInfo(channel, chInfo);
-
-    if (ethdevice.empty() ||
-        chInfo.mediumType !=
-            static_cast<uint8_t>(ipmi::EChannelMediumType::lan8032))
+    // Re-establish the saved settings
+    setDHCPProperty(bus, params, dhcp);
+    if (ifaddr4)
     {
-        return IPMI_CC_INVALID_FIELD_REQUEST;
+        createIfAddr<AF_INET>(bus, params, ifaddr4->address, ifaddr4->prefix);
     }
-    auto channelConf = getChannelConfig(channel);
+}
 
-    switch (static_cast<LanParam>(reqptr->parameter))
+/** @brief Turns a prefix into a netmask
+ *
+ *  @param[in] prefix - The prefix length
+ *  @return The netmask
+ */
+in_addr prefixToNetmask(uint8_t prefix)
+{
+    if (prefix > 32)
     {
+        log<level::ERR>("Invalid prefix", entry("PREFIX=%" PRIu8, prefix));
+        elog<InternalFailure>();
+    }
+    if (prefix == 0)
+    {
+        // Avoids 32-bit lshift by 32 UB
+        return {};
+    }
+    return {htobe32(~UINT32_C(0) << (32 - prefix))};
+}
+
+/** @brief Turns a a netmask into a prefix length
+ *
+ *  @param[in] netmask - The netmask in byte form
+ *  @return The prefix length
+ */
+uint8_t netmaskToPrefix(in_addr netmask)
+{
+    uint32_t x = be32toh(netmask.s_addr);
+    if ((~x & (~x + 1)) != 0)
+    {
+        char maskStr[INET_ADDRSTRLEN];
+        inet_ntop(AF_INET, &netmask, maskStr, sizeof(maskStr));
+        log<level::ERR>("Invalid netmask", entry("NETMASK=%s", maskStr));
+        elog<InternalFailure>();
+    }
+    return 32 - __builtin_ctz(x);
+}
+
+// We need to store this value so it can be returned to the client
+// It is volatile so safe to store in daemon memory.
+static std::unordered_map<uint8_t, SetStatus> setStatus;
+
+// Until we have good support for fixed versions of IPMI tool
+// we need to return the VLAN id for disabled VLANs. The value is only
+// used for verification that a disable operation succeeded and will only
+// be sent if our system indicates that vlans are disabled.
+static std::unordered_map<uint8_t, uint16_t> lastDisabledVlan;
+
+/** @brief Gets the set status for the channel if it exists
+ *         Otherise populates and returns the default value.
+ *
+ *  @param[in] channel - The channel id corresponding to an ethernet interface
+ *  @return A reference to the SetStatus for the channel
+ */
+SetStatus& getSetStatus(uint8_t channel)
+{
+    auto it = setStatus.find(channel);
+    if (it != setStatus.end())
+    {
+        return it->second;
+    }
+    return setStatus[channel] = SetStatus::Complete;
+}
+
+RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
+                 message::Payload& req)
+{
+    auto channel = static_cast<uint8_t>(channelBits);
+    if (!doesDeviceExist(channel))
+    {
+        req.trailingOk = true;
+        return responseInvalidFieldRequest();
+    }
+
+    switch (static_cast<LanParam>(parameter))
+    {
+        case LanParam::SetStatus:
+        {
+            uint2_t flag;
+            uint6_t rsvd;
+            if (req.unpack(flag, rsvd) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+            auto status = static_cast<SetStatus>(static_cast<uint8_t>(flag));
+            switch (status)
+            {
+                case SetStatus::Complete:
+                {
+                    getSetStatus(channel) = status;
+                    return responseSuccess();
+                }
+                case SetStatus::InProgress:
+                {
+                    auto& storedStatus = getSetStatus(channel);
+                    if (storedStatus == SetStatus::InProgress)
+                    {
+                        return response(ccParamSetLocked);
+                    }
+                    storedStatus = status;
+                    return responseSuccess();
+                }
+                case SetStatus::Commit:
+                    if (getSetStatus(channel) != SetStatus::InProgress)
+                    {
+                        return responseInvalidFieldRequest();
+                    }
+                    return responseSuccess();
+            }
+            return response(ccParamNotSupported);
+        }
+        case LanParam::AuthSupport:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
+        }
+        case LanParam::AuthEnables:
+        {
+            req.trailingOk = true;
+            return response(ccParamNotSupported);
+        }
         case LanParam::IP:
         {
-            std::snprintf(ipaddr, INET_ADDRSTRLEN,
-                          ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0],
-                          reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-
-            channelConf->ipaddr.assign(ipaddr);
+            in_addr ip;
+            std::array<uint8_t, sizeof(ip)> bytes;
+            if (req.unpack(bytes) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+            copyInto(ip, bytes);
+            channelCall<reconfigureIfAddr4>(channel, ip, std::nullopt);
+            return responseSuccess();
         }
-        break;
-
-        case LanParam::IPSRC:
+        case LanParam::IPSrc:
         {
-            uint8_t ipsrc{};
-            std::memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE);
-            channelConf->ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc);
+            uint4_t flag;
+            uint4_t rsvd;
+            if (req.unpack(flag, rsvd) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+            switch (static_cast<IPSrc>(static_cast<uint8_t>(flag)))
+            {
+                case IPSrc::DHCP:
+                {
+                    channelCall<setDHCPProperty>(channel, true);
+                    return responseSuccess();
+                }
+                case IPSrc::Unspecified:
+                case IPSrc::Static:
+                case IPSrc::BIOS:
+                case IPSrc::BMC:
+                {
+                    channelCall<setDHCPProperty>(channel, false);
+                    return responseSuccess();
+                }
+            }
+            return response(ccParamNotSupported);
         }
-        break;
-
         case LanParam::MAC:
         {
-            char mac[SIZE_MAC];
-
-            std::snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
-                          reqptr->data[0], reqptr->data[1], reqptr->data[2],
-                          reqptr->data[3], reqptr->data[4], reqptr->data[5]);
-
-            auto macObjectInfo =
-                ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
-                                    ipmi::network::ROOT, ethdevice);
-
-            ipmi::setDbusProperty(
-                bus, macObjectInfo.second, macObjectInfo.first,
-                ipmi::network::MAC_INTERFACE, "MACAddress", std::string(mac));
-
-            channelConf->macAddress = mac;
-        }
-        break;
-
-        case LanParam::SUBNET:
-        {
-            std::snprintf(netmask, INET_ADDRSTRLEN,
-                          ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0],
-                          reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-            channelConf->netmask.assign(netmask);
-        }
-        break;
-
-        case LanParam::GATEWAY:
-        {
-            std::snprintf(gateway, INET_ADDRSTRLEN,
-                          ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0],
-                          reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-            channelConf->gateway.assign(gateway);
-        }
-        break;
-
-        case LanParam::VLAN:
-        {
-            if (reqLen != lanParamVLANSize)
+            ether_addr mac;
+            std::array<uint8_t, sizeof(mac)> bytes;
+            if (req.unpack(bytes) != 0 || !req.fullyUnpacked())
             {
-                return IPMI_CC_REQ_DATA_LEN_INVALID;
+                return responseReqDataLenInvalid();
             }
-
-            uint16_t vlan{};
-            std::memcpy(&vlan, reqptr->data, ipmi::network::VLAN_SIZE_BYTE);
-            // We are not storing the enable bit
-            // We assume that ipmitool always send enable
-            // bit as 1.
-            vlan = le16toh(vlan);
-            if (vlan == 0 || vlan > maxValidVLANIDValue)
-            {
-                return IPMI_CC_INVALID_FIELD_REQUEST;
-            }
-            channelConf->vlanID = vlan;
+            copyInto(mac, bytes);
+            channelCall<setMACProperty>(channel, mac);
+            return responseSuccess();
         }
-        break;
-
-        case LanParam::INPROGRESS:
+        case LanParam::SubnetMask:
         {
-            if (reqptr->data[0] == SET_COMPLETE)
+            in_addr netmask;
+            std::array<uint8_t, sizeof(netmask)> bytes;
+            if (req.unpack(bytes) != 0 || !req.fullyUnpacked())
             {
-                channelConf->lan_set_in_progress = SET_COMPLETE;
-
-                log<level::INFO>(
-                    "Network data from Cache",
-                    entry("PREFIX=%s", channelConf->netmask.c_str()),
-                    entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
-                    entry("GATEWAY=%s", channelConf->gateway.c_str()),
-                    entry("VLAN=%d", channelConf->vlanID));
+                return responseReqDataLenInvalid();
             }
-            else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
-            {
-                channelConf->lan_set_in_progress = SET_IN_PROGRESS;
-            }
+            copyInto(netmask, bytes);
+            channelCall<reconfigureIfAddr4>(channel, std::nullopt,
+                                            netmaskToPrefix(netmask));
+            return responseSuccess();
         }
-        break;
-
-        default:
+        case LanParam::Gateway1:
         {
-            rc = IPMI_CC_PARM_NOT_SUPPORTED;
-            return rc;
+            in_addr gateway;
+            std::array<uint8_t, sizeof(gateway)> bytes;
+            if (req.unpack(bytes) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+            copyInto(gateway, bytes);
+            channelCall<setGatewayProperty<AF_INET>>(channel, gateway);
+            return responseSuccess();
+        }
+        case LanParam::VLANId:
+        {
+            uint16_t vlanData;
+            if (req.unpack(vlanData) != 0 || !req.fullyUnpacked())
+            {
+                return responseReqDataLenInvalid();
+            }
+            if ((vlanData & VLAN_ENABLE_FLAG) == 0)
+            {
+                lastDisabledVlan[channel] = vlanData & VLAN_VALUE_MASK;
+                vlanData = 0;
+            }
+            channelCall<reconfigureVLAN>(channel, vlanData & VLAN_VALUE_MASK);
+            return responseSuccess();
+        }
+        case LanParam::CiphersuiteSupport:
+        case LanParam::CiphersuiteEntries:
+        {
+            req.trailingOk = true;
+            return response(ccParamReadOnly);
         }
     }
-    rc = checkAndUpdateNetwork(channel);
 
-    return rc;
+    req.trailingOk = true;
+    return response(ccParamNotSupported);
 }
 
-struct get_lan_t
+RspType<message::Payload> getLan(uint4_t channelBits, uint3_t, bool revOnly,
+                                 uint8_t parameter, uint8_t set, uint8_t block)
 {
-    uint8_t rev_channel;
-    uint8_t parameter;
-    uint8_t parameter_set;
-    uint8_t parameter_block;
-} __attribute__((packed));
+    message::Payload ret;
+    constexpr uint8_t current_revision = 0x11;
+    ret.pack(current_revision);
 
-ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                                  ipmi_request_t request,
-                                  ipmi_response_t response,
-                                  ipmi_data_len_t data_len,
-                                  ipmi_context_t context)
-{
-    ipmi_ret_t rc = IPMI_CC_OK;
-    *data_len = 0;
-    const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
-
-    get_lan_t* reqptr = (get_lan_t*)request;
-    // channel number is the lower nibble
-    int channel = reqptr->rev_channel & CHANNEL_MASK;
-    ipmi::ChannelInfo chInfo;
-    ipmi::getChannelInfo(channel, chInfo);
-    if (chInfo.mediumType !=
-        static_cast<uint8_t>(ipmi::EChannelMediumType::lan8032))
+    if (revOnly)
     {
-        return IPMI_CC_INVALID_FIELD_REQUEST;
+        return responseSuccess(std::move(ret));
     }
 
-    if (reqptr->rev_channel & 0x80) // Revision is bit 7
+    auto channel = static_cast<uint8_t>(channelBits);
+    if (!doesDeviceExist(channel))
     {
-        // Only current revision was requested
-        *data_len = sizeof(current_revision);
-        std::memcpy(response, &current_revision, *data_len);
-        return IPMI_CC_OK;
+        return responseInvalidFieldRequest();
     }
 
-    static std::vector<uint8_t> cipherList;
-    static auto listInit = false;
-
-    if (!listInit)
+    switch (static_cast<LanParam>(parameter))
     {
-        try
+        case LanParam::SetStatus:
         {
-            cipherList = cipher::getCipherList();
-            listInit = true;
+            SetStatus status;
+            try
+            {
+                status = setStatus.at(channel);
+            }
+            catch (const std::out_of_range&)
+            {
+                status = SetStatus::Complete;
+            }
+            ret.pack(static_cast<uint2_t>(status), uint6_t{});
+            return responseSuccess(std::move(ret));
         }
-        catch (const std::exception& e)
+        case LanParam::AuthSupport:
         {
-            return IPMI_CC_UNSPECIFIED_ERROR;
+            std::bitset<6> support;
+            ret.pack(support, uint2_t{});
+            return responseSuccess(std::move(ret));
         }
-    }
-
-    auto ethdevice = ipmi::getChannelName(channel);
-    if (ethdevice.empty())
-    {
-        return IPMI_CC_INVALID_FIELD_REQUEST;
-    }
-    auto channelConf = getChannelConfig(channel);
-
-    LanParam param = static_cast<LanParam>(reqptr->parameter);
-    switch (param)
-    {
-        case LanParam::INPROGRESS:
+        case LanParam::AuthEnables:
         {
-            uint8_t buf[] = {current_revision,
-                             channelConf->lan_set_in_progress};
-            *data_len = sizeof(buf);
-            std::memcpy(response, &buf, *data_len);
-            break;
-        }
-        case LanParam::AUTHSUPPORT:
-        {
-            uint8_t buf[] = {current_revision, 0x04};
-            *data_len = sizeof(buf);
-            std::memcpy(response, &buf, *data_len);
-            break;
-        }
-        case LanParam::AUTHENABLES:
-        {
-            uint8_t buf[] = {current_revision, 0x04, 0x04, 0x04, 0x04, 0x04};
-            *data_len = sizeof(buf);
-            std::memcpy(response, &buf, *data_len);
-            break;
+            std::bitset<6> enables;
+            ret.pack(enables, uint2_t{}); // Callback
+            ret.pack(enables, uint2_t{}); // User
+            ret.pack(enables, uint2_t{}); // Operator
+            ret.pack(enables, uint2_t{}); // Admin
+            ret.pack(enables, uint2_t{}); // OEM
+            return responseSuccess(std::move(ret));
         }
         case LanParam::IP:
-        case LanParam::SUBNET:
-        case LanParam::GATEWAY:
+        {
+            auto ifaddr = channelCall<getIfAddr4>(channel);
+            in_addr addr{};
+            if (ifaddr)
+            {
+                addr = ifaddr->address;
+            }
+            ret.pack(dataRef(addr));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::IPSrc:
+        {
+            auto src = IPSrc::Static;
+            if (channelCall<getDHCPProperty>(channel))
+            {
+                src = IPSrc::DHCP;
+            }
+            ret.pack(static_cast<uint4_t>(src), uint4_t{});
+            return responseSuccess(std::move(ret));
+        }
         case LanParam::MAC:
         {
-            uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1] = {};
-
-            *data_len = sizeof(current_revision);
-            std::memcpy(buf, &current_revision, *data_len);
-
-            if (getNetworkData(reqptr->parameter, &buf[1], channel) ==
-                IPMI_CC_OK)
+            ether_addr mac = channelCall<getMACProperty>(channel);
+            ret.pack(dataRef(mac));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::SubnetMask:
+        {
+            auto ifaddr = channelCall<getIfAddr4>(channel);
+            uint8_t prefix = AddrFamily<AF_INET>::defaultPrefix;
+            if (ifaddr)
             {
-                if (param == LanParam::MAC)
-                {
-                    *data_len = sizeof(buf);
-                }
-                else
-                {
-                    *data_len = ipmi::network::IPV4_ADDRESS_SIZE_BYTE + 1;
-                }
-                std::memcpy(response, &buf, *data_len);
+                prefix = ifaddr->prefix;
+            }
+            in_addr netmask = prefixToNetmask(prefix);
+            ret.pack(dataRef(netmask));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::Gateway1:
+        {
+            auto gateway =
+                channelCall<getGatewayProperty<AF_INET>>(channel).value_or(
+                    in_addr{});
+            ret.pack(dataRef(gateway));
+            return responseSuccess(std::move(ret));
+        }
+        case LanParam::VLANId:
+        {
+            uint16_t vlan = channelCall<getVLANProperty>(channel);
+            if (vlan != 0)
+            {
+                vlan |= VLAN_ENABLE_FLAG;
             }
             else
             {
-                rc = IPMI_CC_UNSPECIFIED_ERROR;
+                vlan = lastDisabledVlan[channel];
             }
-            break;
+            ret.pack(vlan);
+            return responseSuccess(std::move(ret));
         }
-        case LanParam::VLAN:
-        {
-            uint8_t buf[ipmi::network::VLAN_SIZE_BYTE + 1] = {};
-
-            *data_len = sizeof(current_revision);
-            std::memcpy(buf, &current_revision, *data_len);
-            if (getNetworkData(reqptr->parameter, &buf[1], channel) ==
-                IPMI_CC_OK)
-            {
-                *data_len = sizeof(buf);
-                std::memcpy(response, &buf, *data_len);
-            }
-            break;
-        }
-        case LanParam::IPSRC:
-        {
-            uint8_t buff[ipmi::network::IPSRC_SIZE_BYTE + 1] = {};
-            *data_len = sizeof(current_revision);
-            std::memcpy(buff, &current_revision, *data_len);
-            if (getNetworkData(reqptr->parameter, &buff[1], channel) ==
-                IPMI_CC_OK)
-            {
-                *data_len = sizeof(buff);
-                std::memcpy(response, &buff, *data_len);
-            }
-            break;
-        }
-        case LanParam::CIPHER_SUITE_COUNT:
-        {
-            *(static_cast<uint8_t*>(response)) = current_revision;
-            // Byte 1 is reserved byte and does not indicate a cipher suite ID,
-            // so no of cipher suite entry count is one less than the size of
-            // the vector
-            auto count = static_cast<uint8_t>(cipherList.size() - 1);
-            *(static_cast<uint8_t*>(response) + 1) = count;
-            *data_len = sizeof(current_revision) + sizeof(count);
-            break;
-        }
-        case LanParam::CIPHER_SUITE_ENTRIES:
-        {
-            *(static_cast<uint8_t*>(response)) = current_revision;
-            // Byte 1 is reserved
-            std::copy_n(cipherList.data(), cipherList.size(),
-                        static_cast<uint8_t*>(response) + 1);
-            *data_len = sizeof(current_revision) +
-                        static_cast<uint8_t>(cipherList.size());
-            break;
-        }
-        default:
-            log<level::ERR>("Unsupported parameter",
-                            entry("PARAMETER=0x%x", reqptr->parameter));
-            rc = IPMI_CC_PARM_NOT_SUPPORTED;
+        case LanParam::CiphersuiteSupport:
+        case LanParam::CiphersuiteEntries:
+            return response(ccParamNotSupported);
     }
 
-    return rc;
+    return response(ccParamNotSupported);
 }
 
-void applyChanges(int channel)
-{
-    std::string ipaddress;
-    std::string gateway;
-    uint8_t prefix{};
-    uint32_t vlanID{};
-    std::string networkInterfacePath;
-    ipmi::DbusObjectInfo ipObject;
-    ipmi::DbusObjectInfo systemObject;
+} // namespace transport
+} // namespace ipmi
 
-    auto ethdevice = ipmi::getChannelName(channel);
-    if (ethdevice.empty())
-    {
-        log<level::ERR>("Unable to get the interface name",
-                        entry("CHANNEL=%d", channel));
-        return;
-    }
-    auto ethIp = ethdevice + "/" + ipmi::network::IP_TYPE;
-    auto channelConf = getChannelConfig(channel);
-
-    try
-    {
-        sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
-
-        log<level::INFO>("Network data from Cache",
-                         entry("PREFIX=%s", channelConf->netmask.c_str()),
-                         entry("ADDRESS=%s", channelConf->ipaddr.c_str()),
-                         entry("GATEWAY=%s", channelConf->gateway.c_str()),
-                         entry("VLAN=%d", channelConf->vlanID),
-                         entry("IPSRC=%d", channelConf->ipsrc));
-        if (channelConf->vlanID != ipmi::network::VLAN_ID_MASK)
-        {
-            // get the first twelve bits which is vlan id
-            // not interested in rest of the bits.
-            channelConf->vlanID = le32toh(channelConf->vlanID);
-            vlanID = channelConf->vlanID & ipmi::network::VLAN_ID_MASK;
-        }
-
-        // if the asked ip src is DHCP then not interested in
-        // any given data except vlan.
-        if (channelConf->ipsrc != ipmi::network::IPOrigin::DHCP)
-        {
-            // always get the system object
-            systemObject =
-                ipmi::getDbusObject(bus, ipmi::network::SYSTEMCONFIG_INTERFACE,
-                                    ipmi::network::ROOT);
-
-            // the below code is to determine the mode of the interface
-            // as the handling is same, if the system is configured with
-            // DHCP or user has given all the data.
-            try
-            {
-                ipmi::ObjectTree ancestorMap;
-
-                ipmi::InterfaceList interfaces{
-                    ipmi::network::ETHERNET_INTERFACE};
-
-                // if the system is having ip object,then
-                // get the IP object.
-                ipObject = ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE,
-                                             ipmi::network::ROOT, ethIp);
-
-                // Get the parent interface of the IP object.
-                try
-                {
-                    ancestorMap = ipmi::getAllAncestors(bus, ipObject.first,
-                                                        std::move(interfaces));
-                }
-                catch (InternalFailure& e)
-                {
-                    // if unable to get the parent interface
-                    // then commit the error and return.
-                    log<level::ERR>("Unable to get the parent interface",
-                                    entry("PATH=%s", ipObject.first.c_str()),
-                                    entry("INTERFACE=%s",
-                                          ipmi::network::ETHERNET_INTERFACE));
-                    commit<InternalFailure>();
-                    channelConf->clear();
-                    return;
-                }
-
-                networkInterfacePath = ancestorMap.begin()->first;
-            }
-            catch (InternalFailure& e)
-            {
-                // TODO Currently IPMI supports single interface,need to handle
-                // Multiple interface through
-                // https://github.com/openbmc/openbmc/issues/2138
-
-                // if there is no ip configured on the system,then
-                // get the network interface object.
-                auto networkInterfaceObject =
-                    ipmi::getDbusObject(bus, ipmi::network::ETHERNET_INTERFACE,
-                                        ipmi::network::ROOT, ethdevice);
-
-                networkInterfacePath = std::move(networkInterfaceObject.first);
-            }
-
-            // get the configured mode on the system.
-            auto enableDHCP = std::get<bool>(ipmi::getDbusProperty(
-                bus, ipmi::network::SERVICE, networkInterfacePath,
-                ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled"));
-
-            // if ip address source is not given then get the ip source mode
-            // from the system so that it can be applied later.
-            if (channelConf->ipsrc == ipmi::network::IPOrigin::UNSPECIFIED)
-            {
-                channelConf->ipsrc = (enableDHCP)
-                                         ? ipmi::network::IPOrigin::DHCP
-                                         : ipmi::network::IPOrigin::STATIC;
-            }
-
-            // check whether user has given all the data
-            // or the configured system interface is dhcp enabled,
-            // in both of the cases get the values from the cache.
-            if ((!channelConf->ipaddr.empty() &&
-                 !channelConf->netmask.empty() &&
-                 !channelConf->gateway.empty()) ||
-                (enableDHCP)) // configured system interface mode = DHCP
-            {
-                // convert mask into prefix
-                ipaddress = channelConf->ipaddr;
-                prefix = ipmi::network::toPrefix(AF_INET, channelConf->netmask);
-                gateway = channelConf->gateway;
-            }
-            else // asked ip src = static and configured system src = static
-                 // or partially given data.
-            {
-                // We have partial filled cache so get the remaining
-                // info from the system.
-
-                // Get the network data from the system as user has
-                // not given all the data then use the data fetched from the
-                // system but it is implementation dependent,IPMI spec doesn't
-                // force it.
-
-                // if system is not having any ip object don't throw error,
-                try
-                {
-                    auto properties = ipmi::getAllDbusProperties(
-                        bus, ipObject.second, ipObject.first,
-                        ipmi::network::IP_INTERFACE);
-
-                    ipaddress =
-                        channelConf->ipaddr.empty()
-                            ? std::get<std::string>(properties["Address"])
-                            : channelConf->ipaddr;
-
-                    prefix = channelConf->netmask.empty()
-                                 ? std::get<uint8_t>(properties["PrefixLength"])
-                                 : ipmi::network::toPrefix(
-                                       AF_INET, channelConf->netmask);
-                }
-                catch (InternalFailure& e)
-                {
-                    log<level::INFO>(
-                        "Failed to get IP object which matches",
-                        entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
-                        entry("MATCH=%s", ethIp.c_str()));
-                }
-
-                auto systemProperties = ipmi::getAllDbusProperties(
-                    bus, systemObject.second, systemObject.first,
-                    ipmi::network::SYSTEMCONFIG_INTERFACE);
-
-                gateway = channelConf->gateway.empty()
-                              ? std::get<std::string>(
-                                    systemProperties["DefaultGateway"])
-                              : channelConf->gateway;
-            }
-        }
-
-        // Currently network manager doesn't support purging of all the
-        // ip addresses and the vlan interfaces from the parent interface,
-        // TODO once the support is there, will make the change here.
-        // https://github.com/openbmc/openbmc/issues/2141.
-
-        // TODO Currently IPMI supports single interface,need to handle
-        // Multiple interface through
-        // https://github.com/openbmc/openbmc/issues/2138
-
-        // instead of deleting all the vlan interfaces and
-        // all the ipv4 address,we will call reset method.
-        // delete all the vlan interfaces
-
-        ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
-                                   ipmi::network::VLAN_INTERFACE);
-
-        // set the interface mode  to static
-        auto networkInterfaceObject =
-            ipmi::getDbusObject(bus, ipmi::network::ETHERNET_INTERFACE,
-                                ipmi::network::ROOT, ethdevice);
-
-        // setting the physical interface mode to static.
-        ipmi::setDbusProperty(
-            bus, ipmi::network::SERVICE, networkInterfaceObject.first,
-            ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled", false);
-
-        networkInterfacePath = networkInterfaceObject.first;
-
-        // delete all the ipv4 addresses
-        ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
-                                   ipmi::network::IP_INTERFACE, ethIp);
-
-        if (vlanID)
-        {
-            ipmi::network::createVLAN(bus, ipmi::network::SERVICE,
-                                      ipmi::network::ROOT, ethdevice, vlanID);
-
-            auto networkInterfaceObject = ipmi::getDbusObject(
-                bus, ipmi::network::VLAN_INTERFACE, ipmi::network::ROOT);
-
-            networkInterfacePath = networkInterfaceObject.first;
-        }
-
-        if (channelConf->ipsrc == ipmi::network::IPOrigin::DHCP)
-        {
-            ipmi::setDbusProperty(
-                bus, ipmi::network::SERVICE, networkInterfacePath,
-                ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled", true);
-        }
-        else
-        {
-            // change the mode to static
-            ipmi::setDbusProperty(
-                bus, ipmi::network::SERVICE, networkInterfacePath,
-                ipmi::network::ETHERNET_INTERFACE, "DHCPEnabled", false);
-
-            if (!ipaddress.empty())
-            {
-                ipmi::network::createIP(bus, ipmi::network::SERVICE,
-                                        networkInterfacePath, ipv4Protocol,
-                                        ipaddress, prefix);
-            }
-
-            if (!gateway.empty())
-            {
-                ipmi::setDbusProperty(bus, systemObject.second,
-                                      systemObject.first,
-                                      ipmi::network::SYSTEMCONFIG_INTERFACE,
-                                      "DefaultGateway", std::string(gateway));
-            }
-        }
-    }
-    catch (sdbusplus::exception::exception& e)
-    {
-        log<level::ERR>(
-            "Failed to set network data", entry("PREFIX=%d", prefix),
-            entry("ADDRESS=%s", ipaddress.c_str()),
-            entry("GATEWAY=%s", gateway.c_str()), entry("VLANID=%d", vlanID),
-            entry("IPSRC=%d", channelConf->ipsrc));
-
-        commit<InternalFailure>();
-    }
-
-    channelConf->clear();
-}
-
-void commitNetworkChanges()
-{
-    for (const auto& channel : channelConfig)
-    {
-        if (channel.second->flush)
-        {
-            applyChanges(channel.first);
-        }
-    }
-}
-
-void createNetworkTimer()
-{
-    if (!networkTimer)
-    {
-        std::function<void()> networkTimerCallback(
-            std::bind(&commitNetworkChanges));
-
-        networkTimer = std::make_unique<phosphor::Timer>(networkTimerCallback);
-    }
-}
+void register_netfn_transport_functions() __attribute__((constructor));
 
 void register_netfn_transport_functions()
 {
-    // As this timer is only for transport handler
-    // so creating it here.
-    createNetworkTimer();
-    // <Wildcard Command>
-    ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_WILDCARD, NULL,
-                           ipmi_transport_wildcard, PRIVILEGE_USER);
-
-    // <Set LAN Configuration Parameters>
-    ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_LAN, NULL,
-                           ipmi_transport_set_lan, PRIVILEGE_ADMIN);
-
-    // <Get LAN Configuration Parameters>
-    ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_LAN, NULL,
-                           ipmi_transport_get_lan, PRIVILEGE_OPERATOR);
-
-    return;
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+                          ipmi::transport::cmdSetLanConfigParameters,
+                          ipmi::Privilege::Admin, ipmi::transport::setLan);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+                          ipmi::transport::cmdGetLanConfigParameters,
+                          ipmi::Privilege::Admin, ipmi::transport::getLan);
 }
diff --git a/transporthandler.hpp b/transporthandler.hpp
deleted file mode 100644
index 5896082..0000000
--- a/transporthandler.hpp
+++ /dev/null
@@ -1,141 +0,0 @@
-#pragma once
-
-#include <ipmid/types.hpp>
-#include <string>
-// IPMI commands for Transport net functions.
-enum ipmi_netfn_storage_cmds
-{
-    // Get capability bits
-    IPMI_CMD_SET_LAN = 0x01,
-    IPMI_CMD_GET_LAN = 0x02,
-};
-
-// Command specific completion codes
-enum ipmi_transport_return_codes
-{
-    IPMI_CC_PARM_NOT_SUPPORTED = 0x80,
-};
-
-// Parameters
-enum class LanParam : uint8_t
-{
-    INPROGRESS = 0,
-    AUTHSUPPORT = 1, // Read-only
-    AUTHENABLES = 2,
-    IP = 3,
-    IPSRC = 4,
-    MAC = 5,
-    SUBNET = 6,
-    IPHEADER_PARAMS = 7,
-    RMCP_PORT = 8,
-    RMCP_SECONDARY_PORT = 9,
-    BMC_GENERATED_ARP_CTRL = 10,
-    GRATUITOUS_ARP_INTERVAL = 11,
-    GATEWAY = 12,
-    GATEWAY_MAC = 13,
-    GATEWAY_BACKUP = 14,
-    GATEWAY_BACKUP_MAC = 15,
-    COMMUNITY_STRING = 16,
-    LAN_ALERT_DESTINATION_COUNT = 17, // Read-only
-    LAN_ALERT_DESTINATION_TYPE = 18,  // Type per destination
-    LAN_ALERT_DESTINATIONS = 19,
-    VLAN = 20,
-    VLAN_PRIORITY = 21,
-    CIPHER_SUITE_COUNT = 22,   // Read-only
-    CIPHER_SUITE_ENTRIES = 23, // Read-only
-    CIPHER_SUITE_PRIVILEGE_LEVELS = 24,
-    DESTINATION_ADDR_VLAN_TAGS = 25,
-    BAD_PASSWORD_THRESHOLD = 26,
-    IPV6_AND_IPV4_SUPPORTED = 50, // Read-only
-    IPV6_AND_IPV4_ENABLES = 51,
-    IPV6_HEADER_STATIC_TRAFFIC_CLASS = 52,
-    IPV6_HEADER_STATIC_HOP_LIMIT = 53,
-    IPV6_HEADER_FLOW_LABEL = 54,
-    IPV6_STATUS = 55, // Read-only
-    IPV6_STATIC_ADDRESSES = 56,
-    IPV6_DHCPV6_STATIC_DUID_STORAGE_LENGTH = 57, // Read-only
-    IPV6_DHCPV6_STATIC_DUIDS = 58,
-    IPV6_DYNAMIC_ADDRESSES = 59,            // Read-only
-    IPV6_DHCPV6_DYNAMIC_DUID_STOR_LEN = 60, // Read-only
-    IPV6_DHCPV6_DYNAMIC_DUIDS = 61,
-    IPV6_DHCPV6_TIMING_CONF_SUPPORT = 62, // Read-only
-    IPV6_DHCPV6_TIMING_CONFIGURATION = 63,
-    IPV6_ROUTER_ADDRESS_CONF_CTRL = 64,
-    IPV6_STATIC_ROUTER_1_IP_ADDR = 65,
-    IPV6_STATIC_ROUTER_1_MAC_ADDR = 66,
-    IPV6_STATIC_ROUTER_1_PREFIX_LEN = 67,
-    IPV6_STATIC_ROUTER_1_PREFIX_VAL = 68,
-    IPV6_STATIC_ROUTER_2_IP_ADDR = 69,
-    IPV6_STATIC_ROUTER_2_MAC_ADDR = 70,
-    IPV6_STATIC_ROUTER_2_PREFIX_LEN = 71,
-    IPV6_STATIC_ROUTER_2_PREFIX_VAL = 72,
-    DYNAMIC_ROUTER_INFO_SET_COUNT = 73,       // Read-only
-    IPV6_DYNAMIC_ROUTER_INFO_IP_ADDR = 74,    // Read-only
-    IPV6_DYNAMIC_ROUTER_INFO_MAC = 75,        // Read-only
-    IPV6_DYNAMIC_ROUTER_INFO_PREFIX_LEN = 76, // Read-only
-    IPV6_DYNAMIC_ROUTER_INFO_PREFIX_VAL = 77, // Read-only
-    IPV6_DYNAMIC_ROUTER_RECV_HOP_LIMIT = 78,
-    IPV6_NEIGHBOR_TIMING_CONF_SUPPORT = 79, // Read-only
-    IPV6_NEIGHBOR_TIMING_CONFIGURATION = 80,
-};
-
-// Data length of parameters
-constexpr size_t lanParamVLANSize = 4;
-constexpr uint8_t SET_COMPLETE = 0;
-constexpr uint8_t SET_IN_PROGRESS = 1;
-constexpr uint8_t SET_COMMIT_WRITE = 2;         // Optional
-constexpr uint8_t SET_IN_PROGRESS_RESERVED = 3; // Reserved
-
-const int CHANNEL_MASK = 0x0f;
-const int NUM_CHANNELS = 0x0f;
-
-struct ChannelConfig_t
-{
-    std::string ipaddr;
-    ipmi::network::IPOrigin ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
-    std::string netmask;
-    std::string gateway;
-    std::string macAddress;
-    // IPMI stores the vlan info in 16 bits,32 bits is to aligned
-    // with phosphor-dbus interfaces.
-    // vlan id is in 12 bits and the 16th bit is for enable mask.
-    uint32_t vlanID = ipmi::network::VLAN_ID_MASK;
-    uint8_t lan_set_in_progress = SET_COMPLETE;
-    bool flush = false;
-
-    void clear()
-    {
-        ipaddr.clear();
-        netmask.clear();
-        gateway.clear();
-        macAddress.clear();
-        vlanID = ipmi::network::VLAN_ID_MASK;
-        ipsrc = ipmi::network::IPOrigin::UNSPECIFIED;
-        lan_set_in_progress = SET_COMPLETE;
-        flush = false;
-    }
-};
-
-// Given a channel, get the corresponding configuration,
-// or allocate it first.
-//
-// @param[in] channel the channel
-// @return the ChannelConfig_t pointer.
-struct ChannelConfig_t* getChannelConfig(int channel);
-
-/** @brief Iterate over all the channelconfig and if
- *         user has given the data for a channel then
- *         apply the network changes for that channel.
- */
-void commitNetworkChanges();
-
-/* @brief  Apply the network changes which is there in the
- *         network cache for a given channel which gets filled
- *         through setLan command. If some of the network
- *         parameter was not given by the setLan then this function
- *         gets the value of that parameter which is already
- *         configured on the system.
- * @param[in] channel: channel number.
- */
-void applyChanges(int channel);
-constexpr uint16_t maxValidVLANIDValue = 4095;
