diff --git a/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java b/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java
index 8e11002..018ac69 100755
--- a/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java
+++ b/app/src/main/java/org/opencord/dhcpl2relay/impl/DhcpL2Relay.java
@@ -15,11 +15,36 @@
  */
 package org.opencord.dhcpl2relay.impl;
 
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
+import static org.onlab.packet.MacAddress.valueOf;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.ENABLE_DHCP_BROADCAST_REPLIES;
+import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.ENABLE_DHCP_BROADCAST_REPLIES_DEFAULT;
+import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.OPTION_82;
+import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.OPTION_82_DEFAULT;
+import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.PACKET_PROCESSOR_THREADS;
+import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.PACKET_PROCESSOR_THREADS_DEFAULT;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
 import org.apache.commons.io.HexDump;
 import org.onlab.packet.DHCP;
 import org.onlab.packet.Ethernet;
@@ -30,6 +55,7 @@
 import org.onlab.packet.UDP;
 import org.onlab.packet.VlanId;
 import org.onlab.packet.dhcp.DhcpOption;
+import org.onlab.packet.dhcp.DhcpRelayAgentOption;
 import org.onlab.util.KryoNamespace;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
@@ -78,7 +104,7 @@
 import org.opencord.dhcpl2relay.DhcpL2RelayListener;
 import org.opencord.dhcpl2relay.DhcpL2RelayService;
 import org.opencord.dhcpl2relay.DhcpL2RelayStoreDelegate;
-import org.opencord.dhcpl2relay.impl.packet.DhcpOption82;
+import org.opencord.dhcpl2relay.impl.packet.DhcpOption82Data;
 import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SadisService;
 import org.opencord.sadis.SubscriberAndDeviceInformation;
@@ -93,30 +119,11 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import static java.util.concurrent.Executors.newFixedThreadPool;
-import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
-import static org.onlab.packet.MacAddress.valueOf;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
-import static org.opencord.dhcpl2relay.impl.OsgiPropertyConstants.*;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 /**
  * DHCP Relay Agent Application Component.
@@ -565,54 +572,12 @@
                                     appId, Optional.of(cp.deviceId()));
     }
 
-    private SubscriberAndDeviceInformation getDevice(PacketContext context) {
-        String serialNo = deviceService.getDevice(context.inPacket().
-                receivedFrom().deviceId()).serialNumber();
-
-        return subsService.get(serialNo);
-    }
-
-    private MacAddress relayAgentMacAddress(PacketContext context) {
-
-        SubscriberAndDeviceInformation device = this.getDevice(context);
-        if (device == null) {
-            log.warn("Device not found for {}", context.inPacket().
-                    receivedFrom());
-            return null;
-        }
-
-        return device.hardwareIdentifier();
-    }
-
-    private String nasPortId(PacketContext context) {
-        return nasPortId(context.inPacket().receivedFrom());
-    }
-
-    private String nasPortId(ConnectPoint cp) {
-        Port p = deviceService.getPort(cp);
-        return p.annotations().value(AnnotationKeys.PORT_NAME);
-    }
-
-    private SubscriberAndDeviceInformation getSubscriber(PacketContext context) {
-        return subsService.get(nasPortId(context));
-    }
-
-    private UniTagInformation getUnitagInformationFromPacketContext(PacketContext context,
-                                                                    SubscriberAndDeviceInformation sub) {
-        //If the ctag is defined in the tagList and dhcp is required, return the service info
-        List<UniTagInformation> tagList = sub.uniTagList();
-        for (UniTagInformation uniServiceInformation : tagList) {
-            if (uniServiceInformation.getPonCTag().toShort() == context.inPacket().parsed().getVlanID()) {
-                if (uniServiceInformation.getIsDhcpRequired()) {
-                    return uniServiceInformation;
-                }
-            }
-        }
-
-        return null;
-    }
-
+    /**
+     * Main packet-processing engine for dhcp l2 relay agent.
+     */
     private class DhcpRelayPacketProcessor implements PacketProcessor {
+        private static final String VLAN_KEYWORD = ":vlan";
+        private static final String PCP_KEYWORD = ":pcp";
 
         @Override
         public void process(PacketContext context) {
@@ -655,93 +620,6 @@
             }
         }
 
-        //forward the packet to ConnectPoint where the DHCP server is attached.
-        private void forwardPacket(Ethernet packet, PacketContext context) {
-            if (log.isTraceEnabled()) {
-                IPv4 ipv4Packet = (IPv4) packet.getPayload();
-                UDP udpPacket = (UDP) ipv4Packet.getPayload();
-                DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
-                log.trace("Emitting packet to server: packet {}, with MAC {}",
-                          getDhcpPacketType(dhcpPayload),
-                          MacAddress.valueOf(dhcpPayload.getClientHardwareAddress()));
-            }
-            ConnectPoint toSendTo = null;
-            if (!useOltUplink) {
-                toSendTo = dhcpServerConnectPoint.get();
-            } else {
-                toSendTo = getUplinkConnectPointOfOlt(context.inPacket().
-                        receivedFrom().deviceId());
-            }
-
-            if (toSendTo != null) {
-                TrafficTreatment t = DefaultTrafficTreatment.builder()
-                        .setOutput(toSendTo.port()).build();
-                OutboundPacket o = new DefaultOutboundPacket(
-                        toSendTo.deviceId(), t,
-                        ByteBuffer.wrap(packet.serialize()));
-                if (log.isTraceEnabled()) {
-                    log.trace("Relaying packet to dhcp server at {} {}",
-                              toSendTo, packet);
-                }
-                packetService.emit(o);
-
-                SubscriberAndDeviceInformation entry = getSubscriberInfoFromClient(context);
-                updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("PACKETS_TO_SERVER"));
-            } else {
-                log.error("No connect point to send msg to DHCP Server");
-            }
-        }
-
-        // get the type of the DHCP packet
-        private DHCP.MsgType getDhcpPacketType(DHCP dhcpPayload) {
-
-            for (DhcpOption option : dhcpPayload.getOptions()) {
-                if (option.getCode() == OptionCode_MessageType.getValue()) {
-                    byte[] data = option.getData();
-                    return DHCP.MsgType.getType(data[0]);
-                }
-            }
-            return null;
-        }
-
-        private void updateDhcpRelayCountersStore(SubscriberAndDeviceInformation entry,
-                                                  DhcpL2RelayCounterNames counterType) {
-            // Update global counter stats
-            dhcpL2RelayCounters.incrementCounter(DhcpL2RelayEvent.GLOBAL_COUNTER, counterType);
-            if (entry == null) {
-                log.warn("Counter not updated as subscriber info not found.");
-            } else {
-                // Update subscriber counter stats
-                dhcpL2RelayCounters.incrementCounter(entry.id(), counterType);
-            }
-        }
-
-        /*
-         * Get subscriber information based on it's context packet.
-         */
-        private SubscriberAndDeviceInformation getSubscriberInfoFromClient(PacketContext context) {
-            if (context != null) {
-                return getSubscriber(context);
-            }
-            return null;
-        }
-
-        /*
-         * Get subscriber information based on it's DHCP payload.
-         */
-        private SubscriberAndDeviceInformation getSubscriberInfoFromServer(DHCP dhcpPayload, PacketContext context) {
-            if (dhcpPayload != null) {
-                MacAddress descMac = valueOf(dhcpPayload.getClientHardwareAddress());
-                ConnectPoint subsCp = getConnectPointOfClient(descMac, context);
-
-                if (subsCp != null) {
-                    String portId = nasPortId(subsCp);
-                    return subsService.get(portId);
-                }
-            }
-            return null;
-        }
-
         // process the dhcp packet before relaying to server or client
         private void processDhcpPacket(PacketContext context, Ethernet packet,
                                        DHCP dhcpPayload) {
@@ -776,66 +654,63 @@
                     Ethernet ethernetPacketDiscover =
                             processDhcpPacketFromClient(context, packet);
                     if (ethernetPacketDiscover != null) {
-                        forwardPacket(ethernetPacketDiscover, context);
+                        relayPacketToServer(ethernetPacketDiscover, context);
                     }
-                    entry = getSubscriberInfoFromClient(context);
+                    entry = getSubscriber(context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPDISCOVER"));
                     break;
                 case DHCPOFFER:
-                    //reply to dhcp client.
-                    Ethernet ethernetPacketOffer =
+                    RelayToClientInfo r2cDataOffer =
                             processDhcpPacketFromServer(context, packet);
-                    if (ethernetPacketOffer != null) {
-                        sendReply(ethernetPacketOffer, dhcpPayload, context);
+                    if (r2cDataOffer != null) {
+                        relayPacketToClient(r2cDataOffer, clientMacAddress);
+                        entry = getSubscriber(r2cDataOffer.cp);
                     }
-                    entry = getSubscriberInfoFromServer(dhcpPayload, context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPOFFER"));
                     break;
                 case DHCPREQUEST:
                     Ethernet ethernetPacketRequest =
                             processDhcpPacketFromClient(context, packet);
                     if (ethernetPacketRequest != null) {
-                        forwardPacket(ethernetPacketRequest, context);
+                        relayPacketToServer(ethernetPacketRequest, context);
                     }
-                    entry = getSubscriberInfoFromClient(context);
+                    entry = getSubscriber(context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPREQUEST"));
                     break;
                 case DHCPACK:
-                    //reply to dhcp client.
-                    Ethernet ethernetPacketAck =
+                    RelayToClientInfo r2cDataAck =
                             processDhcpPacketFromServer(context, packet);
-                    if (ethernetPacketAck != null) {
-                        sendReply(ethernetPacketAck, dhcpPayload, context);
+                    if (r2cDataAck != null) {
+                        relayPacketToClient(r2cDataAck, clientMacAddress);
+                        entry = getSubscriber(r2cDataAck.cp);
                     }
-                    entry = getSubscriberInfoFromServer(dhcpPayload, context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPACK"));
                     break;
                 case DHCPDECLINE:
                     Ethernet ethernetPacketDecline =
                             processDhcpPacketFromClient(context, packet);
                     if (ethernetPacketDecline != null) {
-                        forwardPacket(ethernetPacketDecline, context);
+                        relayPacketToServer(ethernetPacketDecline, context);
                     }
-                    entry = getSubscriberInfoFromClient(context);
+                    entry = getSubscriber(context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPDECLINE"));
                     break;
                 case DHCPNAK:
-                    //reply to dhcp client.
-                    Ethernet ethernetPacketNak =
+                    RelayToClientInfo r2cDataNack =
                             processDhcpPacketFromServer(context, packet);
-                    if (ethernetPacketNak != null) {
-                        sendReply(ethernetPacketNak, dhcpPayload, context);
+                    if (r2cDataNack != null) {
+                        relayPacketToClient(r2cDataNack, clientMacAddress);
+                        entry = getSubscriber(r2cDataNack.cp);
                     }
-                    entry = getSubscriberInfoFromServer(dhcpPayload, context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPNACK"));
                     break;
                 case DHCPRELEASE:
                     Ethernet ethernetPacketRelease =
                             processDhcpPacketFromClient(context, packet);
                     if (ethernetPacketRelease != null) {
-                        forwardPacket(ethernetPacketRelease, context);
+                        relayPacketToServer(ethernetPacketRelease, context);
                     }
-                    entry = getSubscriberInfoFromClient(context);
+                    entry = getSubscriber(context);
                     updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("DHCPRELEASE"));
                     break;
                 default:
@@ -843,6 +718,13 @@
             }
         }
 
+        /**
+         * Processes dhcp packets from clients.
+         *
+         * @param context the packet context
+         * @param ethernetPacket the dhcp packet from client
+         * @return the packet to relay to the server
+         */
         private Ethernet processDhcpPacketFromClient(PacketContext context,
                                                      Ethernet ethernetPacket) {
             if (log.isTraceEnabled()) {
@@ -884,19 +766,16 @@
                          inPort, clientVlan);
                 return null;
             }
-
-            DhcpAllocationInfo info = new DhcpAllocationInfo(
-                    inPort, dhcpPacket.getPacketType(), entry.circuitId(),
-                    clientMac, clientIp, clientVlan, entry.id());
-
-            String key = getUniqueUuidFromString(entry.id() + clientMac
-                                                 + clientVlan);
-            allocations.put(key, info);
-
-            post(new DhcpL2RelayEvent(DhcpL2RelayEvent.Type.UPDATED, info,
-                                      inPort));
+            DhcpOption82Data d82 = null;
             if (option82) {
-                DHCP dhcpPacketWithOption82 = addOption82(dhcpPacket, entry);
+                DHCP dhcpPacketWithOption82 = addOption82(dhcpPacket, entry,
+                                                          inPort, clientVlan,
+                                                          uniTagInformation
+                                                                  .getDsPonCTagPriority());
+                byte[] d82b = dhcpPacketWithOption82
+                        .getOption(DHCP.DHCPOptionCode.OptionCode_CircuitID)
+                        .getData();
+                d82 = new DhcpOption82Data(d82b);
                 udpPacket.setPayload(dhcpPacketWithOption82);
             }
 
@@ -914,14 +793,39 @@
             if (uniTagInformation.getUsPonSTagPriority() != -1) {
                 etherReply.setQinQPriorityCode((byte) uniTagInformation.getUsPonSTagPriority());
             }
-            log.info("Finished processing DHCP Packet of type {} from {} and relaying to dhcpServer",
-                     dhcpPacket.getPacketType(), entry.id());
+            if (uniTagInformation.getUsPonCTagPriority() != -1) {
+                etherReply.setPriorityCode((byte) uniTagInformation
+                        .getUsPonCTagPriority());
+            }
+
+            DhcpAllocationInfo info = new DhcpAllocationInfo(inPort,
+                                                             dhcpPacket.getPacketType(),
+                                                             (d82 == null)
+                                                                 ? entry.circuitId()
+                                                                 : d82.getAgentCircuitId(),
+                                                             clientMac, clientIp,
+                                                             clientVlan, entry.id());
+            String key = getUniqueUuidFromString(entry.id() + clientMac
+                    + clientVlan);
+            allocations.put(key, info);
+            post(new DhcpL2RelayEvent(DhcpL2RelayEvent.Type.UPDATED, info, inPort));
+            if (log.isTraceEnabled()) {
+                log.trace("Finished processing DHCP Packet of type {} from {} "
+                        + "... relaying to dhcpServer",
+                          dhcpPacket.getPacketType(), entry.id());
+            }
             return etherReply;
         }
 
-        //build the DHCP offer/ack with proper client port.
-        private Ethernet processDhcpPacketFromServer(PacketContext context,
-                                                     Ethernet ethernetPacket) {
+        /**
+         * Processes dhcp packets from the server.
+         *
+         * @param context the packet context
+         * @param ethernetPacket the dhcp packet
+         * @return returns information necessary for relaying packet to client
+         */
+        private RelayToClientInfo processDhcpPacketFromServer(PacketContext context,
+                                                              Ethernet ethernetPacket) {
             if (log.isTraceEnabled()) {
                 log.trace("DHCP Packet received from server at {} {}",
                           context.inPacket().receivedFrom(), ethernetPacket);
@@ -930,66 +834,349 @@
             Ethernet etherReply = (Ethernet) ethernetPacket.clone();
             IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
             UDP udpPacket = (UDP) ipv4Packet.getPayload();
-            DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
+            DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
             VlanId innerVlan = VlanId.vlanId(ethernetPacket.getVlanID());
+            MacAddress dstMac = valueOf(dhcpPacket.getClientHardwareAddress());
 
-            MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
-            ConnectPoint subsCp = getConnectPointOfClient(dstMac, context);
-            // If we can't find the subscriber, can't process further
-            if (subsCp == null) {
-                log.warn("Couldn't find subscriber, service or host info for mac"
-                        + " address {} and vlan {} .. DHCP packet won't be delivered", dstMac, innerVlan);
-                return null;
-            }
-
-            SubscriberAndDeviceInformation entry = getSubscriberInfoFromServer(dhcpPayload, context);
-            if (entry != null) {
-                IpAddress ip = IpAddress.valueOf(dhcpPayload.getYourIPAddress());
-                // store DHCPAllocationInfo
-                DhcpAllocationInfo info = new DhcpAllocationInfo(subsCp,
-                     dhcpPayload.getPacketType(), entry.circuitId(), dstMac, ip,
-                     innerVlan, entry.id());
-                String key = getUniqueUuidFromString(entry.id()
-                                                     + info.macAddress() + innerVlan);
-                allocations.put(key, info);
-
-                post(new DhcpL2RelayEvent(DhcpL2RelayEvent.Type.UPDATED, info, subsCp));
-            }
-
-            UniTagInformation uniTagInformation = getUnitagInformationFromPacketContext(context, entry);
-            if (uniTagInformation == null) {
-                log.warn("Missing service information for connectPoint {} / cTag {}",
-                         context.inPacket().receivedFrom(), context.inPacket().parsed().getVlanID());
-                return null;
-            }
-
-            updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames.valueOf("PACKETS_FROM_SERVER"));
-
-            // we leave the srcMac from the original packet
+            // we leave the srcMac from the original packet.
+            // TODO remove S-VLAN
             etherReply.setQinQVID(VlanId.NO_VID);
             etherReply.setQinQPriorityCode((byte) 0);
             etherReply.setDestinationMACAddress(dstMac);
-            etherReply.setVlanID(uniTagInformation.getPonCTag().toShort());
-            if (uniTagInformation.getUsPonCTagPriority() != -1) {
-                etherReply.setPriorityCode((byte) uniTagInformation.getUsPonCTagPriority());
-            }
 
+            // TODO deserialization of dhcp option82 leaves 'data' field null
+            // As a result we need to retrieve suboption data
+            RelayToClientInfo r2cData = null;
+            boolean usedOption82 = false;
             if (option82) {
-                udpPacket.setPayload(removeOption82(dhcpPayload));
-            } else {
-                udpPacket.setPayload(dhcpPayload);
+                // retrieve connectPoint and vlan from option82, if it is in expected format
+                DhcpOption opt = dhcpPacket
+                        .getOption(DHCP.DHCPOptionCode.OptionCode_CircuitID);
+                if (opt != null && opt instanceof DhcpRelayAgentOption) {
+                    DhcpRelayAgentOption d82 = (DhcpRelayAgentOption) opt;
+                    DhcpOption d82ckt = d82.getSubOption(DhcpOption82Data.CIRCUIT_ID_CODE);
+                    if (d82ckt.getData() != null) {
+                        r2cData = decodeCircuitId(new String(d82ckt.getData()));
+                    }
+                }
+                if (r2cData != null) {
+                    usedOption82 = true;
+                    etherReply.setVlanID(r2cData.cvid.toShort());
+                    if (r2cData.pcp != -1) {
+                        etherReply.setPriorityCode((byte) r2cData.pcp);
+                    }
+                }
             }
+            // always remove option82 if present
+            DHCP remDhcpPacket = removeOption82(dhcpPacket);
+            udpPacket.setPayload(remDhcpPacket);
+
             ipv4Packet.setPayload(udpPacket);
             etherReply.setPayload(ipv4Packet);
 
-            log.info("Finished processing packet.. relaying to client");
-            return etherReply;
+            if (!usedOption82) {
+                // option 82 data not present or not used, we need to
+                // lookup host store with client dstmac and vlan from context
+                r2cData = new RelayToClientInfo();
+                r2cData.cp = getConnectPointOfClient(dstMac, context);
+                if (r2cData.cp == null) {
+                    log.warn("Couldn't find subscriber, service or host info for mac"
+                            + " address {} and vlan {} .. DHCP packet can't be"
+                            + " delivered to client", dstMac, innerVlan);
+                    return null;
+                }
+            }
+
+            // always need the subscriber entry
+            SubscriberAndDeviceInformation entry = getSubscriber(r2cData.cp);
+            if (entry == null) {
+                log.warn("Couldn't find subscriber info for cp {}.. DHCP packet"
+                        + " can't be delivered to client mac {} and vlan {}",
+                         r2cData.cp, dstMac, innerVlan);
+                return null;
+            }
+
+            if (!usedOption82) {
+                UniTagInformation uniTagInformation =
+                        getUnitagInformationFromPacketContext(context, entry);
+                if (uniTagInformation == null) {
+                    log.warn("Missing service information for connectPoint {} "
+                            + " cTag {} .. DHCP packet can't be delivered to client",
+                             r2cData.cp, innerVlan);
+                    return null;
+                }
+                r2cData.cvid = uniTagInformation.getPonCTag();
+                r2cData.pcp = uniTagInformation.getDsPonCTagPriority();
+                r2cData.cktId = entry.circuitId();
+                etherReply.setVlanID(r2cData.cvid.toShort());
+                if (r2cData.pcp != -1) {
+                    etherReply.setPriorityCode((byte) r2cData.pcp);
+                }
+            }
+
+            // update stats and events
+            IpAddress ip = IpAddress.valueOf(dhcpPacket.getYourIPAddress());
+            DhcpAllocationInfo info =
+                    new DhcpAllocationInfo(r2cData.cp, dhcpPacket.getPacketType(),
+                                           r2cData.cktId, dstMac, ip, innerVlan,
+                                           entry.id());
+            String key = getUniqueUuidFromString(entry.id() + info.macAddress()
+                    + innerVlan);
+            allocations.put(key, info);
+            post(new DhcpL2RelayEvent(DhcpL2RelayEvent.Type.UPDATED, info,
+                                      r2cData.cp));
+            updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames
+                    .valueOf("PACKETS_FROM_SERVER"));
+            if (log.isTraceEnabled()) {
+                log.trace("Finished processing packet.. relaying to client at {}",
+                     r2cData.cp);
+            }
+            r2cData.ethernetPkt = etherReply;
+            return r2cData;
         }
 
-        /*
-         * Get ConnectPoint of the Client based on it's MAC address
+        // forward the packet to ConnectPoint where the DHCP server is attached.
+        private void relayPacketToServer(Ethernet packet, PacketContext context) {
+            if (log.isTraceEnabled()) {
+                IPv4 ipv4Packet = (IPv4) packet.getPayload();
+                UDP udpPacket = (UDP) ipv4Packet.getPayload();
+                DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
+                log.trace("Emitting packet to server: packet {}, with MAC {}",
+                          getDhcpPacketType(dhcpPayload),
+                          MacAddress.valueOf(dhcpPayload.getClientHardwareAddress()));
+            }
+            ConnectPoint toSendTo = null;
+            if (!useOltUplink) {
+                toSendTo = dhcpServerConnectPoint.get();
+            } else {
+                toSendTo = getUplinkConnectPointOfOlt(context.inPacket().receivedFrom()
+                        .deviceId());
+            }
+
+            if (toSendTo != null) {
+                TrafficTreatment t = DefaultTrafficTreatment.builder()
+                        .setOutput(toSendTo.port()).build();
+                OutboundPacket o = new DefaultOutboundPacket(toSendTo
+                        .deviceId(), t, ByteBuffer.wrap(packet.serialize()));
+                if (log.isTraceEnabled()) {
+                    log.trace("Relaying packet to dhcp server at {} {}", toSendTo,
+                              packet);
+                }
+                packetService.emit(o);
+
+                SubscriberAndDeviceInformation entry = getSubscriber(context);
+                updateDhcpRelayCountersStore(entry, DhcpL2RelayCounterNames
+                        .valueOf("PACKETS_TO_SERVER"));
+            } else {
+                log.error("No connect point to send msg to DHCP Server");
+            }
+        }
+
+        // send the response to the requester host (client)
+        private void relayPacketToClient(RelayToClientInfo r2cData,
+                                         MacAddress dstMac) {
+            ConnectPoint subCp = r2cData.cp;
+            Ethernet ethPacket = r2cData.ethernetPkt;
+            // Send packet out to requester if the host information is available
+            if (subCp != null) {
+                TrafficTreatment t = DefaultTrafficTreatment.builder()
+                        .setOutput(subCp.port()).build();
+                OutboundPacket o = new DefaultOutboundPacket(subCp.deviceId(),
+                                        t, ByteBuffer.wrap(ethPacket.serialize()));
+                if (log.isTraceEnabled()) {
+                    log.trace("Relaying packet to DHCP client at {} with "
+                        + "MacAddress {}, {} given {}", subCp, dstMac,
+                         ethPacket, r2cData);
+                }
+                packetService.emit(o);
+            } else {
+                log.error("Dropping DHCP Packet because unknown connectPoint for {}",
+                          dstMac);
+            }
+        }
+
+        /**
+         * Option 82 includes circuitId and remoteId data configured by an
+         * operator in sadis for a subscriber, and can be a string in any form
+         * relevant to the operator's dhcp-server. When circuitId is configured
+         * in sadis, the relay agent adds the option, but does not use the
+         * information for forwarding packets back to client.
+         * <p>
+         * If circuitId is not configured in sadis, this relay-agent adds
+         * circuitId information in the form
+         * "{@literal<}connectPoint>:vlan{@literal<}clientVlanId>:pcp{@literal<}downstreamPcp>"
+         * for example, "of:0000000000000001/32:vlan200:pcp7". When the packet
+         * is received back from the server with circuitId in this form, this
+         * relay agent will use this information to forward packets to the
+         * client.
+         *
+         * @param dhcpPacket the DHCP packet to transform
+         * @param entry sadis information for the subscriber
+         * @param cp the connectPoint to set if sadis entry has no circuitId
+         * @param clientVlan the vlan to set if sadis entry has no circuitId
+         * @param downstreamPbits the pbits to set if sadis entry has no
+         *            circuitId
+         * @return the modified dhcp packet with option82 added
          */
-        private ConnectPoint getConnectPointOfClient(MacAddress dstMac, PacketContext context) {
+        private DHCP addOption82(DHCP dhcpPacket, SubscriberAndDeviceInformation entry,
+                                 ConnectPoint cp, VlanId clientVlan,
+                                 int downstreamPbits) {
+            List<DhcpOption> options = Lists.newArrayList(dhcpPacket.getOptions());
+            DhcpOption82Data option82 = new DhcpOption82Data();
+            if (entry.circuitId() == null || entry.circuitId().isBlank()) {
+                option82.setAgentCircuitId(cp + VLAN_KEYWORD + clientVlan
+                        + PCP_KEYWORD
+                        + downstreamPbits);
+            } else {
+                option82.setAgentCircuitId(entry.circuitId());
+            }
+            option82.setAgentRemoteId(entry.remoteId());
+            if (log.isTraceEnabled()) {
+                log.trace("adding option82 {} ", option82);
+            }
+            DhcpOption option = new DhcpOption()
+                    .setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
+                    .setData(option82.toByteArray())
+                    .setLength(option82.length());
+
+            options.add(options.size() - 1, option);
+            dhcpPacket.setOptions(options);
+
+            return dhcpPacket;
+        }
+
+        private DHCP removeOption82(DHCP dhcpPacket) {
+            List<DhcpOption> options = dhcpPacket.getOptions();
+            List<DhcpOption> newoptions = options.stream()
+                    .filter(option -> option
+                            .getCode() != DHCP.DHCPOptionCode.OptionCode_CircuitID
+                                    .getValue())
+                    .collect(Collectors.toList());
+
+            return dhcpPacket.setOptions(newoptions);
+        }
+
+        /**
+         * Returns the circuit Id values decoded from the option 82 data. Decoding
+         * is performed if and only if the circuit id format is in the form
+         * "{@literal<}connectPoint>:vlan{@literal<}clientVlanId>:pcp{@literal<}downstreamPcp>"
+         *
+         * @param cktId the circuitId string from option 82 data
+         * @return decoded circuit id data if it is in the expected format or
+         *         null
+         */
+        private RelayToClientInfo decodeCircuitId(String cktId) {
+            if (cktId.contains(VLAN_KEYWORD) && cktId.contains(PCP_KEYWORD)) {
+                ConnectPoint cp = ConnectPoint
+                        .fromString(cktId
+                                .substring(0, cktId.indexOf(VLAN_KEYWORD)));
+                VlanId cvid = VlanId
+                        .vlanId(cktId.substring(
+                                                cktId.indexOf(VLAN_KEYWORD)
+                                                        + VLAN_KEYWORD.length(),
+                                                cktId.indexOf(PCP_KEYWORD)));
+                int pcp = Integer
+                        .valueOf(cktId.substring(cktId.indexOf(PCP_KEYWORD)
+                                + PCP_KEYWORD.length()))
+                        .intValue();
+                log.debug("retrieved from option82-> cp={} cvlan={} down-pcp={}"
+                        + " for relaying to client ", cp, cvid, pcp);
+                return new RelayToClientInfo(cp, cvid, pcp, cktId);
+            } else {
+                log.debug("Option 82 circuitId {} is operator defined and will "
+                        + "not be used for forwarding", cktId);
+                return null;
+            }
+        }
+
+        private class RelayToClientInfo {
+            Ethernet ethernetPkt;
+            ConnectPoint cp;
+            VlanId cvid;
+            int pcp;
+            String cktId;
+
+            public RelayToClientInfo(ConnectPoint cp, VlanId cvid, int pcp,
+                                     String cktId) {
+                this.cp = cp;
+                this.cvid = cvid;
+                this.pcp = pcp;
+                this.cktId = cktId;
+            }
+
+            public RelayToClientInfo() {
+            }
+
+            @Override
+            public String toString() {
+                return "RelayToClientInfo: {connectPoint=" + cp + " clientVlan="
+                        + cvid + " clientPcp=" + pcp + " circuitId=" + cktId + "}";
+            }
+
+        }
+
+        // get the type of the DHCP packet
+        private DHCP.MsgType getDhcpPacketType(DHCP dhcpPayload) {
+            for (DhcpOption option : dhcpPayload.getOptions()) {
+                if (option.getCode() == OptionCode_MessageType.getValue()) {
+                    byte[] data = option.getData();
+                    return DHCP.MsgType.getType(data[0]);
+                }
+            }
+            return null;
+        }
+
+        private void updateDhcpRelayCountersStore(SubscriberAndDeviceInformation entry,
+                                                  DhcpL2RelayCounterNames counterType) {
+            // Update global counter stats
+            dhcpL2RelayCounters.incrementCounter(DhcpL2RelayEvent.GLOBAL_COUNTER,
+                                                 counterType);
+            if (entry == null) {
+                log.warn("Counter not updated as subscriber info not found.");
+            } else {
+                // Update subscriber counter stats
+                dhcpL2RelayCounters.incrementCounter(entry.id(), counterType);
+            }
+        }
+
+        /**
+         * Get subscriber information based on subscriber's connectPoint.
+         *
+         * @param subsCp the subscriber's connectPoint
+         * @return subscriber sadis info or null if not found
+         */
+        private SubscriberAndDeviceInformation getSubscriber(ConnectPoint subsCp) {
+            if (subsCp != null) {
+                String portName = getPortName(subsCp);
+                return subsService.get(portName);
+            }
+            return null;
+        }
+
+        /**
+         * Returns sadis info for subscriber based on incoming packet context.
+         * The packet context must refer to a packet coming from a subscriber
+         * port.
+         *
+         * @param context incoming packet context from subscriber port (UNI)
+         * @return sadis info for the subscriber or null
+         */
+        private SubscriberAndDeviceInformation getSubscriber(PacketContext context) {
+            String portName = getPortName(context.inPacket().receivedFrom());
+            return subsService.get(portName);
+        }
+
+        /**
+         * Returns ConnectPoint of the Client based on MAC address and C-VLAN.
+         * Verifies that returned connect point has service defined in sadis.
+         *
+         * @param dstMac client dstMac
+         * @param context context for incoming packet, parsed for C-vlan id
+         * @return connect point information for client or null if connect point
+         *         not found or service cannot be verified for client info
+         */
+        private ConnectPoint getConnectPointOfClient(MacAddress dstMac,
+                                                     PacketContext context) {
             Set<Host> hosts = hostService.getHostsByMac(dstMac);
             if (hosts == null || hosts.isEmpty()) {
                 log.warn("Cannot determine host for DHCP client: {}. Aborting "
@@ -1003,14 +1190,14 @@
                 ConnectPoint cp = new ConnectPoint(h.location().deviceId(),
                                                    h.location().port());
 
-                String portId = nasPortId(cp);
-                SubscriberAndDeviceInformation sub = subsService.get(portId);
+                SubscriberAndDeviceInformation sub = getSubscriber(cp);
                 if (sub == null) {
-                    log.warn("Subscriber info not found for {}", cp);
-                    return null;
+                    log.warn("Subscriber info not found for {} for host {}", cp, h);
+                    continue;
                 }
                 // check for cvlan in subscriber's uniTagInfo list
-                UniTagInformation uniTagInformation = getUnitagInformationFromPacketContext(context, sub);
+                UniTagInformation uniTagInformation =
+                        getUnitagInformationFromPacketContext(context, sub);
                 if (uniTagInformation != null) {
                     return cp;
                 }
@@ -1018,58 +1205,71 @@
             // no sadis config found for this connectPoint/vlan
             log.warn("Missing service information for dhcp packet received from"
                     + " {} with cTag {} .. cannot relay to client",
-                     context.inPacket().receivedFrom(), context.inPacket().parsed().getVlanID());
+                     context.inPacket().receivedFrom(),
+                     context.inPacket().parsed().getVlanID());
+            return null;
+        }
+
+        /**
+         * Returns the port-name for the given connectPoint port.
+         *
+         * @param cp the given connect point
+         * @return the port-name for the connect point port
+         */
+        private String getPortName(ConnectPoint cp) {
+            Port p = deviceService.getPort(cp);
+            return p.annotations().value(AnnotationKeys.PORT_NAME);
+        }
+
+        /**
+         * Return's uniTagInformation (service information) if incoming packet's
+         * client VLAN id matches the subscriber's service info, and dhcp is
+         * required for this service.
+         *
+         * @param context
+         * @param sub
+         * @return
+         */
+        private UniTagInformation getUnitagInformationFromPacketContext(PacketContext context,
+                                                                        SubscriberAndDeviceInformation sub) {
+            // If the ctag is defined in the tagList and dhcp is required,
+            // return the service info
+            List<UniTagInformation> tagList = sub.uniTagList();
+            for (UniTagInformation uniServiceInformation : tagList) {
+                if (uniServiceInformation.getPonCTag().toShort() == context.inPacket()
+                        .parsed().getVlanID()) {
+                    if (uniServiceInformation.getIsDhcpRequired()) {
+                        return uniServiceInformation;
+                    }
+                }
+            }
 
             return null;
         }
 
-        // send the response to the requester host (client)
-        private void sendReply(Ethernet ethPacket, DHCP dhcpPayload, PacketContext context) {
-            MacAddress descMac = valueOf(dhcpPayload.getClientHardwareAddress());
-            ConnectPoint subCp = getConnectPointOfClient(descMac, context);
-            // Send packet out to requester if the host information is available
-            if (subCp != null) {
-                TrafficTreatment t = DefaultTrafficTreatment.builder()
-                        .setOutput(subCp.port()).build();
-                OutboundPacket o = new DefaultOutboundPacket(
-                        subCp.deviceId(), t, ByteBuffer.wrap(ethPacket.serialize()));
-                if (log.isTraceEnabled()) {
-                    log.trace("Relaying packet to DHCP client at {} with MacAddress {}, {}", subCp,
-                              descMac, ethPacket);
-                }
-                packetService.emit(o);
-            } else {
-                log.error("Dropping DHCP Packet because can't find host for {}", descMac);
+
+        private MacAddress relayAgentMacAddress(PacketContext context) {
+            SubscriberAndDeviceInformation device = this.getDevice(context);
+            if (device == null) {
+                log.warn("Device not found for {}", context.inPacket().receivedFrom());
+                return null;
             }
+            return device.hardwareIdentifier();
         }
-    }
 
-    private DHCP addOption82(DHCP dhcpPacket, SubscriberAndDeviceInformation entry) {
-        log.trace("option82data {} ", entry);
+        /**
+         * Returns sadis information for device from which packet was received.
+         *
+         * @param context the packet context
+         * @return sadis information for device
+         */
+        private SubscriberAndDeviceInformation getDevice(PacketContext context) {
+            String serialNo = deviceService
+                    .getDevice(context.inPacket().receivedFrom().deviceId())
+                    .serialNumber();
+            return subsService.get(serialNo);
+        }
 
-        List<DhcpOption> options = Lists.newArrayList(dhcpPacket.getOptions());
-        DhcpOption82 option82 = new DhcpOption82();
-        option82.setAgentCircuitId(entry.circuitId());
-        option82.setAgentRemoteId(entry.remoteId());
-        DhcpOption option = new DhcpOption()
-                .setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
-                .setData(option82.toByteArray())
-                .setLength(option82.length());
-
-        options.add(options.size() - 1, option);
-        dhcpPacket.setOptions(options);
-
-        return dhcpPacket;
-
-    }
-
-    private DHCP removeOption82(DHCP dhcpPacket) {
-        List<DhcpOption> options = dhcpPacket.getOptions();
-        List<DhcpOption> newoptions = options.stream()
-                .filter(option -> option.getCode() != DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
-                .collect(Collectors.toList());
-
-        return dhcpPacket.setOptions(newoptions);
     }
 
     /**
@@ -1122,7 +1322,6 @@
         allocations.clear();
     }
 
-
     @Override
     public boolean removeAllocationsByConnectPoint(ConnectPoint cp) {
         boolean removed = false;
@@ -1136,7 +1335,6 @@
         return removed;
     }
 
-
     /**
      * Checks for mastership or falls back to leadership on deviceId.
      * If the node is not master and device is available
diff --git a/app/src/main/java/org/opencord/dhcpl2relay/impl/packet/DhcpOption82.java b/app/src/main/java/org/opencord/dhcpl2relay/impl/packet/DhcpOption82.java
deleted file mode 100644
index bad55f9..0000000
--- a/app/src/main/java/org/opencord/dhcpl2relay/impl/packet/DhcpOption82.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.opencord.dhcpl2relay.impl.packet;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Represents the DHCP Option 82 information. Currently only supports
- * sub option 1 (agent-circuit-id) and 2 (agent=-relay-id).
- */
-public class DhcpOption82 {
-
-    private String agentCircuitId = null;
-    private String agentRemoteId = null;
-
-    public DhcpOption82() {
-
-    }
-
-    public void setAgentCircuitId(String value) {
-        this.agentCircuitId = value;
-    }
-
-    /**
-     *
-     * @return agentCircuitId
-     */
-    public String getAgentCircuitId() {
-        return this.agentCircuitId;
-    }
-
-    /**
-     * sets AgentRemoteId.
-     * @param value   Value to be set
-     */
-    public void setAgentRemoteId(String value) {
-        this.agentRemoteId = value;
-    }
-
-    /**
-     *
-     * @return agentRemoteId
-     */
-    public String getAgentRemoteId() {
-        return this.agentRemoteId;
-    }
-
-    /**
-     *
-     * @return length of option 82.
-     */
-    public byte length() {
-        int length = 0;
-
-        // +2 below for sub option ID and length of sub option
-        if (agentCircuitId != null) {
-            length += agentCircuitId.length() + 2;
-        }
-        if (agentRemoteId != null) {
-            length += agentRemoteId.length() + 2;
-        }
-        return (byte) length;
-    }
-
-    /**
-     * Returns the representation of the option 82 specification as a byte
-     * array.
-     * @return returns byte array
-     */
-    public byte[] toByteArray() {
-        ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
-        // Add sub option if set
-        if (agentCircuitId != null) {
-            buf.write((byte) 1);
-            buf.write((byte) agentCircuitId.length());
-            byte[] bytes = agentCircuitId.getBytes(StandardCharsets.UTF_8);
-            buf.write(bytes, 0, bytes.length);
-        }
-
-        // Add sub option if set
-        if (agentRemoteId != null) {
-            buf.write((byte) 2);
-            buf.write((byte) agentRemoteId.length());
-            byte[] bytes = agentRemoteId.getBytes(StandardCharsets.UTF_8);
-            buf.write(bytes, 0, bytes.length);
-        }
-
-        return buf.toByteArray();
-    }
-
-}
diff --git a/app/src/main/java/org/opencord/dhcpl2relay/impl/packet/DhcpOption82Data.java b/app/src/main/java/org/opencord/dhcpl2relay/impl/packet/DhcpOption82Data.java
new file mode 100644
index 0000000..a2d031d
--- /dev/null
+++ b/app/src/main/java/org/opencord/dhcpl2relay/impl/packet/DhcpOption82Data.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.dhcpl2relay.impl.packet;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents the DHCP Option 82 sub-options. Currently only supports sub option
+ * 1 (agent-circuit-id) and 2 (agent-remote-id).
+ */
+public class DhcpOption82Data {
+
+    private String agentCircuitId = null;
+    private String agentRemoteId = null;
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    public static final byte CIRCUIT_ID_CODE = 1;
+    public static final byte REMOTE_ID_CODE = 2;
+
+    public DhcpOption82Data() {
+
+    }
+
+    /**
+     * Constructs a DhcpOption82Data object from the given byte array. The
+     * expectation is that the byte array starts with the first suboption (i.e
+     * it does not include the option-code and overall length of the option 82)
+     *
+     * @param b byte array representing the data portion of the dhcp option 82
+     */
+    public DhcpOption82Data(byte[] b) {
+        ByteBuffer bb = ByteBuffer.wrap(b, 0, b.length);
+        if (b.length < 3) {
+            log.warn("Malformed option82 sub-options {}", b);
+            return;
+        }
+        while (bb.hasRemaining() && bb.limit() - bb.position() > 2) {
+            byte subOptionCode = bb.get();
+            byte subOptionLen = bb.get();
+            byte[] subOptionData = new byte[subOptionLen];
+            try {
+                bb.get(subOptionData);
+            } catch (BufferUnderflowException e) {
+                log.warn("Malformed option82 sub-option {}", e.getMessage());
+                return;
+            }
+            if (subOptionCode == CIRCUIT_ID_CODE) {
+                agentCircuitId = new String(subOptionData);
+            } else if (subOptionCode == REMOTE_ID_CODE) {
+                agentRemoteId = new String(subOptionData);
+            } else {
+                log.debug("Unsupported subOption {} in DHCP option82 - {}",
+                          subOptionCode, new String(subOptionData));
+            }
+        }
+    }
+
+    public void setAgentCircuitId(String value) {
+        this.agentCircuitId = value;
+    }
+
+    public void setAgentCircuitId(byte[] subOptionData) {
+        agentCircuitId = new String(subOptionData);
+    }
+
+    /**
+     *
+     * @return agentCircuitId
+     */
+    public String getAgentCircuitId() {
+        return this.agentCircuitId;
+    }
+
+    /**
+     * sets AgentRemoteId.
+     * @param value   Value to be set
+     */
+    public void setAgentRemoteId(String value) {
+        this.agentRemoteId = value;
+    }
+
+    /**
+     *
+     * @return agentRemoteId
+     */
+    public String getAgentRemoteId() {
+        return this.agentRemoteId;
+    }
+
+    /**
+     *
+     * @return length of option 82.
+     */
+    public byte length() {
+        int length = 0;
+
+        // +2 below for sub option ID and length of sub option
+        if (agentCircuitId != null) {
+            length += agentCircuitId.length() + 2;
+        }
+        if (agentRemoteId != null) {
+            length += agentRemoteId.length() + 2;
+        }
+        return (byte) length;
+    }
+
+    /**
+     * Returns the representation of the option 82 specification as a byte
+     * array.
+     * @return returns byte array
+     */
+    public byte[] toByteArray() {
+        ByteArrayOutputStream buf = new ByteArrayOutputStream();
+
+        // Add sub option if set
+        if (agentCircuitId != null) {
+            buf.write(CIRCUIT_ID_CODE);
+            buf.write((byte) agentCircuitId.length());
+            byte[] bytes = agentCircuitId.getBytes(StandardCharsets.UTF_8);
+            buf.write(bytes, 0, bytes.length);
+        }
+
+        // Add sub option if set
+        if (agentRemoteId != null) {
+            buf.write(REMOTE_ID_CODE);
+            buf.write((byte) agentRemoteId.length());
+            byte[] bytes = agentRemoteId.getBytes(StandardCharsets.UTF_8);
+            buf.write(bytes, 0, bytes.length);
+        }
+
+        return buf.toByteArray();
+    }
+
+    @Override
+    public String toString() {
+        return "circuitId: " + agentCircuitId + " remoteId: " + agentRemoteId;
+    }
+
+}
diff --git a/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTest.java b/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTest.java
index c19b2eb..3e19917 100755
--- a/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTest.java
+++ b/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTest.java
@@ -16,19 +16,21 @@
 package org.opencord.dhcpl2relay.impl;
 
 import static org.easymock.EasyMock.createMock;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
-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.packet.DHCP;
+import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.MacAddress;
@@ -45,10 +47,11 @@
 import org.opencord.dhcpl2relay.DhcpAllocationInfo;
 import org.opencord.dhcpl2relay.DhcpL2RelayEvent;
 import org.opencord.dhcpl2relay.DhcpL2RelayStoreDelegate;
-import org.opencord.dhcpl2relay.impl.packet.DhcpOption82;
+import org.opencord.dhcpl2relay.impl.packet.DhcpOption82Data;
 import org.slf4j.Logger;
 
 import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.MoreExecutors;
 
 public class DhcpL2RelayTest extends DhcpL2RelayTestBase {
 
@@ -101,9 +104,9 @@
         dhcpL2Relay.deactivate();
     }
 
-    private void checkAllocation(DHCP.MsgType messageType) {
+    private void checkAllocation(DHCP.MsgType messageType, String circuitId) {
         ConnectPoint clientCp = ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/"
-                                                                        + String.valueOf(CLIENT_PORT));
+                                                + String.valueOf(CLIENT_PORT));
         allocs = dhcpL2Relay.getAllocationInfo();
         assertEquals(1, allocs.size());
         allocs.forEach((k, v) -> {
@@ -111,6 +114,7 @@
             assertEquals(v.type(), messageType);
             assertEquals(v.macAddress(), CLIENT_MAC);
             assertEquals(v.location(), clientCp);
+            assertEquals(v.circuitId(), circuitId);
         });
     }
 
@@ -175,7 +179,8 @@
     }
 
     /**
-     * Tests the DHCP relay app by sending DHCP discovery Packet.
+     * Tests the DHCP relay app by sending DHCP discovery Packet. The circuitId
+     * and remote-Id for this client is operator defined in MockSadis.
      *
      * @throws Exception when an unhandled error occurs
      */
@@ -185,12 +190,79 @@
         dhcpL2Relay.clearAllocations();
         Ethernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
         ConnectPoint clientCp = ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/"
-                                                                        + String.valueOf(CLIENT_PORT));
-        sendPacket(discoverPacket, clientCp);
+                                    + String.valueOf(CLIENT_PORT));
+        // send a copy of the packet as the app code modifies the sent packet
+        sendPacket(discoverPacket.duplicate(), clientCp);
 
         Ethernet discoverRelayed = (Ethernet) getPacket();
         compareClientPackets(discoverPacket, discoverRelayed);
-        checkAllocation(DHCP.MsgType.DHCPDISCOVER);
+        checkAllocation(DHCP.MsgType.DHCPDISCOVER, CLIENT_CIRCUIT_ID);
+    }
+
+    /**
+     * Tests the addition of app-defined circuit id, when this client's
+     * MockSadis config for circiutId is empty. The remoteId is configured.
+     *
+     * @throws Exception when an unhandled error occurs
+     */
+    @Test
+    public void testDhcpDiscoverEmptyCircuitId() throws Exception {
+        dhcpL2Relay.clearAllocations();
+        MacAddress mac32 = MacAddress.valueOf("b4:96:91:0c:4f:e4");
+        VlanId vlan32a = VlanId.vlanId((short) 801); // defined in mockSadis
+        VlanId qinq32a = VlanId.vlanId((short) 111);
+        Ethernet discover32a = constructDhcpDiscoverPacket(mac32, vlan32a,
+                                                           (short) 0);
+        ConnectPoint client32 = ConnectPoint
+                .deviceConnectPoint("of:0000b86a974385f7/32");
+        sendPacket(discover32a.duplicate(), client32);
+        Ethernet discoverRelayed = (Ethernet) getPacket();
+        // empty circuitId in sadis for client32 should result in app defined
+        // circuitId
+        String expectedCircuitId = client32 + ":vlan" + vlan32a + ":pcp-1";
+        compareClientPackets(discover32a, discoverRelayed,
+                             qinq32a, vlan32a, CLIENT_C_PBIT,
+                             expectedCircuitId,
+                             CLIENT_REMOTE_ID);
+        allocs = dhcpL2Relay.getAllocationInfo();
+        allocs.forEach((k, v) -> {
+            log.info("Allocation {} : {}", k, v);
+            assertEquals(v.circuitId(), expectedCircuitId);
+        });
+    }
+
+    /**
+     * Tests the addition of app-defined circuit id, when this client's
+     * MockSadis config for circuitId and remoteId are null. In addition, it
+     * tests that the configured downstream-pcp is included in the circuitId.
+     *
+     * @throws Exception when an unhandled error occurs
+     */
+    @Test
+    public void testDhcpDiscoverNullIds() throws Exception {
+        dhcpL2Relay.clearAllocations();
+        MacAddress mac4112 = MacAddress.valueOf("b4:96:91:0c:4f:c9");
+        VlanId vlan4112 = VlanId.vlanId((short) 101);
+        VlanId qinq4112 = VlanId.vlanId((short) 222);
+        Ethernet discover4112 = constructDhcpDiscoverPacket(mac4112, vlan4112,
+                                                            (short) 0);
+        ConnectPoint client4112 = ConnectPoint
+                .deviceConnectPoint("of:0000b86a974385f7/4112");
+        sendPacket(discover4112.duplicate(), client4112);
+        Ethernet discoverRelayed = (Ethernet) getPacket();
+        // null circuitId in sadis for client32 should result in app defined
+        // circuitId. remoteId should not be there. Correct downstream pbit
+        // should be used
+        String expectedCircuitId = client4112 + ":vlan" + vlan4112 + ":pcp5";
+        compareClientPackets(discover4112, discoverRelayed,
+                             qinq4112, vlan4112, CLIENT_C_PBIT,
+                             expectedCircuitId,
+                             null);
+        allocs = dhcpL2Relay.getAllocationInfo();
+        allocs.forEach((k, v) -> {
+            log.info("Allocation {} : {}", k, v);
+            assertEquals(v.circuitId(), expectedCircuitId);
+        });
     }
 
     /**
@@ -203,67 +275,96 @@
         // Sending DHCP Request packet
         Ethernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
         ConnectPoint clientCp = ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/"
-                                                                        + String.valueOf(CLIENT_PORT));
-        sendPacket(requestPacket, clientCp);
+                                                + String.valueOf(CLIENT_PORT));
+        sendPacket(requestPacket.duplicate(), clientCp);
 
         Ethernet requestRelayed = (Ethernet) getPacket();
         compareClientPackets(requestPacket, requestRelayed);
-        checkAllocation(DHCP.MsgType.DHCPREQUEST);
+        checkAllocation(DHCP.MsgType.DHCPREQUEST, CLIENT_CIRCUIT_ID);
     }
 
     /**
-     * Tests the DHCP relay app by sending DHCP Offer Packet.
+     * Tests the DHCP relay app by sending DHCP Offer Packet with app-defined
+     * circuit id. App should use the circuit id for forwarding.
      *
      * @throws Exception when an unhandled error occurs
      */
     @Test
     public void testDhcpOffer() throws InterruptedException {
         // Sending DHCP Offer packet
-        Ethernet offerPacket = constructDhcpOfferPacket(SERVER_MAC,
-                                                        CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
+        Ethernet offerPacket = constructDhcpOfferPacket(SERVER_MAC, CLIENT_MAC,
+                                                        DESTINATION_ADDRESS_IP,
+                                                        DHCP_CLIENT_IP_ADDRESS);
         sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/"
-                                                                        + String.valueOf(UPLINK_PORT)));
+                                         + String.valueOf(UPLINK_PORT)));
 
         Ethernet offerRelayed = (Ethernet) getPacket();
         compareServerPackets(offerPacket, offerRelayed);
-        checkAllocation(DHCP.MsgType.DHCPOFFER);
+        String expectedCircuitId = OLT_DEV_ID + "/" + CLIENT_PORT + ":vlan"
+                + CLIENT_C_TAG + ":pcp" + CLIENT_C_PBIT;
+        checkAllocation(DHCP.MsgType.DHCPOFFER, expectedCircuitId);
     }
 
     /**
-     * Tests the DHCP relay app by sending DHCP Ack Packet.
+     * Tests the DHCP relay app by sending DHCP Ack Packet with operator defined
+     * circuit id. App should ignore circuit Id and do a host lookup.
      *
      * @throws Exception when an unhandled error occurs
      */
     @Test
     public void testDhcpAck() throws InterruptedException {
 
-        Ethernet ackPacket = constructDhcpAckPacket(SERVER_MAC,
-                                                    CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
+        Ethernet ackPacket = constructDhcpAckPacket(SERVER_MAC, CLIENT_MAC,
+                                                    DESTINATION_ADDRESS_IP,
+                                                    DHCP_CLIENT_IP_ADDRESS);
 
         sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/"
-                                                                      + String.valueOf(UPLINK_PORT)));
+                                                + String.valueOf(UPLINK_PORT)));
 
         Ethernet ackRelayed = (Ethernet) getPacket();
         compareServerPackets(ackPacket, ackRelayed);
-        checkAllocation(DHCP.MsgType.DHCPACK);
+        checkAllocation(DHCP.MsgType.DHCPACK, CLIENT_CIRCUIT_ID);
     }
 
     /**
      * Tests the DHCP relay app by sending DHCP Nak Packet.
+     * Tests app-defined option82, but uses incorrect connectPoint - packet
+     * should still be forwarded to this connectPoint (ie without host lookup).
+     * Also pbit in circuitId is -1, which means original pbit should be retained
      *
      * @throws Exception when an unhandled error occurs
      */
     @Test
     public void testDhcpNak() throws InterruptedException {
+        VlanId fakeVlan = VlanId.vlanId((short) 50);
+        short fakePcp = (short) 4; // should be retained
+        VlanId expectedVlan = VlanId.vlanId((short) 111);
+        // relayed packet should have vlan 111 and retain pcp4 and be sent out
+        // of port32
+        ConnectPoint fakeCp = ConnectPoint.fromString("of:0000b86a974385f7/32");
+        String fakeCircuitId = fakeCp + ":vlan"
+                + expectedVlan + ":pcp-1";
+        Ethernet nakPacket = constructDhcpNakPacket(SERVER_MAC, CLIENT_MAC,
+                                                    DESTINATION_ADDRESS_IP,
+                                                    DHCP_CLIENT_IP_ADDRESS,
+                                                    fakeVlan,
+                                                    fakePcp);
 
-        Ethernet nakPacket = constructDhcpNakPacket(SERVER_MAC,
-                                                    CLIENT_MAC, DESTINATION_ADDRESS_IP, DHCP_CLIENT_IP_ADDRESS);
-
-        sendPacket(nakPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
+        sendPacket(nakPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/"
+                                                + String.valueOf(UPLINK_PORT)));
 
         Ethernet nakRelayed = (Ethernet) getPacket();
-        compareServerPackets(nakPacket, nakRelayed);
-        checkAllocation(DHCP.MsgType.DHCPNAK);
+        compareServerPackets(nakPacket, nakRelayed, expectedVlan, fakePcp);
+
+        allocs = dhcpL2Relay.getAllocationInfo();
+        assertEquals(1, allocs.size());
+        allocs.forEach((k, v) -> {
+            log.info("Allocation {} : {}", k, v);
+            assertEquals(v.type(), DHCP.MsgType.DHCPNAK);
+            assertEquals(v.macAddress(), CLIENT_MAC);
+            assertEquals(v.location(), fakeCp);
+            assertEquals(v.circuitId(), fakeCircuitId);
+        });
     }
 
     /**
@@ -276,11 +377,12 @@
 
         Ethernet declinePacket = constructDhcpDeclinePacket(CLIENT_MAC);
 
-        sendPacket(declinePacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
+        sendPacket(declinePacket.duplicate(),
+                   ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
 
         Ethernet declineRelayed = (Ethernet) getPacket();
         compareClientPackets(declinePacket, declineRelayed);
-        checkAllocation(DHCP.MsgType.DHCPDECLINE);
+        checkAllocation(DHCP.MsgType.DHCPDECLINE, CLIENT_CIRCUIT_ID);
     }
 
     /**
@@ -352,18 +454,31 @@
     }
 
     public void compareClientPackets(Ethernet sent, Ethernet relayed) {
-        sent.setSourceMACAddress(OLT_MAC_ADDRESS);
-        sent.setQinQVID(CLIENT_S_TAG.toShort());
-        sent.setVlanID(CLIENT_C_TAG.toShort());
-        sent.setPriorityCode((byte) CLIENT_C_PBIT);
+        compareClientPackets(sent, relayed, CLIENT_S_TAG, CLIENT_C_TAG,
+                             CLIENT_C_PBIT, CLIENT_CIRCUIT_ID,
+                             CLIENT_REMOTE_ID);
+    }
+
+    public void compareClientPackets(Ethernet sent, Ethernet relayed,
+                                     VlanId expectedQinQ,
+                                     VlanId expectedVlan, short expectedPcp,
+                                     String expectedCircuitId,
+                                     String expectedRemoteId) {
+        // convert the sent packet to the expected relayed packet
+        sent.setSourceMACAddress(OLT_MAC_ADDRESS); // due to netconfig test in setup
+        sent.setQinQVID(expectedQinQ.toShort());
+        sent.setQinQTPID((short) 0x8100);
+        sent.setVlanID(expectedVlan.toShort());
+        sent.setPriorityCode((byte) expectedPcp);
 
         IPv4 ipv4Packet = (IPv4) sent.getPayload();
         UDP udpPacket = (UDP) ipv4Packet.getPayload();
         DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
-
         List<DhcpOption> options = Lists.newArrayList(dhcpPacket.getOptions());
-        DhcpOption82 option82 = new DhcpOption82();
-        option82.setAgentCircuitId(CLIENT_CIRCUIT_ID);
+
+        DhcpOption82Data option82 = new DhcpOption82Data();
+        option82.setAgentCircuitId(expectedCircuitId);
+        option82.setAgentRemoteId(expectedRemoteId);
 
         DhcpOption option = new DhcpOption()
                 .setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
@@ -372,17 +487,54 @@
 
         options.add(options.size() - 1, option);
         dhcpPacket.setOptions(options);
-        assertEquals(sent, relayed);
 
+        byte[] sb = sent.serialize();
+        Ethernet expectedPacket = null;
+        try {
+            expectedPacket = Ethernet.deserializer()
+                    .deserialize(sb, 0, sb.length);
+        } catch (DeserializationException e) {
+            log.error("exeption: {}", e.getMessage());
+            fail();
+        }
+        verifyDhcpOptions(expectedPacket, relayed);
+        assertEquals(expectedPacket, relayed);
+    }
+
+    public void verifyDhcpOptions(Ethernet expected, Ethernet relayed) {
+        DHCP de = ((DHCP) ((UDP) ((IPv4) expected.getPayload()).getPayload())
+                .getPayload());
+        DHCP dr = ((DHCP) ((UDP) ((IPv4) relayed.getPayload()).getPayload())
+                .getPayload());
+        List<DhcpOption> del = de.getOptions();
+        List<DhcpOption> der = dr.getOptions();
+        assertEquals(del.size(), der.size());
+        for (int i = 0; i < del.size(); i++) {
+            assertEquals(del.get(i), der.get(i));
+        }
     }
 
     public void compareServerPackets(Ethernet sent, Ethernet relayed) {
+        compareServerPackets(sent, relayed, CLIENT_C_TAG, CLIENT_C_PBIT);
+    }
 
+    public void compareServerPackets(Ethernet sent, Ethernet relayed,
+                                     VlanId expectedVlan, short expectedPcp) {
         try {
+            // modify sent packet to create expected packet
             sent.setDestinationMACAddress(CLIENT_MAC);
             sent.setQinQVID(NOT_PROVIDED);
             sent.setQinQPriorityCode((byte) NOT_PROVIDED);
-            sent.setVlanID(CLIENT_C_TAG.toShort());
+            sent.setVlanID(expectedVlan.toShort());
+            sent.setPriorityCode((byte) expectedPcp);
+            DHCP d = ((DHCP) ((UDP) ((IPv4) sent.getPayload()).getPayload())
+                    .getPayload());
+            List<DhcpOption> newOptions = d.getOptions().stream()
+                    .filter(option -> option
+                            .getCode() != DHCP.DHCPOptionCode.OptionCode_CircuitID
+                                    .getValue())
+                    .collect(Collectors.toList());
+            d.setOptions(newOptions);
 
             final ByteBuffer byteBuffer = ByteBuffer.wrap(sent.serialize());
             Ethernet expectedPacket = Ethernet.deserializer().deserialize(byteBuffer.array(),
diff --git a/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java b/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java
index 20ac9f5..df480a7 100755
--- a/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java
+++ b/app/src/test/java/org/opencord/dhcpl2relay/impl/DhcpL2RelayTestBase.java
@@ -80,6 +80,7 @@
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
+import org.opencord.dhcpl2relay.impl.packet.DhcpOption82Data;
 import org.opencord.sadis.BandwidthProfileInformation;
 import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SadisService;
@@ -108,6 +109,9 @@
     static final String CLIENT_ID_1 = "SUBSCRIBER_ID_1";
     static final String CLIENT_NAS_PORT_ID = "PON 1/1";
     static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
+    static final String CLIENT32_CIRCUIT_ID = "";
+    static final String CLIENT4112_CIRCUIT_ID = null;
+    public static final String CLIENT_REMOTE_ID = "I am an RG";
     static final short NOT_PROVIDED = 0;
 
     static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
@@ -131,6 +135,7 @@
     static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
             .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
 
+
     List<BasePacket> savedPackets = new LinkedList<>();
     PacketProcessor packetProcessor;
 
@@ -329,10 +334,10 @@
                         CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
         DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation sub32 =
                 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation("ALPHe3d1cea3-1", VlanId.vlanId((short) 801),
-                        VlanId.vlanId((short) 111), CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
+                        VlanId.vlanId((short) 111), CLIENT_NAS_PORT_ID, CLIENT32_CIRCUIT_ID, null, null, -1);
         DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation sub4112 =
                 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation("ALPHe3d1ceb7-1", VlanId.vlanId((short) 101),
-                        VlanId.vlanId((short) 222), CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
+                        VlanId.vlanId((short) 222), CLIENT_NAS_PORT_ID, CLIENT4112_CIRCUIT_ID, null, null, -1);
         @Override
         public SubscriberAndDeviceInformation get(String id) {
             if (id.equals(OLT_DEV_ID)) {
@@ -368,22 +373,29 @@
             this.setId(id);
             this.setIPAddress(ipAddress);
             this.setNasPortId(nasPortId);
-            this.setCircuitId(circuitId);
             this.setUplinkPort(uplinkPort);
+            this.setCircuitId(circuitId);
 
             List<UniTagInformation> uniTagInformationList = new ArrayList<>();
 
-            UniTagInformation uniTagInformation = new UniTagInformation.Builder()
+            UniTagInformation.Builder b = new UniTagInformation.Builder()
                     .setPonCTag(cTag)
                     .setPonSTag(sTag)
                     .setUsPonCTagPriority(CLIENT_C_PBIT)
-                    .setIsDhcpRequired(true)
-                    .build();
-            uniTagInformationList.add(uniTagInformation);
+                    .setIsDhcpRequired(true);
+
+            if (id.equals("ALPHe3d1ceb7-1")) {
+                // null remoteId, ds pbit is defined
+                b.setDsPonCTagPriority(5);
+            } else {
+                this.setRemoteId(CLIENT_REMOTE_ID);
+            }
+
+            uniTagInformationList.add(b.build());
 
             if (id.equals("ALPHe3d1cea3-1")) {
                 // a second service on the same UNI
-                uniTagInformation = new UniTagInformation.Builder()
+                UniTagInformation uniTagInformation = new UniTagInformation.Builder()
                         .setPonCTag(VlanId.vlanId(((short) (cTag.toShort() + 1))))
                         .setPonSTag(sTag)
                         .setUsPonCTagPriority(CLIENT_C_PBIT)
@@ -720,14 +732,16 @@
      */
     Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
         Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
-                "255.255.255.255", DHCP.OPCODE_REQUEST, clientMac,
-                Ip4Address.valueOf("0.0.0.0"));
+                                              "255.255.255.255",
+                                              DHCP.OPCODE_REQUEST, clientMac,
+                                              Ip4Address.valueOf("0.0.0.0"));
 
         IPv4 ipv4Packet = (IPv4) pkt.getPayload();
         UDP udpPacket = (UDP) ipv4Packet.getPayload();
         DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
 
         dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPDISCOVER));
+        log.info("Sending discover packet {}", dhcpPacket.getOptions());
 
         return pkt;
     }
@@ -748,7 +762,6 @@
         DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
 
         dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPDISCOVER));
-
         return pkt;
     }
 
@@ -786,7 +799,7 @@
         DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
 
         dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPOFFER));
-
+        log.info("Sending offer packet {}", dhcpPacket.getOptions());
         return pkt;
     }
 
@@ -815,10 +828,13 @@
      * @return Ethernet packet
      */
     Ethernet constructDhcpNakPacket(MacAddress servMac, MacAddress clientMac,
-                                    String ipAddress, String dhcpClientIpAddress) {
+                                    String ipAddress, String dhcpClientIpAddress,
+                                    VlanId clientVlan, short clientPcp) {
 
-        Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
-                clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
+        Ethernet pkt = constructEthernetPacket(servMac, clientMac, ipAddress,
+                                DHCP.OPCODE_REPLY, clientMac,
+                                Ip4Address.valueOf(dhcpClientIpAddress),
+                                clientVlan, clientPcp);
 
         IPv4 ipv4Packet = (IPv4) pkt.getPayload();
         UDP udpPacket = (UDP) ipv4Packet.getPayload();
@@ -876,6 +892,47 @@
         option.setData(optionData);
         optionList.add(option);
 
+        // Tests app defined Option82
+        if (packetType.equals(DHCP.MsgType.DHCPOFFER)) {
+            option = new DhcpOption();
+            option.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+            DhcpOption82Data option82 = new DhcpOption82Data();
+            option82.setAgentCircuitId(OLT_DEV_ID + "/" + CLIENT_PORT + ":vlan"
+                    + CLIENT_C_TAG + ":pcp" + CLIENT_C_PBIT);
+            option82.setAgentRemoteId("bababababa");
+            option.setData(option82.toByteArray());
+            option.setLength(option82.length());
+            log.info("Added option82 {}", option);
+            optionList.add(option);
+        }
+        // Tests operator configured Option82, resulting in host lookup
+        if (packetType.equals(DHCP.MsgType.DHCPACK)) {
+            option = new DhcpOption();
+            option.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+            DhcpOption82Data option82 = new DhcpOption82Data();
+            option82.setAgentCircuitId(CLIENT_CIRCUIT_ID);
+            option82.setAgentRemoteId(CLIENT_REMOTE_ID);
+            option.setData(option82.toByteArray());
+            option.setLength(option82.length());
+            log.info("Added option82 {}", option);
+            optionList.add(option);
+        }
+        // Tests app-defined option82, but uses incorrect connectPoint - packet
+        // should still be forwarded to this connectPoint (ie without host lookup).
+        // Also pbit in circuitId is -1, which means original pbit should be retained
+        // Finally remoteId is missing
+        if (packetType.equals(DHCP.MsgType.DHCPNAK)) {
+            option = new DhcpOption();
+            option.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+            DhcpOption82Data option82 = new DhcpOption82Data();
+            option82.setAgentCircuitId("of:0000b86a974385f7/32" + ":vlan"
+                    + VlanId.vlanId((short) 111) + ":pcp-1");
+            option.setData(option82.toByteArray());
+            option.setLength(option82.length());
+            log.info("Added option82 {}", option);
+            optionList.add(option);
+        }
+
         // End Option.
         option = new DhcpOption();
         option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
