diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
new file mode 100644
index 0000000..9abe49e
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
@@ -0,0 +1,670 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay;
+
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.CircuitId;
+import org.onlab.packet.dhcp.DhcpOption;
+import org.onlab.packet.dhcp.DhcpRelayAgentOption;
+import org.onosproject.dhcprelay.api.DhcpHandler;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.routing.Route;
+import org.onosproject.incubator.net.routing.RouteStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.HostStore;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_CircuitID;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_END;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
+import static org.onlab.packet.MacAddress.valueOf;
+import static org.onlab.packet.dhcp.DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID;
+
+@Component
+@Service
+@Property(name = "version", value = "4")
+public class Dhcp4HandlerImpl implements DhcpHandler {
+    private static Logger log = LoggerFactory.getLogger(Dhcp4HandlerImpl.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpRelayStore dhcpRelayStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostStore hostStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteStore routeStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    private Ip4Address dhcpServerIp = null;
+    // dhcp server may be connected directly to the SDN network or
+    // via an external gateway. When connected directly, the dhcpConnectPoint, dhcpConnectMac,
+    // and dhcpConnectVlan refer to the server. When connected via the gateway, they refer
+    // to the gateway.
+    private ConnectPoint dhcpServerConnectPoint = null;
+    private MacAddress dhcpConnectMac = null;
+    private VlanId dhcpConnectVlan = null;
+    private Ip4Address dhcpGatewayIp = null;
+
+    @Override
+    public void setDhcpServerIp(IpAddress dhcpServerIp) {
+        checkNotNull(dhcpServerIp, "DHCP server IP can't be null");
+        checkState(dhcpServerIp.isIp4(), "Invalid server IP for DHCPv4 relay handler");
+        this.dhcpServerIp = dhcpServerIp.getIp4Address();
+    }
+
+    @Override
+    public void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
+        checkNotNull(dhcpServerConnectPoint, "Server connect point can't null");
+        this.dhcpServerConnectPoint = dhcpServerConnectPoint;
+    }
+
+    @Override
+    public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
+        this.dhcpConnectMac = dhcpConnectMac;
+    }
+
+    @Override
+    public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
+        this.dhcpConnectVlan = dhcpConnectVlan;
+    }
+
+    @Override
+    public void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
+        if (dhcpGatewayIp != null) {
+            checkState(dhcpGatewayIp.isIp4(), "Invalid gateway IP for DHCPv4 relay handler");
+            this.dhcpGatewayIp = dhcpGatewayIp.getIp4Address();
+        } else {
+            // removes gateway config
+            this.dhcpGatewayIp = null;
+        }
+    }
+
+    @Override
+    public Optional<IpAddress> getDhcpServerIp() {
+        return Optional.ofNullable(dhcpServerIp);
+    }
+
+    @Override
+    public Optional<IpAddress> getDhcpGatewayIp() {
+        return Optional.ofNullable(dhcpGatewayIp);
+    }
+
+    @Override
+    public Optional<MacAddress> getDhcpConnectMac() {
+        return Optional.ofNullable(dhcpConnectMac);
+    }
+
+    @Override
+    public void processDhcpPacket(PacketContext context, BasePacket payload) {
+        checkNotNull(payload, "DHCP payload can't be null");
+        checkState(payload instanceof DHCP, "Payload is not a DHCP");
+        DHCP dhcpPayload = (DHCP) payload;
+        if (!configured()) {
+            log.warn("Missing DHCP relay server config. Abort packet processing");
+            return;
+        }
+
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        Set<Interface> clientServerInterfaces = interfaceService.getInterfacesByPort(inPort);
+        // ignore the packets if dhcp client interface is not configured on onos.
+        if (clientServerInterfaces.isEmpty()) {
+            log.warn("Virtual interface is not configured on {}", inPort);
+            return;
+        }
+        checkNotNull(dhcpPayload, "Can't find DHCP payload");
+        Ethernet packet = context.inPacket().parsed();
+        DHCP.MsgType incomingPacketType = dhcpPayload.getOptions().stream()
+                .filter(dhcpOption -> dhcpOption.getCode() == OptionCode_MessageType.getValue())
+                .map(DhcpOption::getData)
+                .map(data -> DHCP.MsgType.getType(data[0]))
+                .findFirst()
+                .orElse(null);
+        checkNotNull(incomingPacketType, "Can't get message type from DHCP payload {}", dhcpPayload);
+        switch (incomingPacketType) {
+            case DHCPDISCOVER:
+                // add the gatewayip as virtual interface ip for server to understand
+                // the lease to be assigned and forward the packet to dhcp server.
+                Ethernet ethernetPacketDiscover =
+                        processDhcpPacketFromClient(context, packet, clientServerInterfaces);
+
+                if (ethernetPacketDiscover != null) {
+                    writeRequestDhcpRecord(inPort, packet, dhcpPayload);
+                    handleDhcpDiscoverAndRequest(ethernetPacketDiscover);
+                }
+                break;
+            case DHCPOFFER:
+                //reply to dhcp client.
+                Ethernet ethernetPacketOffer = processDhcpPacketFromServer(packet);
+                if (ethernetPacketOffer != null) {
+                    writeResponseDhcpRecord(ethernetPacketOffer, dhcpPayload);
+                    handleDhcpOffer(ethernetPacketOffer, dhcpPayload);
+                }
+                break;
+            case DHCPREQUEST:
+                // add the gateway ip as virtual interface ip for server to understand
+                // the lease to be assigned and forward the packet to dhcp server.
+                Ethernet ethernetPacketRequest =
+                        processDhcpPacketFromClient(context, packet, clientServerInterfaces);
+                if (ethernetPacketRequest != null) {
+                    writeRequestDhcpRecord(inPort, packet, dhcpPayload);
+                    handleDhcpDiscoverAndRequest(ethernetPacketRequest);
+                }
+                break;
+            case DHCPACK:
+                // reply to dhcp client.
+                Ethernet ethernetPacketAck = processDhcpPacketFromServer(packet);
+                if (ethernetPacketAck != null) {
+                    writeResponseDhcpRecord(ethernetPacketAck, dhcpPayload);
+                    handleDhcpAck(ethernetPacketAck, dhcpPayload);
+                }
+                break;
+            case DHCPRELEASE:
+                // TODO: release the ip address from client
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Checks if this app has been configured.
+     *
+     * @return true if all information we need have been initialized
+     */
+    public boolean configured() {
+        return dhcpServerConnectPoint != null && dhcpServerIp != null;
+    }
+
+    /**
+     * Returns the first interface ip out of a set of interfaces or null.
+     *
+     * @param intfs interfaces of one connect port
+     * @return the first interface IP; null if not exists an IP address in
+     *         these interfaces
+     */
+    private Ip4Address getRelayAgentIPv4Address(Set<Interface> intfs) {
+        return intfs.stream()
+                .map(Interface::ipAddressesList)
+                .flatMap(List::stream)
+                .map(InterfaceIpAddress::ipAddress)
+                .filter(IpAddress::isIp4)
+                .map(IpAddress::getIp4Address)
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Build the DHCP discover/request packet with gateway IP(unicast packet).
+     *
+     * @param context the packet context
+     * @param ethernetPacket the ethernet payload to process
+     * @param clientInterfaces interfaces which belongs to input port
+     * @return processed packet
+     */
+    private Ethernet processDhcpPacketFromClient(PacketContext context,
+                                                 Ethernet ethernetPacket,
+                                                 Set<Interface> clientInterfaces) {
+        Ip4Address relayAgentIp = getRelayAgentIPv4Address(clientInterfaces);
+        MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
+        if (relayAgentIp == null || relayAgentMac == null) {
+            log.warn("Missing DHCP relay agent interface Ipv4 addr config for "
+                             + "packet from client on port: {}. Aborting packet processing",
+                     clientInterfaces.iterator().next().connectPoint());
+            return null;
+        }
+        if (dhcpConnectMac == null) {
+            log.warn("DHCP {} not yet resolved .. Aborting DHCP "
+                             + "packet processing from client on port: {}",
+                     (dhcpGatewayIp == null) ? "server IP " + dhcpServerIp
+                             : "gateway IP " + dhcpGatewayIp,
+                     clientInterfaces.iterator().next().connectPoint());
+            return null;
+        }
+        // get dhcp header.
+        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        etherReply.setSourceMACAddress(relayAgentMac);
+        etherReply.setDestinationMACAddress(dhcpConnectMac);
+        etherReply.setVlanID(dhcpConnectVlan.toShort());
+        IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
+        ipv4Packet.setSourceAddress(relayAgentIp.toInt());
+        ipv4Packet.setDestinationAddress(dhcpServerIp.toInt());
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+        // If there is no relay agent option(option 82), add one to DHCP payload
+        boolean containsRelayAgentOption = dhcpPacket.getOptions().stream()
+                .map(DhcpOption::getCode)
+                .anyMatch(code -> code == OptionCode_CircuitID.getValue());
+
+        if (!containsRelayAgentOption) {
+            ConnectPoint inPort = context.inPacket().receivedFrom();
+            VlanId vlanId = VlanId.vlanId(ethernetPacket.getVlanID());
+            // add connected in port and vlan
+            CircuitId cid = new CircuitId(inPort.toString(), vlanId);
+            byte[] circuitId = cid.serialize();
+            DhcpOption circuitIdSubOpt = new DhcpOption();
+            circuitIdSubOpt
+                    .setCode(CIRCUIT_ID.getValue())
+                    .setLength((byte) circuitId.length)
+                    .setData(circuitId);
+
+            DhcpRelayAgentOption newRelayAgentOpt = new DhcpRelayAgentOption();
+            newRelayAgentOpt.setCode(OptionCode_CircuitID.getValue());
+            newRelayAgentOpt.addSubOption(circuitIdSubOpt);
+
+            // Removes END option  first
+            List<DhcpOption> options = dhcpPacket.getOptions().stream()
+                    .filter(opt -> opt.getCode() != OptionCode_END.getValue())
+                    .collect(Collectors.toList());
+
+            // push relay agent option
+            options.add(newRelayAgentOpt);
+
+            // make sure option 255(End) is the last option
+            DhcpOption endOption = new DhcpOption();
+            endOption.setCode(OptionCode_END.getValue());
+            options.add(endOption);
+
+            dhcpPacket.setOptions(options);
+            dhcpPacket.setGatewayIPAddress(relayAgentIp.toInt());
+        }
+
+        udpPacket.setPayload(dhcpPacket);
+        udpPacket.setSourcePort(UDP.DHCP_CLIENT_PORT);
+        udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
+        ipv4Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv4Packet);
+        return etherReply;
+    }
+
+    /**
+     * Writes DHCP record to the store according to the request DHCP packet (Discover, Request).
+     *
+     * @param location the location which DHCP packet comes from
+     * @param ethernet the DHCP packet
+     * @param dhcpPayload the DHCP payload
+     */
+    private void writeRequestDhcpRecord(ConnectPoint location,
+                                        Ethernet ethernet,
+                                        DHCP dhcpPayload) {
+        VlanId vlanId = VlanId.vlanId(ethernet.getVlanID());
+        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+        HostId hostId = HostId.hostId(macAddress, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+        if (record == null) {
+            record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
+        } else {
+            record = record.clone();
+        }
+        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+        record.ip4Status(dhcpPayload.getPacketType());
+        record.setDirectlyConnected(directlyConnected(dhcpPayload));
+        if (!directlyConnected(dhcpPayload)) {
+            // Update gateway mac address if the host is not directly connected
+            record.nextHop(ethernet.getSourceMAC());
+        }
+        record.updateLastSeen();
+        dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
+    }
+
+    /**
+     * Writes DHCP record to the store according to the response DHCP packet (Offer, Ack).
+     *
+     * @param ethernet the DHCP packet
+     * @param dhcpPayload the DHCP payload
+     */
+    private void writeResponseDhcpRecord(Ethernet ethernet,
+                                         DHCP dhcpPayload) {
+        Optional<Interface> outInterface = getOutputInterface(ethernet, dhcpPayload);
+        if (!outInterface.isPresent()) {
+            log.warn("Failed to determine where to send {}", dhcpPayload.getPacketType());
+            return;
+        }
+
+        Interface outIface = outInterface.get();
+        ConnectPoint location = outIface.connectPoint();
+        VlanId vlanId = outIface.vlan();
+        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+        HostId hostId = HostId.hostId(macAddress, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+        if (record == null) {
+            record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
+        } else {
+            record = record.clone();
+        }
+        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+        if (dhcpPayload.getPacketType() == DHCP.MsgType.DHCPACK) {
+            record.ip4Address(Ip4Address.valueOf(dhcpPayload.getYourIPAddress()));
+        }
+        record.ip4Status(dhcpPayload.getPacketType());
+        record.setDirectlyConnected(directlyConnected(dhcpPayload));
+        record.updateLastSeen();
+        dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
+    }
+
+    /**
+     * Build the DHCP offer/ack with proper client port.
+     *
+     * @param ethernetPacket the original packet comes from server
+     * @return new packet which will send to the client
+     */
+    private Ethernet processDhcpPacketFromServer(Ethernet ethernetPacket) {
+        // get dhcp header.
+        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
+
+        // determine the vlanId of the client host - note that this vlan id
+        // could be different from the vlan in the packet from the server
+        Interface outInterface = getOutputInterface(ethernetPacket, dhcpPayload).orElse(null);
+
+        if (outInterface == null) {
+            log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
+            return null;
+        }
+
+        etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
+        etherReply.setVlanID(outInterface.vlan().toShort());
+        // we leave the srcMac from the original packet
+
+        // figure out the relay agent IP corresponding to the original request
+        Ip4Address relayAgentIP = getRelayAgentIPv4Address(
+                interfaceService.getInterfacesByPort(outInterface.connectPoint()));
+        if (relayAgentIP == null) {
+            log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. "
+                             + "Aborting relay for dhcp packet from server {}",
+                     etherReply.getDestinationMAC(), outInterface.vlan(),
+                     ethernetPacket);
+            return null;
+        }
+        // SRC_IP: relay agent IP
+        // DST_IP: offered IP
+        ipv4Packet.setSourceAddress(relayAgentIP.toInt());
+        ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
+        udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
+        if (directlyConnected(dhcpPayload)) {
+            udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
+        } else {
+            // forward to another dhcp relay
+            udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
+        }
+
+        udpPacket.setPayload(dhcpPayload);
+        ipv4Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv4Packet);
+        return etherReply;
+    }
+
+
+    /**
+     * Check if the host is directly connected to the network or not.
+     *
+     * @param dhcpPayload the dhcp payload
+     * @return true if the host is directly connected to the network; false otherwise
+     */
+    private boolean directlyConnected(DHCP dhcpPayload) {
+        DhcpOption relayAgentOption = dhcpPayload.getOption(OptionCode_CircuitID);
+
+        // Doesn't contains relay option
+        if (relayAgentOption == null) {
+            return true;
+        }
+
+        IpAddress gatewayIp = IpAddress.valueOf(dhcpPayload.getGatewayIPAddress());
+        Set<Interface> gatewayInterfaces = interfaceService.getInterfacesByIp(gatewayIp);
+
+        // Contains relay option, and added by ONOS
+        if (!gatewayInterfaces.isEmpty()) {
+            return true;
+        }
+
+        // Relay option added by other relay agent
+        return false;
+    }
+
+
+    /**
+     * Send the DHCP ack to the requester host.
+     * Modify Host or Route store according to the type of DHCP.
+     *
+     * @param ethernetPacketAck the packet
+     * @param dhcpPayload the DHCP data
+     */
+    private void handleDhcpAck(Ethernet ethernetPacketAck, DHCP dhcpPayload) {
+        Optional<Interface> outInterface = getOutputInterface(ethernetPacketAck, dhcpPayload);
+        if (!outInterface.isPresent()) {
+            log.warn("Can't find output interface for dhcp: {}", dhcpPayload);
+            return;
+        }
+
+        Interface outIface = outInterface.get();
+        HostLocation hostLocation = new HostLocation(outIface.connectPoint(), System.currentTimeMillis());
+        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+        VlanId vlanId = outIface.vlan();
+        HostId hostId = HostId.hostId(macAddress, vlanId);
+        Ip4Address ip = Ip4Address.valueOf(dhcpPayload.getYourIPAddress());
+
+        if (directlyConnected(dhcpPayload)) {
+            // Add to host store if it connect to network directly
+            Set<IpAddress> ips = Sets.newHashSet(ip);
+            HostDescription desc = new DefaultHostDescription(macAddress, vlanId,
+                                                              hostLocation, ips);
+
+            // Replace the ip when dhcp server give the host new ip address
+            hostStore.createOrUpdateHost(DhcpRelayManager.PROVIDER_ID, hostId, desc, false);
+        } else {
+            // Add to route store if it does not connect to network directly
+            // Get gateway host IP according to host mac address
+            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+
+            if (record == null) {
+                log.warn("Can't find DHCP record of host {}", hostId);
+                return;
+            }
+
+            MacAddress gwMac = record.nextHop().orElse(null);
+            if (gwMac == null) {
+                log.warn("Can't find gateway mac address from record {}", record);
+                return;
+            }
+
+            HostId gwHostId = HostId.hostId(gwMac, record.vlanId());
+            Host gwHost = hostService.getHost(gwHostId);
+
+            if (gwHost == null) {
+                log.warn("Can't find gateway host {}", gwHostId);
+                return;
+            }
+
+            Ip4Address nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp4)
+                    .map(IpAddress::getIp4Address)
+                    .findFirst()
+                    .orElse(null);
+
+            if (nextHopIp == null) {
+                log.warn("Can't find IP address of gateway {}", gwHost);
+                return;
+            }
+
+            Route route = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp);
+            routeStore.updateRoute(route);
+        }
+        sendResponseToClient(ethernetPacketAck, dhcpPayload);
+    }
+
+    /**
+     * forward the packet to ConnectPoint where the DHCP server is attached.
+     *
+     * @param packet the packet
+     */
+    private void handleDhcpDiscoverAndRequest(Ethernet packet) {
+        // send packet to dhcp server connect point.
+        if (dhcpServerConnectPoint != null) {
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(dhcpServerConnectPoint.port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    dhcpServerConnectPoint.deviceId(), t, ByteBuffer.wrap(packet.serialize()));
+            if (log.isTraceEnabled()) {
+                log.trace("Relaying packet to dhcp server {}", packet);
+            }
+            packetService.emit(o);
+        } else {
+            log.warn("Can't find DHCP server connect point, abort.");
+        }
+    }
+
+
+    /**
+     * Gets output interface of a dhcp packet.
+     * If option 82 exists in the dhcp packet and the option was sent by
+     * ONOS (gateway address exists in ONOS interfaces), use the connect
+     * point and vlan id from circuit id; otherwise, find host by destination
+     * address and use vlan id from sender (dhcp server).
+     *
+     * @param ethPacket the ethernet packet
+     * @param dhcpPayload the dhcp packet
+     * @return an interface represent the output port and vlan; empty value
+     *         if the host or circuit id not found
+     */
+    private Optional<Interface> getOutputInterface(Ethernet ethPacket, DHCP dhcpPayload) {
+        VlanId originalPacketVlanId = VlanId.vlanId(ethPacket.getVlanID());
+        IpAddress gatewayIpAddress = Ip4Address.valueOf(dhcpPayload.getGatewayIPAddress());
+        Set<Interface> gatewayInterfaces = interfaceService.getInterfacesByIp(gatewayIpAddress);
+        DhcpRelayAgentOption option = (DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
+
+        // Sent by ONOS, and contains circuit id
+        if (!gatewayInterfaces.isEmpty() && option != null) {
+            DhcpOption circuitIdSubOption = option.getSubOption(CIRCUIT_ID.getValue());
+            try {
+                CircuitId circuitId = CircuitId.deserialize(circuitIdSubOption.getData());
+                ConnectPoint connectPoint = ConnectPoint.deviceConnectPoint(circuitId.connectPoint());
+                VlanId vlanId = circuitId.vlanId();
+                return Optional.of(new Interface(null, connectPoint, null, null, vlanId));
+            } catch (IllegalArgumentException ex) {
+                // invalid circuit format, didn't sent by ONOS
+                log.debug("Invalid circuit {}, use information from dhcp payload",
+                          circuitIdSubOption.getData());
+            }
+        }
+
+        // Use Vlan Id from DHCP server if DHCP relay circuit id was not
+        // sent by ONOS or circuit Id can't be parsed
+        MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
+        Optional<DhcpRecord> dhcpRecord = dhcpRelayStore.getDhcpRecord(HostId.hostId(dstMac, originalPacketVlanId));
+        return dhcpRecord
+                .map(DhcpRecord::locations)
+                .orElse(Collections.emptySet())
+                .stream()
+                .reduce((hl1, hl2) -> {
+                    if (hl1 == null || hl2 == null) {
+                        return hl1 == null ? hl2 : hl1;
+                    }
+                    return hl1.time() > hl2.time() ? hl1 : hl2;
+                })
+                .map(lastLocation -> new Interface(null, lastLocation, null, null, originalPacketVlanId));
+    }
+
+    /**
+     * Handles DHCP offer packet.
+     *
+     * @param ethPacket the packet
+     * @param dhcpPayload the DHCP data
+     */
+    private void handleDhcpOffer(Ethernet ethPacket, DHCP dhcpPayload) {
+        // TODO: removes option 82 if necessary
+        sendResponseToClient(ethPacket, dhcpPayload);
+    }
+
+    /**
+     * Send the response DHCP to the requester host.
+     *
+     * @param ethPacket the packet
+     * @param dhcpPayload the DHCP data
+     */
+    private void sendResponseToClient(Ethernet ethPacket, DHCP dhcpPayload) {
+        Optional<Interface> outInterface = getOutputInterface(ethPacket, dhcpPayload);
+        outInterface.ifPresent(theInterface -> {
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(theInterface.connectPoint().port())
+                    .build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    theInterface.connectPoint().deviceId(),
+                    treatment,
+                    ByteBuffer.wrap(ethPacket.serialize()));
+            if (log.isTraceEnabled()) {
+                log.trace("Relaying packet to DHCP client {} via {}, vlan {}",
+                          ethPacket,
+                          theInterface.connectPoint(),
+                          theInterface.vlan());
+            }
+            packetService.emit(o);
+        });
+    }
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
new file mode 100644
index 0000000..f5375bf
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.dhcprelay.api.DhcpHandler;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.packet.PacketContext;
+
+import java.util.Optional;
+
+@Component
+@Service
+@Property(name = "version", value = "6")
+public class Dhcp6HandlerImpl implements DhcpHandler {
+
+    @Override
+    public void processDhcpPacket(PacketContext context, BasePacket dhcp6Payload) {
+
+    }
+
+    @Override
+    public Optional<IpAddress> getDhcpServerIp() {
+        return null;
+    }
+
+    @Override
+    public Optional<IpAddress> getDhcpGatewayIp() {
+        return null;
+    }
+
+    @Override
+    public Optional<MacAddress> getDhcpConnectMac() {
+        return null;
+    }
+
+    @Override
+    public void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
+
+    }
+
+    @Override
+    public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
+
+    }
+
+    @Override
+    public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
+
+    }
+
+    @Override
+    public void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
+
+    }
+
+    @Override
+    public void setDhcpServerIp(IpAddress dhcpServerIp) {
+
+    }
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java
index 11a5d7a..0ed8411 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java
@@ -33,7 +33,6 @@
 
     @Override
     public boolean isValid() {
-
         return hasOnlyFields(DHCP_CONNECT_POINT, DHCP_SERVER_IP, DHCP_GATEWAY_IP) &&
                 isConnectPoint(DHCP_CONNECT_POINT, MANDATORY) &&
                 isIpAddress(DHCP_SERVER_IP, MANDATORY) &&
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
index de682de..a310a96 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -17,15 +17,12 @@
 
 import java.nio.ByteBuffer;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Dictionary;
-import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Stream;
 
-import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -39,31 +36,26 @@
 import org.onlab.packet.DHCP6;
 import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
-import org.onlab.packet.dhcp.DhcpOption;
-import org.onlab.packet.dhcp.CircuitId;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
-import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.UDP;
 import org.onlab.packet.VlanId;
-import org.onlab.packet.dhcp.DhcpRelayAgentOption;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.dhcprelay.api.DhcpHandler;
+import org.onosproject.dhcprelay.api.DhcpRelayService;
 import org.onosproject.dhcprelay.store.DhcpRecord;
 import org.onosproject.dhcprelay.store.DhcpRelayStore;
 import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.incubator.net.routing.Route;
-import org.onosproject.incubator.net.routing.RouteStore;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
 import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigEvent;
 import org.onosproject.net.config.NetworkConfigListener;
@@ -72,13 +64,9 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.DefaultHostDescription;
-import org.onosproject.net.host.HostDescription;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
 import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.HostStore;
-import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.packet.PacketContext;
@@ -92,12 +80,7 @@
 
 import com.google.common.collect.ImmutableSet;
 
-import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_CircuitID;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.packet.dhcp.DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID;
 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
-import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
-import static org.onlab.packet.MacAddress.valueOf;
 /**
  * DHCP Relay Agent Application Component.
  */
@@ -105,7 +88,7 @@
 @Service
 public class DhcpRelayManager implements DhcpRelayService {
     public static final String DHCP_RELAY_APP = "org.onosproject.dhcp-relay";
-    protected static final ProviderId PROVIDER_ID = new ProviderId("dhcp", DHCP_RELAY_APP);
+    public static final ProviderId PROVIDER_ID = new ProviderId("host", DHCP_RELAY_APP);
     public static final String HOST_LOCATION_PROVIDER =
             "org.onosproject.provider.host.impl.HostLocationProvider";
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -135,12 +118,6 @@
     protected HostService hostService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostStore hostStore;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected RouteStore routeStore;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected InterfaceService interfaceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -149,21 +126,20 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ComponentConfigService compCfgService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY,
+               target = "(version=4)")
+    protected DhcpHandler v4Handler;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY,
+               target = "(version=6)")
+    protected DhcpHandler v6Handler;
+
     @Property(name = "arpEnabled", boolValue = true,
-            label = "Enable Address resolution protocol")
+             label = "Enable Address resolution protocol")
     protected boolean arpEnabled = true;
 
     private DhcpRelayPacketProcessor dhcpRelayPacketProcessor = new DhcpRelayPacketProcessor();
     private InternalHostListener hostListener = new InternalHostListener();
-    private Ip4Address dhcpServerIp = null;
-    // dhcp server may be connected directly to the SDN network or
-    // via an external gateway. When connected directly, the dhcpConnectPoint, dhcpConnectMac,
-    // and dhcpConnectVlan refer to the server. When connected via the gateway, they refer
-    // to the gateway.
-    private ConnectPoint dhcpServerConnectPoint = null;
-    private MacAddress dhcpConnectMac = null;
-    private VlanId dhcpConnectVlan = null;
-    private Ip4Address dhcpGatewayIp = null;
     private ApplicationId appId;
 
     @Activate
@@ -175,8 +151,11 @@
         factories.forEach(cfgService::registerConfigFactory);
         //update the dhcp server configuration.
         updateConfig();
-        //add the packet services.
+
+        //add the packet processor
         packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
+
+        // listen host event for dhcp server or the gateway
         hostService.addListener(hostListener);
         requestDhcpPackets();
         modified(context);
@@ -196,11 +175,10 @@
         hostService.removeListener(hostListener);
         cancelDhcpPackets();
         cancelArpPackets();
-        if (dhcpGatewayIp != null) {
-            hostService.stopMonitoringIp(dhcpGatewayIp);
-        } else {
-            hostService.stopMonitoringIp(dhcpServerIp);
-        }
+        v4Handler.getDhcpGatewayIp().ifPresent(hostService::stopMonitoringIp);
+        v4Handler.getDhcpServerIp().ifPresent(hostService::stopMonitoringIp);
+        // TODO: DHCPv6 Handler
+
         compCfgService.unregisterProperties(getClass(), true);
         log.info("DHCP-RELAY Stopped");
     }
@@ -224,44 +202,33 @@
         }
     }
 
-    /**
-     * Checks if this app has been configured.
-     *
-     * @return true if all information we need have been initialized
-     */
-    private boolean configured() {
-        return dhcpServerConnectPoint != null && dhcpServerIp != null;
-    }
-
     private void updateConfig() {
         DhcpRelayConfig cfg = cfgService.getConfig(appId, DhcpRelayConfig.class);
         if (cfg == null) {
             log.warn("Dhcp Server info not available");
             return;
         }
+        Optional<IpAddress> oldDhcpServerIp = v4Handler.getDhcpServerIp();
+        Optional<IpAddress> oldDhcpGatewayIp = v4Handler.getDhcpGatewayIp();
+        v4Handler.setDhcpServerConnectPoint(cfg.getDhcpServerConnectPoint());
+        v4Handler.setDhcpServerIp(cfg.getDhcpServerIp());
+        v4Handler.setDhcpGatewayIp(cfg.getDhcpGatewayIp());
+        v4Handler.setDhcpConnectMac(null);
+        v4Handler.setDhcpConnectVlan(null);
 
-        dhcpServerConnectPoint = cfg.getDhcpServerConnectPoint();
-        Ip4Address oldDhcpServerIp = dhcpServerIp;
-        Ip4Address oldDhcpGatewayIp = dhcpGatewayIp;
-        dhcpServerIp = cfg.getDhcpServerIp();
-        dhcpGatewayIp = cfg.getDhcpGatewayIp();
-        dhcpConnectMac = null; // reset for updated config
-        dhcpConnectVlan = null; // reset for updated config
-        log.info("DHCP server connect point: " + dhcpServerConnectPoint);
-        log.info("DHCP server ipaddress " + dhcpServerIp);
+        log.info("DHCP server connect point: " + cfg.getDhcpServerConnectPoint());
+        log.info("DHCP server ipaddress " + cfg.getDhcpServerIp());
 
-        IpAddress ipToProbe = dhcpGatewayIp != null ? dhcpGatewayIp : dhcpServerIp;
-        String hostToProbe = dhcpGatewayIp != null ? "gateway" : "DHCP server";
+        IpAddress ipToProbe = v4Handler.getDhcpGatewayIp().isPresent() ? cfg.getDhcpGatewayIp() :
+                                                                         cfg.getDhcpServerIp();
+        String hostToProbe = v4Handler.getDhcpGatewayIp().isPresent() ? "gateway" : "DHCP server";
 
+        // TODO: DHCPv6 server config
         Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
         if (hosts.isEmpty()) {
             log.info("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
-            if (oldDhcpGatewayIp != null) {
-                hostService.stopMonitoringIp(oldDhcpGatewayIp);
-            }
-            if (oldDhcpServerIp != null) {
-                hostService.stopMonitoringIp(oldDhcpServerIp);
-            }
+            oldDhcpGatewayIp.ifPresent(hostService::stopMonitoringIp);
+            oldDhcpServerIp.ifPresent(hostService::stopMonitoringIp);
             hostService.startMonitoringIp(ipToProbe);
         } else {
             // Probe target is known; There should be only 1 host with this ip
@@ -270,30 +237,39 @@
     }
 
     private void hostRemoved(Host host) {
-        if (host.ipAddresses().contains(dhcpServerIp)) {
-            log.warn("DHCP server {} removed", dhcpServerIp);
-            dhcpConnectMac = null;
-            dhcpConnectVlan = null;
-        }
-        if (dhcpGatewayIp != null && host.ipAddresses().contains(dhcpGatewayIp)) {
-            log.warn("DHCP gateway {} removed", dhcpGatewayIp);
-            dhcpConnectMac = null;
-            dhcpConnectVlan = null;
-        }
+        v4Handler.getDhcpServerIp().ifPresent(ip -> {
+            if (host.ipAddresses().contains(ip)) {
+                log.warn("DHCP server {} removed", ip);
+                v4Handler.setDhcpConnectMac(null);
+                v4Handler.setDhcpConnectVlan(null);
+            }
+        });
+        v4Handler.getDhcpGatewayIp().ifPresent(ip -> {
+            if (host.ipAddresses().contains(ip)) {
+                log.warn("DHCP gateway {} removed", ip);
+                v4Handler.setDhcpConnectMac(null);
+                v4Handler.setDhcpConnectVlan(null);
+            }
+        });
+        // TODO: v6 handler
     }
 
     private void hostUpdated(Host host) {
-        if (dhcpGatewayIp != null && host.ipAddresses().contains(dhcpGatewayIp)) {
-            dhcpConnectMac = host.mac();
-            dhcpConnectVlan = host.vlan();
-            log.info("DHCP gateway {} resolved to Mac/Vlan:{}/{}", dhcpGatewayIp,
-                     dhcpConnectMac, dhcpConnectVlan);
-        } else if (host.ipAddresses().contains(dhcpServerIp)) {
-            dhcpConnectMac = host.mac();
-            dhcpConnectVlan = host.vlan();
-            log.info("DHCP server {} resolved to Mac/Vlan:{}/{}", dhcpServerIp,
-                    dhcpConnectMac, dhcpConnectVlan);
-        }
+        v4Handler.getDhcpGatewayIp().ifPresent(ip -> {
+            if (host.ipAddresses().contains(ip)) {
+                log.warn("DHCP gateway {} removed", ip);
+                v4Handler.setDhcpConnectMac(host.mac());
+                v4Handler.setDhcpConnectVlan(host.vlan());
+            }
+        });
+        v4Handler.getDhcpServerIp().ifPresent(ip -> {
+            if (host.ipAddresses().contains(ip)) {
+                log.warn("DHCP server {} removed", ip);
+                v4Handler.setDhcpConnectMac(host.mac());
+                v4Handler.setDhcpConnectVlan(host.vlan());
+            }
+        });
+        // TODO: v6 handler
     }
 
     /**
@@ -360,174 +336,7 @@
 
     @Override
     public Optional<MacAddress> getDhcpServerMacAddress() {
-        return Optional.ofNullable(dhcpConnectMac);
-    }
-
-    /**
-     * Gets output interface of a dhcp packet.
-     * If option 82 exists in the dhcp packet and the option was sent by
-     * ONOS (gateway address exists in ONOS interfaces), use the connect
-     * point and vlan id from circuit id; otherwise, find host by destination
-     * address and use vlan id from sender (dhcp server).
-     *
-     * @param ethPacket the ethernet packet
-     * @param dhcpPayload the dhcp packet
-     * @return an interface represent the output port and vlan; empty value
-     *         if the host or circuit id not found
-     */
-    private Optional<Interface> getOutputInterface(Ethernet ethPacket, DHCP dhcpPayload) {
-        VlanId originalPacketVlanId = VlanId.vlanId(ethPacket.getVlanID());
-        IpAddress gatewayIpAddress = Ip4Address.valueOf(dhcpPayload.getGatewayIPAddress());
-        Set<Interface> gatewayInterfaces = interfaceService.getInterfacesByIp(gatewayIpAddress);
-        DhcpRelayAgentOption option = (DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
-
-        // Sent by ONOS, and contains circuit id
-        if (!gatewayInterfaces.isEmpty() && option != null) {
-            DhcpOption circuitIdSubOption = option.getSubOption(CIRCUIT_ID.getValue());
-            try {
-                CircuitId circuitId = CircuitId.deserialize(circuitIdSubOption.getData());
-                ConnectPoint connectPoint = ConnectPoint.deviceConnectPoint(circuitId.connectPoint());
-                VlanId vlanId = circuitId.vlanId();
-                return Optional.of(new Interface(null, connectPoint, null, null, vlanId));
-            } catch (IllegalArgumentException ex) {
-                // invalid circuit format, didn't sent by ONOS
-                log.debug("Invalid circuit {}, use information from dhcp payload",
-                          circuitIdSubOption.getData());
-            }
-        }
-
-        // Use Vlan Id from DHCP server if DHCP relay circuit id was not
-        // sent by ONOS or circuit Id can't be parsed
-        MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
-        Optional<DhcpRecord> dhcpRecord = dhcpRelayStore.getDhcpRecord(HostId.hostId(dstMac, originalPacketVlanId));
-        return dhcpRecord
-                .map(DhcpRecord::locations)
-                .orElse(Collections.emptySet())
-                .stream()
-                .reduce((hl1, hl2) -> {
-                    if (hl1 == null || hl2 == null) {
-                        return hl1 == null ? hl2 : hl1;
-                    }
-                    return hl1.time() > hl2.time() ? hl1 : hl2;
-                })
-                .map(lastLocation -> new Interface(null, lastLocation, null, null, originalPacketVlanId));
-    }
-
-    /**
-     * Send the response DHCP to the requester host.
-     *
-     * @param ethPacket the packet
-     * @param dhcpPayload the DHCP data
-     */
-    private void handleDhcpOffer(Ethernet ethPacket, DHCP dhcpPayload) {
-        Optional<Interface> outInterface = getOutputInterface(ethPacket, dhcpPayload);
-        outInterface.ifPresent(theInterface -> {
-            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                    .setOutput(theInterface.connectPoint().port())
-                    .build();
-            OutboundPacket o = new DefaultOutboundPacket(
-                    theInterface.connectPoint().deviceId(),
-                    treatment,
-                    ByteBuffer.wrap(ethPacket.serialize()));
-            if (log.isTraceEnabled()) {
-                log.trace("Relaying packet to DHCP client {} via {}, vlan {}",
-                          ethPacket,
-                          theInterface.connectPoint(),
-                          theInterface.vlan());
-            }
-            packetService.emit(o);
-        });
-    }
-
-    /**
-     * Send the DHCP ack to the requester host.
-     *
-     * @param ethernetPacketAck the packet
-     * @param dhcpPayload the DHCP data
-     */
-    private void handleDhcpAck(Ethernet ethernetPacketAck, DHCP dhcpPayload) {
-        Optional<Interface> outInterface = getOutputInterface(ethernetPacketAck, dhcpPayload);
-        if (!outInterface.isPresent()) {
-            log.warn("Can't find output interface for dhcp: {}", dhcpPayload);
-            return;
-        }
-
-        Interface outIface = outInterface.get();
-        HostLocation hostLocation = new HostLocation(outIface.connectPoint(), System.currentTimeMillis());
-        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
-        VlanId vlanId = outIface.vlan();
-        HostId hostId = HostId.hostId(macAddress, vlanId);
-        Ip4Address ip = Ip4Address.valueOf(dhcpPayload.getYourIPAddress());
-
-        if (directlyConnected(dhcpPayload)) {
-            // Add to host store if it connect to network directly
-            Set<IpAddress> ips = Sets.newHashSet(ip);
-            HostDescription desc = new DefaultHostDescription(macAddress, vlanId,
-                                                              hostLocation, ips);
-
-            // Replace the ip when dhcp server give the host new ip address
-            hostStore.createOrUpdateHost(PROVIDER_ID, hostId, desc, true);
-        } else {
-            // Add to route store if it does not connect to network directly
-            // Get gateway host IP according to host mac address
-            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
-
-            if (record == null) {
-                log.warn("Can't find DHCP record of host {}", hostId);
-                return;
-            }
-
-            MacAddress gwMac = record.nextHop().orElse(null);
-            if (gwMac == null) {
-                log.warn("Can't find gateway mac address from record {}", record);
-                return;
-            }
-
-            HostId gwHostId = HostId.hostId(gwMac, record.vlanId());
-            Host gwHost = hostService.getHost(gwHostId);
-
-            if (gwHost == null) {
-                log.warn("Can't find gateway host {}", gwHostId);
-                return;
-            }
-
-            Ip4Address nextHopIp = gwHost.ipAddresses()
-                    .stream()
-                    .filter(IpAddress::isIp4)
-                    .map(IpAddress::getIp4Address)
-                    .findFirst()
-                    .orElse(null);
-
-            if (nextHopIp == null) {
-                log.warn("Can't find IP address of gateway {}", gwHost);
-                return;
-            }
-
-            Route route = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp);
-            routeStore.updateRoute(route);
-        }
-        handleDhcpOffer(ethernetPacketAck, dhcpPayload);
-    }
-
-    /**
-     * forward the packet to ConnectPoint where the DHCP server is attached.
-     *
-     * @param packet the packet
-     */
-    private void handleDhcpDiscoverAndRequest(Ethernet packet) {
-        // send packet to dhcp server connect point.
-        if (dhcpServerConnectPoint != null) {
-            TrafficTreatment t = DefaultTrafficTreatment.builder()
-                    .setOutput(dhcpServerConnectPoint.port()).build();
-            OutboundPacket o = new DefaultOutboundPacket(
-                    dhcpServerConnectPoint.deviceId(), t, ByteBuffer.wrap(packet.serialize()));
-            if (log.isTraceEnabled()) {
-                log.trace("Relaying packet to dhcp server {}", packet);
-            }
-            packetService.emit(o);
-        } else {
-            log.warn("Can't find DHCP server connect point, abort.");
-        }
+        return v4Handler.getDhcpConnectMac();
     }
 
     /**
@@ -572,41 +381,11 @@
                 .findFirst();
     }
 
-    /**
-     * Check if the host is directly connected to the network or not.
-     *
-     * @param dhcpPayload the dhcp payload
-     * @return true if the host is directly connected to the network; false otherwise
-     */
-    private boolean directlyConnected(DHCP dhcpPayload) {
-        DhcpOption relayAgentOption = dhcpPayload.getOption(OptionCode_CircuitID);
-
-        // Doesn't contains relay option
-        if (relayAgentOption == null) {
-            return true;
-        }
-
-        IpAddress gatewayIp = IpAddress.valueOf(dhcpPayload.getGatewayIPAddress());
-        Set<Interface> gatewayInterfaces = interfaceService.getInterfacesByIp(gatewayIp);
-
-        // Contains relay option, and added by ONOS
-        if (!gatewayInterfaces.isEmpty()) {
-            return true;
-        }
-
-        // Relay option added by other relay agent
-        return false;
-    }
 
     private class DhcpRelayPacketProcessor implements PacketProcessor {
 
         @Override
         public void process(PacketContext context) {
-            if (!configured()) {
-                log.warn("Missing DHCP relay server config. Abort packet processing");
-                return;
-            }
-
             // process the packet and get the payload
             Ethernet packet = context.inPacket().parsed();
             if (packet == null) {
@@ -614,12 +393,11 @@
             }
 
             findDhcp(packet).ifPresent(dhcpPayload -> {
-                processDhcpPacket(context, dhcpPayload);
+                v4Handler.processDhcpPacket(context, dhcpPayload);
             });
 
             findDhcp6(packet).ifPresent(dhcp6Payload -> {
-                // TODO: handle DHCPv6 packet
-                log.warn("DHCPv6 unsupported.");
+                v6Handler.processDhcpPacket(context, dhcp6Payload);
             });
 
             if (packet.getEtherType() == Ethernet.TYPE_ARP && arpEnabled) {
@@ -641,8 +419,7 @@
                         .map(Interface::mac)
                         .filter(mac -> !mac.equals(MacAddress.NONE))
                         .findFirst()
-                        .orElse(null);
-
+                        .orElse(MacAddress.ONOS);
                 if (interfaceMac == null) {
                     // can't find interface mac address
                     return;
@@ -686,263 +463,6 @@
             }
             packetService.emit(o);
         }
-
-        // process the dhcp packet before sending to server
-        private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) {
-            ConnectPoint inPort = context.inPacket().receivedFrom();
-            Set<Interface> clientServerInterfaces = interfaceService.getInterfacesByPort(inPort);
-            // ignore the packets if dhcp client interface is not configured on onos.
-            if (clientServerInterfaces.isEmpty()) {
-                log.warn("Virtual interface is not configured on {}", inPort);
-                return;
-            }
-            checkNotNull(dhcpPayload, "Can't find DHCP payload");
-            Ethernet packet = context.inPacket().parsed();
-            DHCP.MsgType incomingPacketType = dhcpPayload.getOptions().stream()
-                    .filter(dhcpOption -> dhcpOption.getCode() == OptionCode_MessageType.getValue())
-                    .map(DhcpOption::getData)
-                    .map(data -> DHCP.MsgType.getType(data[0]))
-                    .findFirst()
-                    .orElse(null);
-            checkNotNull(incomingPacketType, "Can't get message type from DHCP payload {}", dhcpPayload);
-            switch (incomingPacketType) {
-                case DHCPDISCOVER:
-                    // add the gatewayip as virtual interface ip for server to understand
-                    // the lease to be assigned and forward the packet to dhcp server.
-                    Ethernet ethernetPacketDiscover =
-                            processDhcpPacketFromClient(context, packet, clientServerInterfaces);
-
-                    if (ethernetPacketDiscover != null) {
-                        writeRequestDhcpRecord(inPort, packet, dhcpPayload);
-                        handleDhcpDiscoverAndRequest(ethernetPacketDiscover);
-                    }
-                    break;
-                case DHCPOFFER:
-                    //reply to dhcp client.
-                    Ethernet ethernetPacketOffer = processDhcpPacketFromServer(packet);
-                    if (ethernetPacketOffer != null) {
-                        writeResponseDhcpRecord(ethernetPacketOffer, dhcpPayload);
-                        handleDhcpOffer(ethernetPacketOffer, dhcpPayload);
-                    }
-                    break;
-                case DHCPREQUEST:
-                    // add the gateway ip as virtual interface ip for server to understand
-                    // the lease to be assigned and forward the packet to dhcp server.
-                    Ethernet ethernetPacketRequest =
-                            processDhcpPacketFromClient(context, packet, clientServerInterfaces);
-                    if (ethernetPacketRequest != null) {
-                        writeRequestDhcpRecord(inPort, packet, dhcpPayload);
-                        handleDhcpDiscoverAndRequest(ethernetPacketRequest);
-                    }
-                    break;
-                case DHCPACK:
-                    // reply to dhcp client.
-                    Ethernet ethernetPacketAck = processDhcpPacketFromServer(packet);
-                    if (ethernetPacketAck != null) {
-                        writeResponseDhcpRecord(ethernetPacketAck, dhcpPayload);
-                        handleDhcpAck(ethernetPacketAck, dhcpPayload);
-                    }
-                    break;
-                case DHCPRELEASE:
-                    // TODO: release the ip address from client
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        private void writeRequestDhcpRecord(ConnectPoint location,
-                                            Ethernet ethernet,
-                                            DHCP dhcpPayload) {
-            VlanId vlanId = VlanId.vlanId(ethernet.getVlanID());
-            MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
-            HostId hostId = HostId.hostId(macAddress, vlanId);
-            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
-            if (record == null) {
-                record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
-            } else {
-                record = record.clone();
-            }
-            record.addLocation(new HostLocation(location, System.currentTimeMillis()));
-            record.ip4Status(dhcpPayload.getPacketType());
-            record.setDirectlyConnected(directlyConnected(dhcpPayload));
-            if (!directlyConnected(dhcpPayload)) {
-                // Update gateway mac address if the host is not directly connected
-                record.nextHop(ethernet.getSourceMAC());
-            }
-            record.updateLastSeen();
-            dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
-        }
-
-        private void writeResponseDhcpRecord(Ethernet ethernet,
-                                             DHCP dhcpPayload) {
-            Optional<Interface> outInterface = getOutputInterface(ethernet, dhcpPayload);
-            if (!outInterface.isPresent()) {
-                log.warn("Failed to determine where to send {}", dhcpPayload.getPacketType());
-                return;
-            }
-
-            Interface outIface = outInterface.get();
-            ConnectPoint location = outIface.connectPoint();
-            VlanId vlanId = outIface.vlan();
-            MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
-            HostId hostId = HostId.hostId(macAddress, vlanId);
-            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
-            if (record == null) {
-                record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
-            } else {
-                record = record.clone();
-            }
-            record.addLocation(new HostLocation(location, System.currentTimeMillis()));
-            if (dhcpPayload.getPacketType() == DHCP.MsgType.DHCPACK) {
-                record.ip4Address(Ip4Address.valueOf(dhcpPayload.getYourIPAddress()));
-            }
-            record.ip4Status(dhcpPayload.getPacketType());
-            record.setDirectlyConnected(directlyConnected(dhcpPayload));
-            record.updateLastSeen();
-            dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
-        }
-
-        //build the DHCP discover/request packet with gatewayip(unicast packet)
-        private Ethernet processDhcpPacketFromClient(PacketContext context,
-                             Ethernet ethernetPacket, Set<Interface> clientInterfaces) {
-            Ip4Address relayAgentIp = getRelayAgentIPv4Address(clientInterfaces);
-            MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
-            if (relayAgentIp == null || relayAgentMac == null) {
-                log.warn("Missing DHCP relay agent interface Ipv4 addr config for "
-                        + "packet from client on port: {}. Aborting packet processing",
-                         clientInterfaces.iterator().next().connectPoint());
-                return null;
-            }
-            if (dhcpConnectMac == null) {
-                log.warn("DHCP {} not yet resolved .. Aborting DHCP "
-                        + "packet processing from client on port: {}",
-                        (dhcpGatewayIp == null) ? "server IP " + dhcpServerIp
-                                                : "gateway IP " + dhcpGatewayIp,
-                        clientInterfaces.iterator().next().connectPoint());
-                return null;
-            }
-            // get dhcp header.
-            Ethernet etherReply = (Ethernet) ethernetPacket.clone();
-            etherReply.setSourceMACAddress(relayAgentMac);
-            etherReply.setDestinationMACAddress(dhcpConnectMac);
-            etherReply.setVlanID(dhcpConnectVlan.toShort());
-            IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
-            ipv4Packet.setSourceAddress(relayAgentIp.toInt());
-            ipv4Packet.setDestinationAddress(dhcpServerIp.toInt());
-            UDP udpPacket = (UDP) ipv4Packet.getPayload();
-            DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
-
-            // If there is no relay agent option(option 82), add one to DHCP payload
-            boolean containsRelayAgentOption = dhcpPacket.getOptions().stream()
-                    .map(DhcpOption::getCode)
-                    .anyMatch(code -> code == OptionCode_CircuitID.getValue());
-
-            if (!containsRelayAgentOption) {
-                ConnectPoint inPort = context.inPacket().receivedFrom();
-                VlanId vlanId = VlanId.vlanId(ethernetPacket.getVlanID());
-                // add connected in port and vlan
-                CircuitId cid = new CircuitId(inPort.toString(), vlanId);
-                byte[] circuitId = cid.serialize();
-
-                if (circuitId != null) {
-                    DhcpOption circuitIdSubOpt = new DhcpOption();
-                    circuitIdSubOpt
-                            .setCode(CIRCUIT_ID.getValue())
-                            .setLength((byte) circuitId.length)
-                            .setData(circuitId);
-
-                    DhcpRelayAgentOption newRelayAgentOpt = new DhcpRelayAgentOption();
-                    newRelayAgentOpt.setCode(OptionCode_CircuitID.getValue());
-                    newRelayAgentOpt.addSubOption(circuitIdSubOpt);
-
-                    // push new circuit id to last
-                    List<DhcpOption> options = dhcpPacket.getOptions();
-                    options.add(newRelayAgentOpt);
-
-                    // make sure option 255(End) is the last option
-                    options.sort((opt1, opt2) -> opt2.getCode() - opt1.getCode());
-                    dhcpPacket.setOptions(options);
-
-                    dhcpPacket.setGatewayIPAddress(relayAgentIp.toInt());
-                } else {
-                    log.warn("Can't generate circuit id for port {}, vlan {}", inPort, vlanId);
-                }
-            } else {
-                // TODO: if it contains a relay agent information, sets gateway ip
-                // according to the information it provided
-            }
-
-            udpPacket.setPayload(dhcpPacket);
-            udpPacket.setSourcePort(UDP.DHCP_CLIENT_PORT);
-            udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
-            ipv4Packet.setPayload(udpPacket);
-            etherReply.setPayload(ipv4Packet);
-            return etherReply;
-        }
-
-        // Returns the first v4 interface ip out of a set of interfaces or null.
-        // Checks all interfaces, and ignores v6 interface ips
-        private Ip4Address getRelayAgentIPv4Address(Set<Interface> intfs) {
-            for (Interface intf : intfs) {
-                for (InterfaceIpAddress ip : intf.ipAddressesList()) {
-                    Ip4Address relayAgentIp = ip.ipAddress().getIp4Address();
-                    if (relayAgentIp != null) {
-                        return relayAgentIp;
-                    }
-                }
-            }
-            return null;
-        }
-
-        //build the DHCP offer/ack with proper client port.
-        private Ethernet processDhcpPacketFromServer(Ethernet ethernetPacket) {
-            // get dhcp header.
-            Ethernet etherReply = (Ethernet) ethernetPacket.clone();
-            IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
-            UDP udpPacket = (UDP) ipv4Packet.getPayload();
-            DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
-
-            // determine the vlanId of the client host - note that this vlan id
-            // could be different from the vlan in the packet from the server
-            Interface outInterface = getOutputInterface(ethernetPacket, dhcpPayload).orElse(null);
-
-            if (outInterface == null) {
-                log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
-                return null;
-            }
-
-            etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
-            etherReply.setVlanID(outInterface.vlan().toShort());
-            // we leave the srcMac from the original packet
-
-            // figure out the relay agent IP corresponding to the original request
-            Ip4Address relayAgentIP = getRelayAgentIPv4Address(
-                          interfaceService.getInterfacesByPort(outInterface.connectPoint()));
-            if (relayAgentIP == null) {
-                log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. "
-                        + "Aborting relay for dhcp packet from server {}",
-                         etherReply.getDestinationMAC(), outInterface.vlan(),
-                         ethernetPacket);
-                return null;
-            }
-            // SRC_IP: relay agent IP
-            // DST_IP: offered IP
-            ipv4Packet.setSourceAddress(relayAgentIP.toInt());
-            ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
-            udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
-            if (directlyConnected(dhcpPayload)) {
-                udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
-            } else {
-                // forward to another dhcp relay
-                udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
-            }
-
-            udpPacket.setPayload(dhcpPayload);
-            ipv4Packet.setPayload(udpPacket);
-            etherReply.setPayload(ipv4Packet);
-            return etherReply;
-        }
     }
 
     /**
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
new file mode 100644
index 0000000..d015532
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay.api;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.packet.PacketContext;
+
+import java.util.Optional;
+
+/**
+ * DHCP relay handler.
+ */
+public interface DhcpHandler {
+    /**
+     * Process the DHCP packet before sending to server or client.
+     *
+     * @param context the packet context
+     * @param dhcpPayload the DHCP payload
+     */
+    void processDhcpPacket(PacketContext context, BasePacket dhcpPayload);
+
+    /**
+     * Gets DHCP server IP.
+     *
+     * @return IP address of DHCP server; empty value if not exist
+     */
+    Optional<IpAddress> getDhcpServerIp();
+
+    /**
+     * Gets DHCP gateway IP.
+     *
+     * @return IP address of DHCP gateway; empty value if not exist
+     */
+    Optional<IpAddress> getDhcpGatewayIp();
+
+    /**
+     * Gets DHCP connect Mac address.
+     *
+     * @return the connect Mac address of server or gateway
+     */
+    Optional<MacAddress> getDhcpConnectMac();
+
+    /**
+     * Sets DHCP gateway IP.
+     *
+     * @param dhcpGatewayIp the DHCP gateway IP
+     */
+    void setDhcpGatewayIp(IpAddress dhcpGatewayIp);
+
+    /**
+     * Sets DHCP connect vlan.
+     *
+     * @param dhcpConnectVlan the DHCP connect vlan
+     */
+    void setDhcpConnectVlan(VlanId dhcpConnectVlan);
+
+    /**
+     * Sets DHCP connect Mac address.
+     *
+     * @param dhcpConnectMac the connect Mac address
+     */
+    void setDhcpConnectMac(MacAddress dhcpConnectMac);
+
+    /**
+     * Sets DHCP server connect point.
+     *
+     * @param dhcpServerConnectPoint the server connect point
+     */
+    void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint);
+
+    /**
+     * Sets DHCP server IP.
+     *
+     * @param dhcpServerIp the DHCP server IP
+     */
+    void setDhcpServerIp(IpAddress dhcpServerIp);
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayService.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpRelayService.java
similarity index 96%
rename from apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayService.java
rename to apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpRelayService.java
index c4ab2d1..9bad009 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayService.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpRelayService.java
@@ -12,9 +12,10 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
  */
 
-package org.onosproject.dhcprelay;
+package org.onosproject.dhcprelay.api;
 
 import org.onlab.packet.MacAddress;
 import org.onosproject.dhcprelay.store.DhcpRecord;
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/package-info.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/package-info.java
new file mode 100644
index 0000000..fa239e8
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * APIs for DHCP relay application.
+ */
+package org.onosproject.dhcprelay.api;
\ No newline at end of file
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
index be4b75c..089b8ba 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
@@ -27,7 +27,7 @@
 import org.onosproject.core.CoreService;
 import org.onosproject.dhcprelay.DhcpRelayConfig;
 import org.onosproject.dhcprelay.DhcpRelayManager;
-import org.onosproject.dhcprelay.DhcpRelayService;
+import org.onosproject.dhcprelay.api.DhcpRelayService;
 import org.onosproject.dhcprelay.store.DhcpRecord;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Host;
diff --git a/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
index 784524a..3b8e08c 100644
--- a/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
+++ b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
@@ -186,13 +186,20 @@
         mockHostStore = new MockHostStore();
         mockRouteStore = new MockRouteStore();
         mockDhcpRelayStore = new MockDhcpRelayStore();
-
-        manager.hostStore = mockHostStore;
-        manager.routeStore = mockRouteStore;
         manager.dhcpRelayStore = mockDhcpRelayStore;
 
         manager.interfaceService = new MockInterfaceService();
 
+        Dhcp4HandlerImpl v4Handler = new Dhcp4HandlerImpl();
+        v4Handler.dhcpRelayStore = mockDhcpRelayStore;
+        v4Handler.hostService = manager.hostService;
+        v4Handler.hostStore = mockHostStore;
+        v4Handler.interfaceService = manager.interfaceService;
+        v4Handler.packetService = manager.packetService;
+        v4Handler.routeStore = mockRouteStore;
+        manager.v4Handler = v4Handler;
+
+        // TODO: initialize v6 handler.
         // properties
         Dictionary<String, Object> dictionary = createNiceMock(Dictionary.class);
         expect(dictionary.get("arpEnabled")).andReturn(true).anyTimes();
