diff --git a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
index 7190aea..b762e79 100644
--- a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
+++ b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
@@ -28,7 +28,6 @@
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.packet.ARP;
 import org.onlab.packet.DHCP;
-import org.onlab.packet.dhcp.DhcpOption;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
@@ -37,6 +36,7 @@
 import org.onlab.packet.TpPort;
 import org.onlab.packet.UDP;
 import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.DhcpOption;
 import org.onlab.util.SharedScheduledExecutors;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
@@ -77,6 +77,7 @@
 import java.util.Date;
 import java.util.Dictionary;
 import java.util.HashSet;
+
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
diff --git a/apps/dhcprelay/BUCK b/apps/dhcprelay/BUCK
index e420f72..4a2b65c 100644
--- a/apps/dhcprelay/BUCK
+++ b/apps/dhcprelay/BUCK
@@ -6,6 +6,8 @@
 
 TEST_DEPS = [
     '//lib:TEST_ADAPTERS',
+    '//core/api:onos-api-tests',
+    '//incubator/api:onos-incubator-api-tests',
 ]
 
 osgi_jar_with_tests (
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelay.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelay.java
deleted file mode 100644
index 778f778..0000000
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelay.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * 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 java.nio.ByteBuffer;
-import java.util.Dictionary;
-import java.util.Objects;
-import java.util.Set;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.ARP;
-import org.onlab.packet.DHCP;
-import org.onlab.packet.dhcp.DhcpOption;
-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.util.Tools;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.config.ConfigFactory;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-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.PacketPriority;
-import org.onosproject.net.packet.PacketProcessor;
-import org.onosproject.net.packet.PacketService;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableSet;
-
-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.
- */
-@Component(immediate = true)
-public class DhcpRelay {
-
-    public static final String DHCP_RELAY_APP = "org.onosproject.dhcp-relay";
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final InternalConfigListener cfgListener = new InternalConfigListener();
-    private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
-
-    private final Set<ConfigFactory> factories = ImmutableSet.of(
-            new ConfigFactory<ApplicationId, DhcpRelayConfig>(APP_SUBJECT_FACTORY,
-                    DhcpRelayConfig.class,
-                    "dhcprelay") {
-                @Override
-                public DhcpRelayConfig createConfig() {
-                    return new DhcpRelayConfig();
-                }
-            }
-    );
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigRegistry cfgService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected PacketService packetService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostService hostService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected InterfaceService interfaceService;
-
-    @Property(name = "arpEnabled", boolValue = true,
-            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
-    protected void activate(ComponentContext context) {
-        //start the dhcp relay agent
-        appId = coreService.registerApplication(DHCP_RELAY_APP);
-
-        cfgService.addListener(cfgListener);
-        factories.forEach(cfgService::registerConfigFactory);
-        //update the dhcp server configuration.
-        updateConfig();
-        //add the packet services.
-        packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
-        hostService.addListener(hostListener);
-        requestDhcpPackets();
-        modified(context);
-
-        log.info("DHCP-RELAY Started");
-    }
-
-    @Deactivate
-    protected void deactivate() {
-        cfgService.removeListener(cfgListener);
-        factories.forEach(cfgService::unregisterConfigFactory);
-        packetService.removeProcessor(dhcpRelayPacketProcessor);
-        hostService.removeListener(hostListener);
-        cancelDhcpPackets();
-        cancelArpPackets();
-        if (dhcpGatewayIp != null) {
-            hostService.stopMonitoringIp(dhcpGatewayIp);
-        } else {
-            hostService.stopMonitoringIp(dhcpServerIp);
-        }
-
-        log.info("DHCP-RELAY Stopped");
-    }
-
-    @Modified
-    protected void modified(ComponentContext context) {
-        Dictionary<?, ?> properties = context.getProperties();
-        Boolean flag;
-
-        flag = Tools.isPropertyEnabled(properties, "arpEnabled");
-        if (flag != null) {
-            arpEnabled = flag;
-            log.info("Address resolution protocol is {}",
-                     arpEnabled ? "enabled" : "disabled");
-        }
-
-        if (arpEnabled) {
-            requestArpPackets();
-        } else {
-            cancelArpPackets();
-        }
-    }
-
-    /**
-     * 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;
-        }
-
-        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);
-
-        IpAddress ipToProbe = dhcpGatewayIp != null ? dhcpGatewayIp : dhcpServerIp;
-        String hostToProbe = dhcpGatewayIp != null ? "gateway" : "DHCP server";
-
-        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);
-            }
-            hostService.startMonitoringIp(ipToProbe);
-        } else {
-            // Probe target is known; There should be only 1 host with this ip
-            hostUpdated(hosts.iterator().next());
-        }
-    }
-
-    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;
-        }
-    }
-
-    private void hostUpdated(Host host) {
-        if (dhcpGatewayIp != null) {
-            if (host.ipAddresses().contains(dhcpGatewayIp)) {
-                dhcpConnectMac = host.mac();
-                dhcpConnectVlan = host.vlan();
-                log.info("DHCP gateway {} resolved to Mac/Vlan:{}/{}", dhcpGatewayIp,
-                        dhcpConnectMac, dhcpConnectVlan);
-            }
-            return;
-        }
-        if (host.ipAddresses().contains(dhcpServerIp)) {
-            dhcpConnectMac = host.mac();
-            dhcpConnectVlan = host.vlan();
-            log.info("DHCP server {} resolved to Mac/Vlan:{}/{}", dhcpServerIp,
-                    dhcpConnectMac, dhcpConnectVlan);
-        }
-    }
-
-    /**
-     * Request DHCP packet in via PacketService.
-     */
-    private void requestDhcpPackets() {
-        TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPProtocol(IPv4.PROTOCOL_UDP)
-                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
-        packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
-
-        TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPProtocol(IPv4.PROTOCOL_UDP)
-                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
-        packetService.requestPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
-    }
-
-    /**
-     * Cancel requested DHCP packets in via packet service.
-     */
-    private void cancelDhcpPackets() {
-        TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPProtocol(IPv4.PROTOCOL_UDP)
-                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
-        packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
-
-        TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPProtocol(IPv4.PROTOCOL_UDP)
-                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
-        packetService.cancelPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
-    }
-
-    /**
-     * Request ARP packet in via PacketService.
-     */
-    private void requestArpPackets() {
-        TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_ARP);
-        packetService.requestPackets(selectorArpServer.build(), PacketPriority.CONTROL, appId);
-    }
-
-    /**
-     * Cancel requested ARP packets in via packet service.
-     */
-    private void cancelArpPackets() {
-        TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_ARP);
-        packetService.cancelPackets(selectorArpServer.build(), PacketPriority.CONTROL, appId);
-    }
-
-    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) {
-                return;
-            }
-
-            if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
-                IPv4 ipv4Packet = (IPv4) packet.getPayload();
-
-                if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
-                    UDP udpPacket = (UDP) ipv4Packet.getPayload();
-                    DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
-                    if (udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT ||
-                        udpPacket.getSourcePort() == UDP.DHCP_SERVER_PORT) {
-                        //This packet is dhcp.
-                        processDhcpPacket(context, dhcpPayload);
-                    }
-                }
-            } else if (packet.getEtherType() == Ethernet.TYPE_ARP && arpEnabled) {
-                ARP arpPacket = (ARP) packet.getPayload();
-                Set<Interface> serverInterfaces = interfaceService.
-                        getInterfacesByPort(context.inPacket().receivedFrom());
-                //ignore the packets if dhcp server interface is not configured on onos.
-                if (serverInterfaces.isEmpty()) {
-                    log.warn("server virtual interface not configured");
-                    return;
-                }
-                if ((arpPacket.getOpCode() == ARP.OP_REQUEST) &&
-                        checkArpRequestFrmDhcpServ(serverInterfaces, arpPacket)) {
-                    processArpPacket(context, packet);
-                }
-            }
-        }
-
-        //method to check the arp request is from dhcp server for default-gateway.
-        private boolean checkArpRequestFrmDhcpServ(Set<Interface> serverInterfaces, ARP arpPacket) {
-            if (Objects.equals(serverInterfaces.iterator().next().ipAddressesList().get(0).
-                    ipAddress().getIp4Address(),
-                    Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) {
-                return true;
-            }
-            return false;
-        }
-
-        //forward the packet to ConnectPoint where the DHCP server is attached.
-        private void forwardPacket(Ethernet packet) {
-            //send Packetout to dhcp server connectpoint.
-            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);
-            }
-        }
-
-        /**
-         * Processes the ARP Payload and initiates a reply to the client.
-         *
-         * @param context context of the incoming message
-         * @param packet the ethernet payload
-         */
-        private void processArpPacket(PacketContext context, Ethernet packet) {
-            ARP arpPacket = (ARP) packet.getPayload();
-
-            ARP arpReply = (ARP) arpPacket.clone();
-            arpReply.setOpCode(ARP.OP_REPLY);
-
-            arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
-            arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress());
-            arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress());
-            arpReply.setSenderHardwareAddress(myMAC.toBytes());
-
-            // Ethernet Frame.
-            Ethernet ethReply = new Ethernet();
-            ethReply.setSourceMACAddress(myMAC);
-            ethReply.setDestinationMACAddress(packet.getSourceMAC());
-            ethReply.setEtherType(Ethernet.TYPE_ARP);
-            ethReply.setVlanID(packet.getVlanID());
-
-            ethReply.setPayload(arpReply);
-            forwardPacket(ethReply);
-        }
-
-        //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;
-            }
-
-            if (dhcpPayload == null) {
-                return;
-            }
-
-            Ethernet packet = context.inPacket().parsed();
-            DHCP.MsgType incomingPacketType = null;
-            for (DhcpOption option : dhcpPayload.getOptions()) {
-                if (option.getCode() == OptionCode_MessageType.getValue()) {
-                    byte[] data = option.getData();
-                    incomingPacketType = DHCP.MsgType.getType(data[0]);
-                }
-            }
-
-            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) {
-                    forwardPacket(ethernetPacketDiscover);
-                }
-                break;
-            case DHCPOFFER:
-                //reply to dhcp client.
-                Ethernet ethernetPacketOffer = processDhcpPacketFromServer(packet);
-                if (ethernetPacketOffer != null) {
-                    sendReply(ethernetPacketOffer, dhcpPayload);
-                }
-                break;
-            case DHCPREQUEST:
-                // add the gatewayip 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) {
-                    forwardPacket(ethernetPacketRequest);
-                }
-                break;
-            case DHCPACK:
-                //reply to dhcp client.
-                Ethernet ethernetPacketAck = processDhcpPacketFromServer(packet);
-                if (ethernetPacketAck != null) {
-                    sendReply(ethernetPacketAck, dhcpPayload);
-                }
-                break;
-            default:
-                break;
-            }
-        }
-
-        //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();
-            dhcpPacket.setGatewayIPAddress(relayAgentIp.toInt());
-            udpPacket.setPayload(dhcpPacket);
-            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
-            MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
-            Set<Host> hosts = hostService.getHostsByMac(dstMac);
-            if (hosts == null || hosts.isEmpty()) {
-                log.warn("Cannot determine host for DHCP client: {}. Aborting "
-                        + "relay for dhcp packet from server {}",
-                         dhcpPayload.getClientHardwareAddress(), ethernetPacket);
-                return null;
-            } else if (hosts.size() > 1) {
-                // XXX  redo to send reply to all hosts found
-                log.warn("Multiple hosts found for mac:{}. Picking one "
-                        + "host out of {}", dstMac, hosts);
-            }
-            Host host = hosts.iterator().next();
-            etherReply.setDestinationMACAddress(dstMac);
-            etherReply.setVlanID(host.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(host.location()));
-            if (relayAgentIP == null) {
-                log.warn("Cannot determine relay agent interface Ipv4 addr for host {}. "
-                        + "Aborting relay for dhcp packet from server {}",
-                        host, ethernetPacket);
-                return null;
-            }
-            // SRC_IP: relay agent IP
-            // DST_IP: offered IP
-            ipv4Packet.setSourceAddress(relayAgentIP.toInt());
-            ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
-
-            udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
-            udpPacket.setPayload(dhcpPayload);
-            ipv4Packet.setPayload(udpPacket);
-            etherReply.setPayload(ipv4Packet);
-            return etherReply;
-        }
-
-        //send the response to the requester host.
-        private void sendReply(Ethernet ethPacket, DHCP dhcpPayload) {
-            MacAddress descMac = valueOf(dhcpPayload.getClientHardwareAddress());
-            Host host = hostService.getHost(HostId.hostId(descMac,
-                    VlanId.vlanId(ethPacket.getVlanID())));
-
-            // Send packet out to requester if the host information is available
-            if (host != null) {
-                TrafficTreatment t = DefaultTrafficTreatment.builder()
-                        .setOutput(host.location().port()).build();
-                OutboundPacket o = new DefaultOutboundPacket(
-                        host.location().deviceId(), t, ByteBuffer.wrap(ethPacket.serialize()));
-                if (log.isTraceEnabled()) {
-                    log.trace("Relaying packet to dhcp client {}", ethPacket);
-                }
-                packetService.emit(o);
-            }
-        }
-    }
-
-    /**
-     * Listener for network config events.
-     */
-    private class InternalConfigListener implements NetworkConfigListener {
-
-        @Override
-        public void event(NetworkConfigEvent event) {
-
-            if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
-                    event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
-                    event.configClass().equals(DhcpRelayConfig.class)) {
-                updateConfig();
-                log.info("Reconfigured");
-            }
-        }
-    }
-
-    /**
-     * Internal listener for host events.
-     */
-    private class InternalHostListener implements HostListener {
-        @Override
-        public void event(HostEvent event) {
-            switch (event.type()) {
-            case HOST_ADDED:
-            case HOST_UPDATED:
-                hostUpdated(event.subject());
-                break;
-            case HOST_REMOVED:
-                hostRemoved(event.subject());
-                break;
-            case HOST_MOVED:
-                // XXX todo -- moving dhcp server
-                break;
-            default:
-                break;
-            }
-        }
-    }
-}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
new file mode 100644
index 0000000..7a0aec8
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -0,0 +1,975 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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 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;
+import org.apache.felix.scr.annotations.Modified;
+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.ARP;
+import org.onlab.packet.DHCP;
+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.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;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+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;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.provider.ProviderId;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.
+ */
+@Component(immediate = true)
+@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 String HOST_LOCATION_PROVIDER =
+            "org.onosproject.provider.host.impl.HostLocationProvider";
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final InternalConfigListener cfgListener = new InternalConfigListener();
+
+    private final Set<ConfigFactory> factories = ImmutableSet.of(
+            new ConfigFactory<ApplicationId, DhcpRelayConfig>(APP_SUBJECT_FACTORY,
+                    DhcpRelayConfig.class,
+                    "dhcprelay") {
+                @Override
+                public DhcpRelayConfig createConfig() {
+                    return new DhcpRelayConfig();
+                }
+            }
+    );
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    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)
+    protected DhcpRelayStore dhcpRelayStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService compCfgService;
+
+    @Property(name = "arpEnabled", boolValue = true,
+            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
+    protected void activate(ComponentContext context) {
+        //start the dhcp relay agent
+        appId = coreService.registerApplication(DHCP_RELAY_APP);
+
+        cfgService.addListener(cfgListener);
+        factories.forEach(cfgService::registerConfigFactory);
+        //update the dhcp server configuration.
+        updateConfig();
+        //add the packet services.
+        packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
+        hostService.addListener(hostListener);
+        requestDhcpPackets();
+        modified(context);
+
+        // disable dhcp from host location provider
+        compCfgService.preSetProperty(HOST_LOCATION_PROVIDER,
+                                      "useDhcp", Boolean.FALSE.toString());
+        compCfgService.registerProperties(getClass());
+        log.info("DHCP-RELAY Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        cfgService.removeListener(cfgListener);
+        factories.forEach(cfgService::unregisterConfigFactory);
+        packetService.removeProcessor(dhcpRelayPacketProcessor);
+        hostService.removeListener(hostListener);
+        cancelDhcpPackets();
+        cancelArpPackets();
+        if (dhcpGatewayIp != null) {
+            hostService.stopMonitoringIp(dhcpGatewayIp);
+        } else {
+            hostService.stopMonitoringIp(dhcpServerIp);
+        }
+        compCfgService.unregisterProperties(getClass(), true);
+        log.info("DHCP-RELAY Stopped");
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        Boolean flag;
+
+        flag = Tools.isPropertyEnabled(properties, "arpEnabled");
+        if (flag != null) {
+            arpEnabled = flag;
+            log.info("Address resolution protocol is {}",
+                     arpEnabled ? "enabled" : "disabled");
+        }
+
+        if (arpEnabled) {
+            requestArpPackets();
+        } else {
+            cancelArpPackets();
+        }
+    }
+
+    /**
+     * 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;
+        }
+
+        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);
+
+        IpAddress ipToProbe = dhcpGatewayIp != null ? dhcpGatewayIp : dhcpServerIp;
+        String hostToProbe = dhcpGatewayIp != null ? "gateway" : "DHCP server";
+
+        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);
+            }
+            hostService.startMonitoringIp(ipToProbe);
+        } else {
+            // Probe target is known; There should be only 1 host with this ip
+            hostUpdated(hosts.iterator().next());
+        }
+    }
+
+    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;
+        }
+    }
+
+    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);
+        }
+    }
+
+    /**
+     * Request DHCP packet in via PacketService.
+     */
+    private void requestDhcpPackets() {
+        TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
+        packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
+
+        TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
+        packetService.requestPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
+    }
+
+    /**
+     * Cancel requested DHCP packets in via packet service.
+     */
+    private void cancelDhcpPackets() {
+        TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
+        packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
+
+        TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
+        packetService.cancelPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
+    }
+
+    /**
+     * Request ARP packet in via PacketService.
+     */
+    private void requestArpPackets() {
+        TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_ARP);
+        packetService.requestPackets(selectorArpServer.build(), PacketPriority.CONTROL, appId);
+    }
+
+    /**
+     * Cancel requested ARP packets in via packet service.
+     */
+    private void cancelArpPackets() {
+        TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_ARP);
+        packetService.cancelPackets(selectorArpServer.build(), PacketPriority.CONTROL, appId);
+    }
+
+    @Override
+    public Optional<DhcpRecord> getDhcpRecord(HostId hostId) {
+        return dhcpRelayStore.getDhcpRecord(hostId);
+    }
+
+    @Override
+    public Collection<DhcpRecord> getDhcpRecords() {
+        return dhcpRelayStore.getDhcpRecords();
+    }
+
+    /**
+     * 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.");
+        }
+    }
+
+    /**
+     * Gets DHCP data from a packet.
+     *
+     * @param packet the packet
+     * @return the DHCP data; empty if it is not a DHCP packet
+     */
+    private Optional<DHCP> findDhcp(Ethernet packet) {
+        return Stream.of(packet)
+                .filter(Objects::nonNull)
+                .map(Ethernet::getPayload)
+                .filter(p -> p instanceof IPv4)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof UDP)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof DHCP)
+                .map(p -> (DHCP) p)
+                .findFirst();
+    }
+
+    /**
+     * Gets DHCPv6 data from a packet.
+     *
+     * @param packet the packet
+     * @return the DHCPv6 data; empty if it is not a DHCPv6 packet
+     */
+    private Optional<DHCP6> findDhcp6(Ethernet packet) {
+        return Stream.of(packet)
+                .filter(Objects::nonNull)
+                .map(Ethernet::getPayload)
+                .filter(p -> p instanceof IPv6)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof UDP)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof DHCP6)
+                .map(p -> (DHCP6) p)
+                .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) {
+                return;
+            }
+
+            findDhcp(packet).ifPresent(dhcpPayload -> {
+                processDhcpPacket(context, dhcpPayload);
+            });
+
+            findDhcp6(packet).ifPresent(dhcp6Payload -> {
+                // TODO: handle DHCPv6 packet
+                log.warn("DHCPv6 unsupported.");
+            });
+
+            if (packet.getEtherType() == Ethernet.TYPE_ARP && arpEnabled) {
+                ARP arpPacket = (ARP) packet.getPayload();
+                VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+                Set<Interface> interfaces = interfaceService.
+                        getInterfacesByPort(context.inPacket().receivedFrom());
+                //ignore the packets if dhcp server interface is not configured on onos.
+                if (interfaces.isEmpty()) {
+                    log.warn("server virtual interface not configured");
+                    return;
+                }
+                if ((arpPacket.getOpCode() != ARP.OP_REQUEST)) {
+                    // handle request only
+                    return;
+                }
+                MacAddress interfaceMac = interfaces.stream()
+                        .filter(iface -> iface.vlan().equals(vlanId))
+                        .map(Interface::mac)
+                        .filter(mac -> !mac.equals(MacAddress.NONE))
+                        .findFirst()
+                        .orElse(null);
+
+                if (interfaceMac == null) {
+                    // can't find interface mac address
+                    return;
+                }
+                processArpPacket(context, packet, interfaceMac);
+            }
+        }
+
+        /**
+         * Processes the ARP Payload and initiates a reply to the client.
+         *
+         * @param context the packet context
+         * @param packet the ethernet payload
+         * @param replyMac mac address to be replied
+         */
+        private void processArpPacket(PacketContext context, Ethernet packet, MacAddress replyMac) {
+            ARP arpPacket = (ARP) packet.getPayload();
+            ARP arpReply = (ARP) arpPacket.clone();
+            arpReply.setOpCode(ARP.OP_REPLY);
+
+            arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
+            arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress());
+            arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress());
+            arpReply.setSenderHardwareAddress(replyMac.toBytes());
+
+            // Ethernet Frame.
+            Ethernet ethReply = new Ethernet();
+            ethReply.setSourceMACAddress(replyMac.toBytes());
+            ethReply.setDestinationMACAddress(packet.getSourceMAC());
+            ethReply.setEtherType(Ethernet.TYPE_ARP);
+            ethReply.setVlanID(packet.getVlanID());
+            ethReply.setPayload(arpReply);
+
+            ConnectPoint targetPort = context.inPacket().receivedFrom();
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(targetPort.port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    targetPort.deviceId(), t, ByteBuffer.wrap(ethReply.serialize()));
+            if (log.isTraceEnabled()) {
+                log.trace("Relaying ARP packet {} to {}", packet, targetPort);
+            }
+            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);
+            outInterface.ifPresent(outIface -> {
+                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.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;
+        }
+    }
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
+                    event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
+                    event.configClass().equals(DhcpRelayConfig.class)) {
+                updateConfig();
+                log.info("Reconfigured");
+            }
+        }
+    }
+
+    /**
+     * Internal listener for host events.
+     */
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            switch (event.type()) {
+            case HOST_ADDED:
+            case HOST_UPDATED:
+                hostUpdated(event.subject());
+                break;
+            case HOST_REMOVED:
+                hostRemoved(event.subject());
+                break;
+            case HOST_MOVED:
+                // XXX todo -- moving dhcp server
+                break;
+            default:
+                break;
+            }
+        }
+    }
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayService.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayService.java
new file mode 100644
index 0000000..7ced882
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.net.HostId;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface DhcpRelayService {
+    /**
+     * Gets DHCP record for specific host id (mac + vlan).
+     *
+     * @param hostId the id of host
+     * @return the DHCP record of the host
+     */
+    Optional<DhcpRecord> getDhcpRecord(HostId hostId);
+
+    /**
+     * Gets all DHCP records from store.
+     *
+     * @return all DHCP records from store
+     */
+    Collection<DhcpRecord> getDhcpRecords();
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java
index bca3df3..ca1112e 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java
@@ -45,7 +45,7 @@
      * @param type the type of event
      * @param subject the DHCP record of this event
      */
-    protected DhcpRelayStoreEvent(Type type, DhcpRecord subject) {
+    public DhcpRelayStoreEvent(Type type, DhcpRecord subject) {
         super(type, subject);
     }
 }
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
index b5f2bf8..e2225f1 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
@@ -21,6 +21,7 @@
 import org.apache.felix.scr.annotations.Deactivate;
 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.DHCP;
 import org.onlab.packet.DHCP6;
 import org.onlab.util.KryoNamespace;
@@ -43,7 +44,8 @@
 /**
  * Distributed DHCP relay store.
  */
-@Component
+@Component(immediate = true)
+@Service
 public class DistributedDhcpRelayStore implements DhcpRelayStore {
     private static final KryoNamespace APP_KRYO = KryoNamespace.newBuilder()
             .register(KryoNamespaces.API)
diff --git a/apps/dhcprelay/src/main/resources/dhcp-relay.json b/apps/dhcprelay/src/main/resources/dhcp-relay.json
index 616c4ab..be8b062 100644
--- a/apps/dhcprelay/src/main/resources/dhcp-relay.json
+++ b/apps/dhcprelay/src/main/resources/dhcp-relay.json
@@ -4,7 +4,7 @@
       "dhcprelay" : {
         "dhcpserverConnectPoint": "of:0000000000000002/2",
         "serverip": "172.168.10.2",
-        "servermac": "d2:70:98:90:8c:44"
+        "gatewayip": "192.168.10.254"
       }
     }
   }
diff --git a/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
new file mode 100644
index 0000000..fe2cbff
--- /dev/null
+++ b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
@@ -0,0 +1,648 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ARP;
+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.TestApplicationId;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.dhcprelay.store.DhcpRelayStoreEvent;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
+import org.onosproject.incubator.net.routing.Route;
+import org.onosproject.incubator.net.routing.RouteStoreAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.HostStoreAdapter;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketContextAdapter;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.StoreDelegate;
+import org.osgi.service.component.ComponentContext;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+public class DhcpRelayManagerTest {
+    // Ip address for interfaces
+    private static final InterfaceIpAddress INTERFACE_IP = InterfaceIpAddress.valueOf("10.0.3.254/32");
+    private static final List<InterfaceIpAddress> INTERFACE_IPS = ImmutableList.of(INTERFACE_IP);
+
+    // DHCP client (will send without option 82)
+    private static final Ip4Address IP_FOR_CLIENT = Ip4Address.valueOf("10.0.0.1");
+    private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId CLIENT_VLAN = VlanId.vlanId("100");
+    private static final ConnectPoint CLIENT_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+    private static final MacAddress CLIENT_IFACE_MAC = MacAddress.valueOf("00:00:00:00:11:01");
+    private static final Interface CLIENT_INTERFACE = new Interface("C1",
+                                                                    CLIENT_CP,
+                                                                    INTERFACE_IPS,
+                                                                    CLIENT_IFACE_MAC,
+                                                                    CLIENT_VLAN);
+
+    // DHCP client 2 (will send with option 82, so the vlan should equals to vlan from server)
+    private static final MacAddress CLIENT2_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId CLIENT2_VLAN = VlanId.NONE;
+    private static final ConnectPoint CLIENT2_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
+    private static final MacAddress CLIENT2_IFACE_MAC = MacAddress.valueOf("00:00:00:00:11:01");
+    private static final Interface CLIENT2_INTERFACE = new Interface("C2",
+                                                                     CLIENT2_CP,
+                                                                     INTERFACE_IPS,
+                                                                     CLIENT2_IFACE_MAC,
+                                                                     CLIENT2_VLAN);
+
+    // Outer relay information
+    private static final Ip4Address OUTER_RELAY_IP = Ip4Address.valueOf("10.0.5.253");
+    private static final Set<IpAddress> OUTER_RELAY_IPS = ImmutableSet.of(OUTER_RELAY_IP);
+    private static final MacAddress OUTER_RELAY_MAC = MacAddress.valueOf("00:01:02:03:04:05");
+    private static final VlanId OUTER_RELAY_VLAN = VlanId.NONE;
+    private static final ConnectPoint OUTER_RELAY_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
+    private static final HostLocation OUTER_REPLAY_HL = new HostLocation(OUTER_RELAY_CP, 0);
+    private static final HostId OUTER_RELAY_HOST_ID = HostId.hostId(OUTER_RELAY_MAC, OUTER_RELAY_VLAN);
+    private static final Host OUTER_RELAY_HOST = new DefaultHost(DhcpRelayManager.PROVIDER_ID,
+                                                                 OUTER_RELAY_HOST_ID,
+                                                                 OUTER_RELAY_MAC,
+                                                                 OUTER_RELAY_VLAN,
+                                                                 OUTER_REPLAY_HL,
+                                                                 OUTER_RELAY_IPS);
+
+    // DHCP Server
+    private static final MacAddress SERVER_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId SERVER_VLAN = VlanId.NONE;
+    private static final ConnectPoint SERVER_CONNECT_POINT =
+            ConnectPoint.deviceConnectPoint("of:0000000000000001/5");
+    private static final HostLocation SERVER_LOCATION =
+            new HostLocation(SERVER_CONNECT_POINT, 0);
+    private static final Ip4Address SERVER_IP = Ip4Address.valueOf("10.0.3.253");
+    private static final Set<IpAddress> DHCP_SERVER_IPS = ImmutableSet.of(SERVER_IP);
+    private static final HostId SERVER_HOST_ID = HostId.hostId(SERVER_MAC, SERVER_VLAN);
+    private static final Host SERVER_HOST = new DefaultHost(DhcpRelayManager.PROVIDER_ID,
+                                                            SERVER_HOST_ID,
+                                                            SERVER_MAC,
+                                                            SERVER_VLAN,
+                                                            SERVER_LOCATION,
+                                                            DHCP_SERVER_IPS);
+    private static final MacAddress SERVER_IFACE_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final Interface SERVER_INTERFACE = new Interface("SERVER",
+                                                                    SERVER_CONNECT_POINT,
+                                                                    INTERFACE_IPS,
+                                                                    SERVER_IFACE_MAC,
+                                                                    SERVER_VLAN);
+
+    // Components
+    private static final ApplicationId APP_ID = TestApplicationId.create(DhcpRelayManager.DHCP_RELAY_APP);
+    private static final DhcpRelayConfig CONFIG = new MockDhcpRelayConfig();
+    private static final Set<Interface> INTERFACES = ImmutableSet.of(
+            CLIENT_INTERFACE,
+            CLIENT2_INTERFACE,
+            SERVER_INTERFACE
+    );
+
+    private DhcpRelayManager manager;
+    private MockPacketService packetService;
+    private MockHostStore mockHostStore;
+    private MockRouteStore mockRouteStore;
+    private MockDhcpRelayStore mockDhcpRelayStore;
+
+    @Before
+    public void setup() {
+        manager = new DhcpRelayManager();
+        manager.cfgService = createNiceMock(NetworkConfigRegistry.class);
+
+        expect(manager.cfgService.getConfig(anyObject(), anyObject()))
+                .andReturn(CONFIG)
+                .anyTimes();
+
+        manager.coreService = createNiceMock(CoreService.class);
+        expect(manager.coreService.registerApplication(anyString()))
+                .andReturn(APP_ID).anyTimes();
+
+        manager.hostService = createNiceMock(HostService.class);
+        expect(manager.hostService.getHostsByIp(anyObject())).andReturn(ImmutableSet.of(SERVER_HOST));
+        expect(manager.hostService.getHost(OUTER_RELAY_HOST_ID)).andReturn(OUTER_RELAY_HOST);
+
+        packetService = new MockPacketService();
+        manager.packetService = packetService;
+        manager.compCfgService = createNiceMock(ComponentConfigService.class);
+
+        mockHostStore = new MockHostStore();
+        mockRouteStore = new MockRouteStore();
+        mockDhcpRelayStore = new MockDhcpRelayStore();
+
+        manager.hostStore = mockHostStore;
+        manager.routeStore = mockRouteStore;
+        manager.dhcpRelayStore = mockDhcpRelayStore;
+
+        manager.interfaceService = new MockInterfaceService();
+
+        // properties
+        Dictionary<String, Object> dictionary = createNiceMock(Dictionary.class);
+        expect(dictionary.get("arpEnabled")).andReturn(true).anyTimes();
+        ComponentContext context = createNiceMock(ComponentContext.class);
+        expect(context.getProperties()).andReturn(dictionary).anyTimes();
+
+        EasyMock.replay(manager.cfgService, manager.coreService, manager.hostService,
+                        manager.compCfgService, dictionary, context);
+        manager.activate(context);
+    }
+
+    @After
+    public void tearDown() {
+        manager.deactivate();
+    }
+
+    /**
+     * Relay a DHCP packet without option 82.
+     * Should add new host to host store after dhcp ack.
+     */
+    @Test
+    public void relayDhcpWithoutAgentInfo() {
+        // send request
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT_MAC,
+                                                                     CLIENT_VLAN,
+                                                                     CLIENT_CP,
+                                                                     INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                     false));
+
+        Set<Host> hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(0, hosts.size());
+        assertEquals(0, mockRouteStore.routes.size());
+
+        // send ack
+        packetService.processPacket(new TestDhcpAckPacketContext(CLIENT_CP, CLIENT_MAC,
+                                                                 CLIENT_VLAN, INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                 false));
+        hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(1, hosts.size());
+        assertEquals(0, mockRouteStore.routes.size());
+
+        Host host = hosts.iterator().next();
+        assertEquals(CLIENT_MAC, host.mac());
+        assertEquals(CLIENT_VLAN, host.vlan());
+        assertEquals(CLIENT_CP.deviceId(), host.location().elementId());
+        assertEquals(CLIENT_CP.port(), host.location().port());
+        assertEquals(1, host.ipAddresses().size());
+        assertEquals(IP_FOR_CLIENT, host.ipAddresses().iterator().next());
+        assertEquals(HostId.hostId(CLIENT_MAC, CLIENT_VLAN), host.id());
+    }
+
+    /**
+     * Relay a DHCP packet with option 82 (Indirectly connected host).
+     */
+    @Test
+    public void relayDhcpWithAgentInfo() {
+        // Assume outer dhcp relay agent exists in store already
+        // send request
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT2_MAC,
+                                                                     CLIENT2_VLAN,
+                                                                     CLIENT2_CP,
+                                                                     INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                     true));
+
+        Set<Host> hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(0, hosts.size());
+        assertEquals(0, mockRouteStore.routes.size());
+
+        // send ack
+        packetService.processPacket(new TestDhcpAckPacketContext(CLIENT2_CP,
+                                                                 CLIENT2_MAC,
+                                                                 CLIENT2_VLAN,
+                                                                 INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                 true));
+
+        hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(0, hosts.size());
+        assertEquals(1, mockRouteStore.routes.size());
+
+        Route route = mockRouteStore.routes.get(0);
+        assertEquals(OUTER_RELAY_IP, route.nextHop());
+        assertEquals(IP_FOR_CLIENT.toIpPrefix(), route.prefix());
+        assertEquals(Route.Source.STATIC, route.source());
+    }
+
+    @Test
+    public void testArpRequest() throws Exception {
+        packetService.processPacket(new TestArpRequestPacketContext(CLIENT_INTERFACE));
+        OutboundPacket outboundPacket = packetService.emitedPacket;
+        byte[] outPacketData = outboundPacket.data().array();
+        Ethernet eth = Ethernet.deserializer().deserialize(outPacketData, 0, outPacketData.length);
+
+        assertEquals(eth.getEtherType(), Ethernet.TYPE_ARP);
+        ARP arp = (ARP) eth.getPayload();
+        assertArrayEquals(arp.getSenderHardwareAddress(), CLIENT_INTERFACE.mac().toBytes());
+    }
+
+    private static class MockDhcpRelayConfig extends DhcpRelayConfig {
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        public ConnectPoint getDhcpServerConnectPoint() {
+            return SERVER_CONNECT_POINT;
+        }
+
+        public Ip4Address getDhcpServerIp() {
+            return SERVER_IP;
+        }
+
+        public Ip4Address getDhcpGatewayIp() {
+            return null;
+        }
+    }
+
+    private class MockHostStore extends HostStoreAdapter {
+
+        private final Map<HostId, HostDescription> hosts = Maps.newHashMap();
+
+        @Override
+        public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
+                                            HostDescription hostDescription,
+                                            boolean replaceIps) {
+            hosts.put(hostId, hostDescription);
+
+            // not necessary to return host event in this test.
+            return null;
+        }
+
+        public HostDescription hostDesc(HostId hostId) {
+            return hosts.get(hostId);
+        }
+
+        @Override
+        public Iterable<Host> getHosts() {
+            return hosts.values().stream()
+                    .map(hd -> new DefaultHost(DhcpRelayManager.PROVIDER_ID,
+                                               HostId.hostId(hd.hwAddress(), hd.vlan()),
+                                               hd.hwAddress(),
+                                               hd.vlan(), hd.locations(),
+                                               hd.ipAddress(), false))
+                    .collect(Collectors.toList());
+        }
+    }
+
+    private class MockRouteStore extends RouteStoreAdapter {
+        private List<Route> routes = Lists.newArrayList();
+
+        @Override
+        public void updateRoute(Route route) {
+            routes.add(route);
+        }
+    }
+
+    private class MockInterfaceService extends InterfaceServiceAdapter {
+
+        @Override
+        public Set<Interface> getInterfaces() {
+            return INTERFACES;
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByIp(IpAddress ip) {
+            return INTERFACES.stream()
+                    .filter(iface -> {
+                        return iface.ipAddressesList().stream()
+                                .anyMatch(ifaceIp -> ifaceIp.ipAddress().equals(ip));
+                    })
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+            return INTERFACES.stream()
+                    .filter(iface -> iface.connectPoint().equals(port))
+                    .collect(Collectors.toSet());
+        }
+    }
+
+    private class MockDhcpRelayStore implements DhcpRelayStore {
+        StoreDelegate<DhcpRelayStoreEvent> delegate;
+        private Map<HostId, DhcpRecord> records = Maps.newHashMap();
+
+        @Override
+        public void updateDhcpRecord(HostId hostId, DhcpRecord dhcpRecord) {
+            records.put(hostId, dhcpRecord);
+            DhcpRelayStoreEvent event = new DhcpRelayStoreEvent(DhcpRelayStoreEvent.Type.UPDATED,
+                                                                dhcpRecord);
+            if (delegate != null) {
+                delegate.notify(event);
+            }
+        }
+
+        @Override
+        public Optional<DhcpRecord> getDhcpRecord(HostId hostId) {
+            return Optional.ofNullable(records.get(hostId));
+        }
+
+        @Override
+        public Collection<DhcpRecord> getDhcpRecords() {
+            return records.values();
+        }
+
+        @Override
+        public Optional<DhcpRecord> removeDhcpRecord(HostId hostId) {
+            DhcpRecord dhcpRecord = records.remove(hostId);
+            if (dhcpRecord != null) {
+                DhcpRelayStoreEvent event = new DhcpRelayStoreEvent(DhcpRelayStoreEvent.Type.REMOVED,
+                                                                    dhcpRecord);
+                if (delegate != null) {
+                    delegate.notify(event);
+                }
+            }
+            return Optional.ofNullable(dhcpRecord);
+        }
+
+        @Override
+        public void setDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public void unsetDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
+            this.delegate = null;
+        }
+
+        @Override
+        public boolean hasDelegate() {
+            return this.delegate != null;
+        }
+    }
+
+    private class MockPacketService extends PacketServiceAdapter {
+        Set<PacketProcessor> packetProcessors = Sets.newHashSet();
+        OutboundPacket emitedPacket;
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessors.add(processor);
+        }
+
+        public void processPacket(PacketContext packetContext) {
+            packetProcessors.forEach(p -> p.process(packetContext));
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            this.emitedPacket = packet;
+        }
+    }
+
+
+
+    /**
+     * Generates DHCP REQUEST packet.
+     */
+    private class TestDhcpRequestPacketContext extends PacketContextAdapter {
+
+
+        private InboundPacket inPacket;
+
+        public TestDhcpRequestPacketContext(MacAddress clientMac, VlanId vlanId,
+                                            ConnectPoint clientCp,
+                                            Ip4Address clientGwAddr,
+                                            boolean withNonOnosRelayInfo) {
+            super(0, null, null, false);
+            byte[] dhcpMsgType = new byte[1];
+            dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPREQUEST.getValue();
+
+            DhcpOption dhcpOption = new DhcpOption();
+            dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+            dhcpOption.setData(dhcpMsgType);
+            dhcpOption.setLength((byte) 1);
+            DhcpOption endOption = new DhcpOption();
+            endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+
+            DHCP dhcp = new DHCP();
+            dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
+            dhcp.setHardwareAddressLength((byte) 6);
+            dhcp.setClientHardwareAddress(clientMac.toBytes());
+            if (withNonOnosRelayInfo) {
+                DhcpRelayAgentOption relayOption = new DhcpRelayAgentOption();
+                DhcpOption circuitIdOption = new DhcpOption();
+                CircuitId circuitId = new CircuitId("Custom option", VlanId.NONE);
+                byte[] cid = circuitId.serialize();
+                circuitIdOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdOption.setLength((byte) cid.length);
+                circuitIdOption.setData(cid);
+                relayOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayOption.addSubOption(circuitIdOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayOption, endOption));
+                dhcp.setGatewayIPAddress(OUTER_RELAY_IP.getIp4Address().toInt());
+            } else {
+                dhcp.setOptions(ImmutableList.of(dhcpOption, endOption));
+            }
+
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp);
+            udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
+            udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
+
+            IPv4 ipv4 = new IPv4();
+            ipv4.setPayload(udp);
+            ipv4.setDestinationAddress(SERVER_IP.toInt());
+            ipv4.setSourceAddress(clientGwAddr.toInt());
+
+            Ethernet eth = new Ethernet();
+            if (withNonOnosRelayInfo) {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(vlanId.toShort())
+                        .setSourceMACAddress(OUTER_RELAY_MAC)
+                        .setDestinationMACAddress(MacAddress.BROADCAST)
+                        .setPayload(ipv4);
+            } else {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(vlanId.toShort())
+                        .setSourceMACAddress(clientMac)
+                        .setDestinationMACAddress(MacAddress.BROADCAST)
+                        .setPayload(ipv4);
+            }
+
+            this.inPacket = new DefaultInboundPacket(clientCp, eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
+    /**
+     * Generates DHCP ACK packet.
+     */
+    private class TestDhcpAckPacketContext extends PacketContextAdapter {
+        private InboundPacket inPacket;
+
+        public TestDhcpAckPacketContext(ConnectPoint clientCp, MacAddress clientMac,
+                                        VlanId clientVlan, Ip4Address clientGwAddr,
+                                        boolean withNonOnosRelayInfo) {
+            super(0, null, null, false);
+
+            byte[] dhcpMsgType = new byte[1];
+            dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPACK.getValue();
+
+            DhcpOption dhcpOption = new DhcpOption();
+            dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+            dhcpOption.setData(dhcpMsgType);
+            dhcpOption.setLength((byte) 1);
+
+            DhcpOption endOption = new DhcpOption();
+            endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+
+            DHCP dhcp = new DHCP();
+            if (withNonOnosRelayInfo) {
+                DhcpRelayAgentOption relayOption = new DhcpRelayAgentOption();
+                DhcpOption circuitIdOption = new DhcpOption();
+                CircuitId circuitId = new CircuitId("Custom cid", VlanId.NONE);
+                byte[] cid = circuitId.serialize();
+                circuitIdOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdOption.setLength((byte) cid.length);
+                circuitIdOption.setData(cid);
+                relayOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayOption.addSubOption(circuitIdOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayOption, endOption));
+                dhcp.setGatewayIPAddress(OUTER_RELAY_IP.getIp4Address().toInt());
+            } else {
+                CircuitId cid = new CircuitId(clientCp.toString(), clientVlan);
+                byte[] circuitId = cid.serialize();
+                DhcpOption circuitIdSubOption = new DhcpOption();
+                circuitIdSubOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdSubOption.setData(circuitId);
+                circuitIdSubOption.setLength((byte) circuitId.length);
+
+                DhcpRelayAgentOption relayInfoOption = new DhcpRelayAgentOption();
+                relayInfoOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayInfoOption.addSubOption(circuitIdSubOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayInfoOption, endOption));
+                dhcp.setGatewayIPAddress(clientGwAddr.toInt());
+            }
+            dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
+            dhcp.setHardwareAddressLength((byte) 6);
+            dhcp.setClientHardwareAddress(clientMac.toBytes());
+            dhcp.setYourIPAddress(IP_FOR_CLIENT.toInt());
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp);
+            udp.setSourcePort(UDP.DHCP_SERVER_PORT);
+            udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
+            IPv4 ipv4 = new IPv4();
+            ipv4.setPayload(udp);
+            ipv4.setDestinationAddress(IP_FOR_CLIENT.toString());
+            ipv4.setSourceAddress(SERVER_IP.toString());
+            Ethernet eth = new Ethernet();
+            if (withNonOnosRelayInfo) {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(SERVER_VLAN.toShort())
+                        .setSourceMACAddress(SERVER_MAC)
+                        .setDestinationMACAddress(OUTER_RELAY_MAC)
+                        .setPayload(ipv4);
+            } else {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(SERVER_VLAN.toShort())
+                        .setSourceMACAddress(SERVER_MAC)
+                        .setDestinationMACAddress(CLIENT_MAC)
+                        .setPayload(ipv4);
+            }
+
+            this.inPacket = new DefaultInboundPacket(SERVER_CONNECT_POINT, eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
+    private class TestArpRequestPacketContext extends PacketContextAdapter {
+        private InboundPacket inPacket;
+
+        public TestArpRequestPacketContext(Interface fromInterface) {
+            super(0, null, null, false);
+            ARP arp = new ARP();
+            arp.setOpCode(ARP.OP_REQUEST);
+
+            IpAddress targetIp = fromInterface.ipAddressesList().get(0).ipAddress();
+            arp.setTargetProtocolAddress(targetIp.toOctets());
+            arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
+            arp.setSenderHardwareAddress(MacAddress.NONE.toBytes());
+            arp.setSenderProtocolAddress(Ip4Address.valueOf(0).toOctets());
+            arp.setHardwareAddressLength((byte) MacAddress.MAC_ADDRESS_LENGTH);
+            Ethernet eth = new Ethernet();
+            eth.setEtherType(Ethernet.TYPE_ARP);
+            eth.setSourceMACAddress(MacAddress.NONE);
+            eth.setDestinationMACAddress(MacAddress.BROADCAST);
+            eth.setVlanID(fromInterface.vlan().toShort());
+            eth.setPayload(arp);
+
+            this.inPacket = new DefaultInboundPacket(fromInterface.connectPoint(), eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/host/HostStoreAdapter.java b/core/api/src/test/java/org/onosproject/net/host/HostStoreAdapter.java
new file mode 100644
index 0000000..796e6d6
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/host/HostStoreAdapter.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.net.host;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Set;
+
+/**
+ * Test adapter for host store.
+ */
+public class HostStoreAdapter implements HostStore {
+    @Override
+    public void setDelegate(HostStoreDelegate delegate) {
+
+    }
+
+    @Override
+    public void unsetDelegate(HostStoreDelegate delegate) {
+
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return false;
+    }
+
+    @Override
+    public HostEvent createOrUpdateHost(ProviderId providerId,
+                                        HostId hostId,
+                                        HostDescription hostDescription,
+                                        boolean replaceIps) {
+        return null;
+    }
+
+    @Override
+    public HostEvent removeHost(HostId hostId) {
+        return null;
+    }
+
+    @Override
+    public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
+        return null;
+    }
+
+    @Override
+    public void removeLocation(HostId hostId, HostLocation location) {
+
+    }
+
+    @Override
+    public int getHostCount() {
+        return 0;
+    }
+
+    @Override
+    public Iterable<Host> getHosts() {
+        return null;
+    }
+
+    @Override
+    public Host getHost(HostId hostId) {
+        return null;
+    }
+
+    @Override
+    public Set<Host> getHosts(VlanId vlanId) {
+        return null;
+    }
+
+    @Override
+    public Set<Host> getHosts(MacAddress mac) {
+        return null;
+    }
+
+    @Override
+    public Set<Host> getHosts(IpAddress ip) {
+        return null;
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+        return null;
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(DeviceId deviceId) {
+        return null;
+    }
+}
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/routing/RouteStoreAdapter.java b/incubator/api/src/test/java/org/onosproject/incubator/net/routing/RouteStoreAdapter.java
new file mode 100644
index 0000000..c5250d7
--- /dev/null
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/routing/RouteStoreAdapter.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.incubator.net.routing;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Adapter class for the route store.
+ */
+public class RouteStoreAdapter implements RouteStore {
+    @Override
+    public void updateRoute(Route route) {
+
+    }
+
+    @Override
+    public void removeRoute(Route route) {
+
+    }
+
+    @Override
+    public Set<RouteTableId> getRouteTables() {
+        return null;
+    }
+
+    @Override
+    public Collection<RouteSet> getRoutes(RouteTableId table) {
+        return null;
+    }
+
+    @Override
+    public Collection<Route> getRoutesForNextHop(IpAddress ip) {
+        return null;
+    }
+
+    @Override
+    public RouteSet getRoutes(IpPrefix prefix) {
+        return null;
+    }
+
+    @Override
+    public void setDelegate(RouteStoreDelegate delegate) {
+
+    }
+
+    @Override
+    public void unsetDelegate(RouteStoreDelegate delegate) {
+
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return false;
+    }
+}
diff --git a/providers/host/BUCK b/providers/host/BUCK
index f5cf0c3..2cfed29 100644
--- a/providers/host/BUCK
+++ b/providers/host/BUCK
@@ -1,5 +1,6 @@
 COMPILE_DEPS = [
     '//lib:CORE_DEPS',
+    '//incubator/api:onos-incubator-api',
 ]
 
 TEST_DEPS = [
diff --git a/providers/host/pom.xml b/providers/host/pom.xml
index 7ead81d..f6016ca 100644
--- a/providers/host/pom.xml
+++ b/providers/host/pom.xml
@@ -64,6 +64,9 @@
             <artifactId>easymock</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-incubator-api</artifactId>
+        </dependency>
     </dependencies>
-
 </project>
diff --git a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
index 996bd43..e197a0d 100644
--- a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
+++ b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
@@ -43,6 +43,7 @@
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
@@ -77,7 +78,10 @@
 
 import java.nio.ByteBuffer;
 import java.util.Dictionary;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.ExecutorService;
+import java.util.stream.Stream;
 
 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
 import static org.onlab.util.Tools.groupedThreads;
@@ -89,7 +93,6 @@
  */
 @Component(immediate = true)
 public class HostLocationProvider extends AbstractProvider implements HostProvider {
-
     private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -113,6 +116,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ComponentConfigService cfgService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
     private HostProviderService providerService;
 
     private final InternalHostProvider processor = new InternalHostProvider();
@@ -124,18 +130,18 @@
             label = "Enable host removal on port/device down events")
     private boolean hostRemovalEnabled = true;
 
-    @Property(name = "useArp", boolValue = true,
-            label = "Enable using ARP for neighbor discovery by the " +
+    @Property(name = "requestArp", boolValue = true,
+            label = "Request ARP packets for neighbor discovery by the " +
                     "Host Location Provider; default is true")
-    private boolean useArp = true;
+    private boolean requestArp = true;
 
-    @Property(name = "useIpv6ND", boolValue = false,
-            label = "Enable using IPv6 Neighbor Discovery by the " +
+    @Property(name = "requestIpv6ND", boolValue = false,
+            label = "Requests IPv6 Neighbor Discovery by the " +
                     "Host Location Provider; default is false")
-    private boolean useIpv6ND = false;
+    private boolean requestIpv6ND = false;
 
     @Property(name = "useDhcp", boolValue = false,
-            label = "Enable using DHCP for neighbor discovery by the " +
+            label = "Use DHCP for neighbor discovery by the " +
                     "Host Location Provider; default is false")
     private boolean useDhcp = false;
 
@@ -202,7 +208,7 @@
         TrafficSelector arpSelector = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_ARP)
                 .build();
-        if (useArp) {
+        if (requestArp) {
             packetService.requestPackets(arpSelector, PacketPriority.CONTROL, appId);
         } else {
             packetService.cancelPackets(arpSelector, PacketPriority.CONTROL, appId);
@@ -219,7 +225,7 @@
                 .matchIPProtocol(IPv6.PROTOCOL_ICMP6)
                 .matchIcmpv6Type(ICMP6.NEIGHBOR_ADVERTISEMENT)
                 .build();
-        if (useIpv6ND) {
+        if (requestIpv6ND) {
             packetService.requestPackets(ipv6NsSelector, PacketPriority.CONTROL, appId);
             packetService.requestPackets(ipv6NaSelector, PacketPriority.CONTROL, appId);
         } else {
@@ -238,13 +244,6 @@
                 .matchIPProtocol(IPv4.PROTOCOL_UDP)
                 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
                 .build();
-        if (useDhcp) {
-            packetService.requestPackets(dhcpServerSelector, PacketPriority.CONTROL, appId);
-            packetService.requestPackets(dhcpClientSelector, PacketPriority.CONTROL, appId);
-        } else {
-            packetService.cancelPackets(dhcpServerSelector, PacketPriority.CONTROL, appId);
-            packetService.cancelPackets(dhcpClientSelector, PacketPriority.CONTROL, appId);
-        }
     }
 
     /**
@@ -278,51 +277,51 @@
         flag = Tools.isPropertyEnabled(properties, "hostRemovalEnabled");
         if (flag == null) {
             log.info("Host removal on port/device down events is not configured, " +
-                             "using current value of {}", hostRemovalEnabled);
+                     "using current value of {}", hostRemovalEnabled);
         } else {
             hostRemovalEnabled = flag;
             log.info("Configured. Host removal on port/device down events is {}",
                      hostRemovalEnabled ? "enabled" : "disabled");
         }
 
-        flag = Tools.isPropertyEnabled(properties, "useArp");
+        flag = Tools.isPropertyEnabled(properties, "requestArp");
         if (flag == null) {
             log.info("Using ARP is not configured, " +
-                    "using current value of {}", useArp);
+                     "using current value of {}", requestArp);
         } else {
-            useArp = flag;
+            requestArp = flag;
             log.info("Configured. Using ARP is {}",
-                    useArp ? "enabled" : "disabled");
+                     requestArp ? "enabled" : "disabled");
         }
 
-        flag = Tools.isPropertyEnabled(properties, "useIpv6ND");
+        flag = Tools.isPropertyEnabled(properties, "requestIpv6ND");
         if (flag == null) {
             log.info("Using IPv6 Neighbor Discovery is not configured, " +
-                             "using current value of {}", useIpv6ND);
+                             "using current value of {}", requestIpv6ND);
         } else {
-            useIpv6ND = flag;
+            requestIpv6ND = flag;
             log.info("Configured. Using IPv6 Neighbor Discovery is {}",
-                     useIpv6ND ? "enabled" : "disabled");
+                     requestIpv6ND ? "enabled" : "disabled");
         }
 
         flag = Tools.isPropertyEnabled(properties, "useDhcp");
         if (flag == null) {
             log.info("Using DHCP is not configured, " +
-                    "using current value of {}", useDhcp);
+                     "using current value of {}", useDhcp);
         } else {
             useDhcp = flag;
             log.info("Configured. Using DHCP is {}",
-                    useDhcp ? "enabled" : "disabled");
+                     useDhcp ? "enabled" : "disabled");
         }
 
         flag = Tools.isPropertyEnabled(properties, "requestInterceptsEnabled");
         if (flag == null) {
             log.info("Request intercepts is not configured, " +
-                    "using current value of {}", requestInterceptsEnabled);
+                     "using current value of {}", requestInterceptsEnabled);
         } else {
             requestInterceptsEnabled = flag;
             log.info("Configured. Request intercepts is {}",
-                    requestInterceptsEnabled ? "enabled" : "disabled");
+                     requestInterceptsEnabled ? "enabled" : "disabled");
         }
     }
 
@@ -475,30 +474,12 @@
                 createOrUpdateHost(hid, srcMac, vlan, hloc, ip);
 
             // IPv4: update location only
-            // DHCP ACK: additionally update IP of DHCP client
             } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
-                IPacket pkt = eth.getPayload();
-                if (pkt != null && pkt instanceof IPv4) {
-                    pkt = pkt.getPayload();
-                    if (pkt != null && pkt instanceof UDP) {
-                        pkt = pkt.getPayload();
-                        if (pkt != null && pkt instanceof DHCP) {
-                            DHCP dhcp = (DHCP) pkt;
-                            if (dhcp.getOptions().stream()
-                                    .anyMatch(dhcpOption -> dhcpOption.getCode() ==
-                                            DHCP.DHCPOptionCode.OptionCode_MessageType.getValue() &&
-                                            dhcpOption.getLength() == 1 &&
-                                            dhcpOption.getData()[0] == DHCP.MsgType.DHCPACK.getValue())) {
-                                MacAddress hostMac = MacAddress.valueOf(dhcp.getClientHardwareAddress());
-                                VlanId hostVlan = VlanId.vlanId(eth.getVlanID());
-                                HostId hostId = HostId.hostId(hostMac, hostVlan);
-                                updateHostIp(hostId, IpAddress.valueOf(dhcp.getYourIPAddress()));
-                            }
-                        }
-                    }
+                // DHCP ACK: additionally update IP of DHCP client
+                Optional<DHCP> dhcp = findDhcp(eth);
+                if (useDhcp || !dhcp.isPresent()) {
+                    createOrUpdateHost(hid, srcMac, vlan, hloc, null);
                 }
-                createOrUpdateHost(hid, srcMac, vlan, hloc, null);
-
             //
             // NeighborAdvertisement and NeighborSolicitation: possible
             // new hosts, update both location and IP.
@@ -546,6 +527,21 @@
                 createOrUpdateHost(hid, srcMac, vlan, hloc, null);
             }
         }
+
+        private Optional<DHCP> findDhcp(Ethernet eth) {
+            IPacket pkt = eth.getPayload();
+            return Stream.of(pkt)
+                    .filter(Objects::nonNull)
+                    .filter(p -> p instanceof IPv4)
+                    .map(IPacket::getPayload)
+                    .filter(Objects::nonNull)
+                    .filter(p -> p instanceof UDP)
+                    .map(IPacket::getPayload)
+                    .filter(Objects::nonNull)
+                    .filter(p -> p instanceof DHCP)
+                    .map(p -> (DHCP) p)
+                    .findFirst();
+        }
     }
 
     // Auxiliary listener to device events.
diff --git a/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java b/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
index b28ec17..080e0e4 100644
--- a/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
+++ b/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
@@ -15,16 +15,19 @@
  */
 package org.onosproject.provider.host.impl;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.MoreExecutors;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.junit.TestUtils;
 import org.onlab.osgi.ComponentContextAdapter;
 import org.onlab.packet.ARP;
 import org.onlab.packet.ChassisId;
 import org.onlab.packet.DHCP;
+import org.onlab.packet.dhcp.CircuitId;
 import org.onlab.packet.dhcp.DhcpOption;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.ICMP6;
@@ -35,6 +38,7 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.UDP;
 import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.DhcpRelayAgentOption;
 import org.onlab.packet.ndp.NeighborAdvertisement;
 import org.onlab.packet.ndp.NeighborSolicitation;
 import org.onlab.packet.ndp.RouterAdvertisement;
@@ -43,6 +47,9 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultDevice;
 import org.onosproject.net.DefaultHost;
@@ -60,6 +67,7 @@
 import org.onosproject.net.host.HostProviderRegistry;
 import org.onosproject.net.host.HostProviderService;
 import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.packet.DefaultInboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.PacketContextAdapter;
@@ -85,7 +93,6 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
 import static org.onlab.packet.VlanId.vlanId;
 import static org.onosproject.net.Device.Type.SWITCH;
 import static org.onosproject.net.DeviceId.deviceId;
@@ -109,6 +116,7 @@
     private static final String DEV6 = "of:6";
 
     private static final VlanId VLAN = vlanId();
+    private static final VlanId VLAN_100 = VlanId.vlanId("100");
 
     // IPv4 Host
     private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
@@ -122,6 +130,10 @@
             new DefaultHost(PROVIDER_ID, hostId(MAC), MAC,
                     VLAN, LOCATION,
                     ImmutableSet.of(IP_ADDRESS));
+    private static final DefaultHost HOST_VLAN_100 =
+            new DefaultHost(PROVIDER_ID, hostId(MAC, VLAN_100), MAC,
+                            VLAN_100, LOCATION,
+                            ImmutableSet.of(IP_ADDRESS));
 
     // IPv6 Host
     private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
@@ -149,6 +161,14 @@
                     VLAN, LOCATION3,
                     ImmutableSet.of(IP_ADDRESS3));
 
+    // Gateway information for relay agent
+    private static final InterfaceIpAddress GW_IFACE_ADDR = InterfaceIpAddress.valueOf("10.0.1.1/32");
+    private static final Interface GW_IFACE = new Interface("gateway",
+                                                                    LOCATION,
+                                                                    ImmutableList.of(GW_IFACE_ADDR),
+                                                                    null,
+                                                                    VLAN_100);
+
     private static final ComponentContextAdapter CTX_FOR_REMOVE =
             new ComponentContextAdapter() {
                 @Override
@@ -173,6 +193,7 @@
     private final TestDeviceService deviceService = new TestDeviceService();
     private final TestHostService hostService = new TestHostService();
     private final TestPacketService packetService = new TestPacketService();
+    private final TestInterfaceService interfaceService = new TestInterfaceService();
 
     private PacketProcessor testProcessor;
     private CoreService coreService;
@@ -183,7 +204,6 @@
 
     @Before
     public void setUp() {
-
         coreService = createMock(CoreService.class);
         expect(coreService.registerApplication(appId.name()))
                 .andReturn(appId).anyTimes();
@@ -197,6 +217,7 @@
         provider.packetService = packetService;
         provider.deviceService = deviceService;
         provider.hostService = hostService;
+        provider.interfaceService = interfaceService;
 
         provider.activate(CTX_FOR_NO_REMOVE);
 
@@ -335,8 +356,9 @@
      */
     @Test
     public void receiveDhcp() {
+        TestUtils.setField(provider, "useDhcp", true);
         // DHCP Request
-        testProcessor.process(new TestDhcpRequestPacketContext(DEV1));
+        testProcessor.process(new TestDhcpRequestPacketContext(DEV1, VLAN));
         assertThat("receiveDhcpRequest. One host description expected",
                 providerService.descriptions.size(), is(1));
         // Should learn the MAC and location of DHCP client
@@ -347,23 +369,30 @@
         assertThat(descr.vlan(), is(VLAN));
 
         // DHCP Ack
-        testProcessor.process(new TestDhcpAckPacketContext(DEV1));
+        testProcessor.process(new TestDhcpAckPacketContext(DEV1, false));
         assertThat("receiveDhcpAck. Two additional host descriptions expected",
-                providerService.descriptions.size(), is(3));
-        // Should learn the IP of DHCP client
-        HostDescription descr2 = providerService.descriptions.get(1);
-        assertThat(descr2.location(), is(LOCATION));
-        assertThat(descr2.hwAddress(), is(MAC));
-        assertThat(descr2.ipAddress().size(), is(1));
-        assertTrue(descr2.ipAddress().contains(IP_ADDRESS));
-        assertThat(descr2.vlan(), is(VLAN));
-        // Should also learn the MAC, location of DHCP server
-        HostDescription descr3 = providerService.descriptions.get(2);
-        assertThat(descr3.location(), is(LOCATION3));
-        assertThat(descr3.hwAddress(), is(MAC3));
-        assertThat(descr3.ipAddress().size(), is(0));
-        assertThat(descr3.vlan(), is(VLAN));
+                providerService.descriptions.size(), is(2));
 
+        // Should also learn the MAC, location of DHCP server
+        HostDescription descr2 = providerService.descriptions.get(1);
+        assertThat(descr2.location(), is(LOCATION3));
+        assertThat(descr2.hwAddress(), is(MAC3));
+        assertThat(descr2.ipAddress().size(), is(0));
+        assertThat(descr2.vlan(), is(VLAN));
+
+        // Should not update the IP address of the host.
+    }
+
+    /**
+     * The host store should not updated when we disabled "useDhcp".
+     */
+    @Test
+    public void receiveDhcpButNotEnabled() {
+        TestUtils.setField(provider, "useDhcp", false);
+        // DHCP Request
+        testProcessor.process(new TestDhcpRequestPacketContext(DEV1, VLAN));
+        assertThat("receiveDhcpButNotEnabled. No host description expected",
+                   providerService.descriptions.size(), is(0));
     }
 
     /**
@@ -604,10 +633,12 @@
      */
     private class TestDhcpRequestPacketContext extends PacketContextAdapter {
         private final String deviceId;
+        private final VlanId vlanId;
 
-        public TestDhcpRequestPacketContext(String deviceId) {
+        public TestDhcpRequestPacketContext(String deviceId, VlanId vlanId) {
             super(0, null, null, false);
             this.deviceId = deviceId;
+            this.vlanId = vlanId;
         }
 
         @Override
@@ -632,7 +663,7 @@
             ipv4.setSourceAddress(IP_ADDRESS.toString());
             Ethernet eth = new Ethernet();
             eth.setEtherType(Ethernet.TYPE_IPV4)
-                    .setVlanID(VLAN.toShort())
+                    .setVlanID(this.vlanId.toShort())
                     .setSourceMACAddress(MAC)
                     .setDestinationMACAddress(MAC3)
                     .setPayload(ipv4);
@@ -648,10 +679,12 @@
      */
     private class TestDhcpAckPacketContext extends PacketContextAdapter {
         private final String deviceId;
+        private final boolean withRelayinfo;
 
-        public TestDhcpAckPacketContext(String deviceId) {
+        public TestDhcpAckPacketContext(String deviceId, boolean withRelayInfo) {
             super(0, null, null, false);
             this.deviceId = deviceId;
+            this.withRelayinfo = withRelayInfo;
         }
 
         @Override
@@ -663,10 +696,29 @@
             dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
             dhcpOption.setData(dhcpMsgType);
             dhcpOption.setLength((byte) 1);
+
             DHCP dhcp = new DHCP();
-            dhcp.setOptions(Collections.singletonList(dhcpOption));
+
+            if (withRelayinfo) {
+                CircuitId cid = new CircuitId(LOCATION.toString(), VLAN_100);
+                byte[] circuitId = cid.serialize();
+                DhcpOption circuitIdSubOption = new DhcpOption();
+                circuitIdSubOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdSubOption.setData(circuitId);
+                circuitIdSubOption.setLength((byte) circuitId.length);
+
+                DhcpRelayAgentOption relayInfoOption = new DhcpRelayAgentOption();
+                relayInfoOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayInfoOption.addSubOption(circuitIdSubOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayInfoOption));
+                dhcp.setGatewayIPAddress(GW_IFACE_ADDR.ipAddress().getIp4Address().toInt());
+            } else {
+                dhcp.setOptions(ImmutableList.of(dhcpOption));
+            }
+
             dhcp.setClientHardwareAddress(MAC.toBytes());
             dhcp.setYourIPAddress(IP_ADDRESS.getIp4Address().toInt());
+
             UDP udp = new UDP();
             udp.setPayload(dhcp);
             udp.setSourcePort(UDP.DHCP_SERVER_PORT);
@@ -961,9 +1013,60 @@
                 return HOST2;
             } else if (hostId.equals(HostId.hostId(MAC3, VLAN))) {
                 return HOST3;
+            } else if (hostId.equals(HostId.hostId(MAC, VLAN_100))) {
+                return HOST_VLAN_100;
             }
             return null;
         }
+    }
 
+    private class TestInterfaceService implements InterfaceService {
+        @Override
+        public Set<Interface> getInterfaces() {
+            return null;
+        }
+
+        @Override
+        public Interface getInterfaceByName(ConnectPoint connectPoint, String name) {
+            return null;
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+            return null;
+        }
+
+        public Set<Interface> getInterfacesByIp(IpAddress ip) {
+            if (ip.equals(GW_IFACE_ADDR.ipAddress())) {
+                return ImmutableSet.of(GW_IFACE);
+            } else {
+                return ImmutableSet.of();
+            }
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByVlan(VlanId vlan) {
+            return null;
+        }
+
+        @Override
+        public Interface getMatchingInterface(IpAddress ip) {
+            return null;
+        }
+
+        @Override
+        public Set<Interface> getMatchingInterfaces(IpAddress ip) {
+            return null;
+        }
+
+        @Override
+        public void addListener(InterfaceListener listener) {
+
+        }
+
+        @Override
+        public void removeListener(InterfaceListener listener) {
+
+        }
     }
 }
diff --git a/utils/misc/src/main/java/org/onlab/packet/DHCP.java b/utils/misc/src/main/java/org/onlab/packet/DHCP.java
index ed1741e..f673da0 100644
--- a/utils/misc/src/main/java/org/onlab/packet/DHCP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/DHCP.java
@@ -583,7 +583,6 @@
             boolean foundEndOptionsMarker = false;
             while (bb.hasRemaining()) {
                 DhcpOption option;
-
                 int pos = bb.position();
                 int optCode = UNSIGNED_BYTE_MASK & bb.array()[pos]; // to unsigned integer
                 int optLen;
