diff --git a/transporthandler.cpp b/transporthandler.cpp
index f4326c1..bbc6ae5 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -22,7 +22,19 @@
 #include <mapper.h>
 #endif
 
+/** @struct SetChannelAccessRequest
+ *
+ * IPMI payload for Set Channel access command request.
+ */
+struct SetChannelAccessRequest
+{
+    uint8_t channelNumber;       //!< Channel number.
+    uint8_t setting;             //!< The setting values.
+    uint8_t privilegeLevelLimit; //!< The Privilege Level Limit
+} __attribute__((packed));
+
 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;
 
@@ -620,6 +632,319 @@
     return rc;
 }
 
+ipmi_ret_t ipmi_set_channel_access(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;
+
+    std::string ipaddress;
+    std::string gateway;
+    uint8_t prefix {};
+    uint32_t vlanID {};
+    std::string networkInterfacePath;
+    ipmi::DbusObjectInfo ipObject;
+    ipmi::DbusObjectInfo systemObject;
+
+    if (*data_len < sizeof(SetChannelAccessRequest))
+    {
+        return IPMI_CC_INVALID;
+    }
+
+    auto requestData = reinterpret_cast<const SetChannelAccessRequest*>
+                   (request);
+    int channel = requestData->channelNumber & CHANNEL_MASK;
+
+    auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
+    if (ethdevice.empty())
+    {
+        return IPMI_CC_INVALID_FIELD_REQUEST;
+    }
+    auto ethIp = ethdevice + "/" + ipmi::network::IP_TYPE;
+    auto channelConf = getChannelConfig(channel);
+
+    // Todo: parse the request data if needed.
+    // Using Set Channel cmd to apply changes of Set Lan Cmd.
+    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::getDbusObject(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>();
+                    rc = IPMI_CC_UNSPECIFIED_ERROR;
+                    channelConf->clear();
+                    return rc;
+                }
+
+                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 = ipmi::getDbusProperty(
+                    bus,
+                    ipmi::network::SERVICE,
+                    networkInterfacePath,
+                    ipmi::network::ETHERNET_INTERFACE,
+                    "DHCPEnabled").get<bool>();
+
+            // 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() ?
+                        properties["Address"].get<std::string>() :
+                        channelConf->ipaddr;
+
+                    prefix = channelConf->netmask.empty() ?
+                        properties["PrefixLength"].get<uint8_t>() :
+                        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));
+                }
+
+                auto systemProperties = ipmi::getAllDbusProperties(
+                        bus,
+                        systemObject.second,
+                        systemObject.first,
+                        ipmi::network::SYSTEMCONFIG_INTERFACE);
+
+                gateway = channelConf->gateway.empty() ?
+                        systemProperties["DefaultGateway"].get<std::string>() :
+                        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 (InternalFailure& 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>();
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+    }
+
+    channelConf->clear();
+    return rc;
+}
+
 void register_netfn_transport_functions()
 {
     // <Wildcard Command>
