diff --git a/src/main/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManager.java
index ed57586..33dbf57 100644
--- a/src/main/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -27,6 +27,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -67,7 +68,9 @@
 import net.onrc.onos.core.packet.IPv4;
 import net.onrc.onos.core.packet.LLDP;
 import net.onrc.onos.core.packet.LLDPTLV;
+import net.onrc.onos.core.packet.OnosLldp;
 import net.onrc.onos.core.registry.IControllerRegistryService;
+import net.onrc.onos.core.util.SwitchPort;
 
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
@@ -81,13 +84,14 @@
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.protocol.action.OFActionType;
 import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * This class sends out LLDP messages containing the sending switch's datapath
- * id as well as the outgoing port number.  Received LLrescDP messages that
+ * id as well as the outgoing port number.  Received LLDP messages that
  * match a known switch cause a new LinkTuple to be created according to the
  * invariant rules listed below.  This new LinkTuple is also passed to routing
  * if it exists to trigger updates.
@@ -252,7 +256,7 @@
     /**
      * Quarantine task.
      */
-    protected SingletonTask bddpTask;
+    //protected SingletonTask bddpTask;
     protected static final int BDDP_TASK_INTERVAL = 100; // 100 ms.
     protected static final int BDDP_TASK_SIZE = 5;       // # of ports per iteration
 
@@ -352,6 +356,7 @@
     /**
      * Quarantine Ports.
      */
+    /*
     protected class QuarantineWorker implements Runnable {
         @Override
         public void run() {
@@ -365,6 +370,7 @@
             }
         }
     }
+    */
 
     /**
      * Add a switch port to the quarantine queue. Schedule the
@@ -604,89 +610,8 @@
                     sw, port);
         }
 
-        // using "nearest customer bridge" MAC address for broadest possible propagation
-        // through provider and TPMR bridges (see IEEE 802.1AB-2009 and 802.1Q-2011),
-        // in particular the Linux bridge which behaves mostly like a provider bridge
-        byte[] chassisId = new byte[]{4, 0, 0, 0, 0, 0, 0}; // filled in later
-        byte[] portId = new byte[]{2, 0, 0}; // filled in later
-        byte[] ttlValue = new byte[]{0, 0x78};
-        // OpenFlow OUI - 00-26-E1
-        byte[] dpidTLVValue = new byte[]{0x0, 0x26, (byte) 0xe1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+        OFPacketOut po = createLLDPPacketOut(sw, ofpPort, isReverse);
 
-        byte[] dpidArray = new byte[8];
-        ByteBuffer dpidBB = ByteBuffer.wrap(dpidArray);
-        ByteBuffer portBB = ByteBuffer.wrap(portId, 1, 2);
-
-        Long dpid = sw;
-        dpidBB.putLong(dpid);
-        // set the ethernet source mac to last 6 bytes of dpid
-        byte[] hardwareAddress = new byte[6];
-        System.arraycopy(dpidArray, 2, hardwareAddress, 0, 6);
-        ofpPort.setHardwareAddress(hardwareAddress);
-        // set the chassis id's value to last 6 bytes of dpid
-        System.arraycopy(dpidArray, 2, chassisId, 1, 6);
-        // set the optional tlv to the full dpid
-        System.arraycopy(dpidArray, 0, dpidTLVValue, 4, 8);
-        LLDPTLV dpidTLV = new LLDPTLV().setType((byte) 127)
-                .setLength((short) dpidTLVValue.length).setValue(dpidTLVValue);
-
-        // set the portId to the outgoing port
-        portBB.putShort(port);
-        if (log.isTraceEnabled()) {
-            log.trace("Sending LLDP out of interface: {}/{}",
-                    HexString.toHexString(sw), port);
-        }
-
-        LLDP lldp = new LLDP();
-        lldp.setChassisId(new LLDPTLV().setType((byte) 1).setLength((short) chassisId.length).setValue(chassisId));
-        lldp.setPortId(new LLDPTLV().setType((byte) 2).setLength((short) portId.length).setValue(portId));
-        lldp.setTtl(new LLDPTLV().setType((byte) 3).setLength((short) ttlValue.length).setValue(ttlValue));
-        lldp.getOptionalTLVList().add(dpidTLV);
-
-        // Add the controller identifier to the TLV value.
-        lldp.getOptionalTLVList().add(controllerTLV);
-        if (isReverse) {
-            lldp.getOptionalTLVList().add(REVERSE_TLV);
-        } else {
-            lldp.getOptionalTLVList().add(FORWARD_TLV);
-        }
-
-        Ethernet ethernet;
-        if (isStandard) {
-            ethernet = new Ethernet()
-                    .setSourceMACAddress(ofpPort.getHardwareAddress())
-                    .setDestinationMACAddress(LLDP_STANDARD_DST_MAC_STRING)
-                    .setEtherType(Ethernet.TYPE_LLDP);
-            ethernet.setPayload(lldp);
-        } else {
-            BSN bsn = new BSN(BSN.BSN_TYPE_BDDP);
-            bsn.setPayload(lldp);
-
-            ethernet = new Ethernet()
-                    .setSourceMACAddress(ofpPort.getHardwareAddress())
-                    .setDestinationMACAddress(LLDP_BSN_DST_MAC_STRING)
-                    .setEtherType(Ethernet.TYPE_BSN);
-            ethernet.setPayload(bsn);
-        }
-
-
-        // serialize and wrap in a packet out
-        byte[] data = ethernet.serialize();
-        OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
-        po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
-        po.setInPort(OFPort.OFPP_NONE);
-
-        // set actions
-        List<OFAction> actions = new ArrayList<OFAction>();
-        actions.add(new OFActionOutput(port, (short) 0));
-        po.setActions(actions);
-        po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-
-        // set data
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLength() + data.length);
-        po.setPacketData(data);
-
-        // send
         try {
             iofSwitch.write(po, null);
             iofSwitch.flush();
@@ -697,6 +622,51 @@
     }
 
     /**
+     * Creates packet_out LLDP for specified output port.
+     *
+     * @param dpid the dpid of the outgoing switch
+     * @param port the outgoing port
+     * @param isReverse whether this is a reverse LLDP or not
+     * @return Packet_out message with LLDP data
+     */
+    private OFPacketOut createLLDPPacketOut(long dpid,
+            final OFPhysicalPort port, boolean isReverse) {
+        // Set up packets
+        // TODO optimize by not creating new packets each time
+        OnosLldp lldpPacket = new OnosLldp();
+
+        Ethernet ethPacket = new Ethernet();
+        ethPacket.setEtherType(Ethernet.TYPE_LLDP);
+        ethPacket.setDestinationMACAddress(LLDP_STANDARD_DST_MAC_STRING);
+        ethPacket.setPayload(lldpPacket);
+        ethPacket.setPad(true);
+
+        final OFPacketOut packetOut = (OFPacketOut) floodlightProvider.getOFMessageFactory()
+                .getMessage(OFType.PACKET_OUT);
+        packetOut.setBufferId(OFPacketOut.BUFFER_ID_NONE);
+
+        final List<OFAction> actionsList = new LinkedList<OFAction>();
+        final OFActionOutput out = (OFActionOutput) floodlightProvider.getOFMessageFactory()
+                .getAction(OFActionType.OUTPUT);
+        out.setPort(port.getPortNumber());
+        actionsList.add(out);
+        packetOut.setActions(actionsList);
+        final short alen = (short) OFActionOutput.MINIMUM_LENGTH;
+
+        lldpPacket.setSwitch(dpid);
+        lldpPacket.setPort(port.getPortNumber());
+        lldpPacket.setReverse(isReverse);
+        ethPacket.setSourceMACAddress(port.getHardwareAddress());
+
+        final byte[] lldp = ethPacket.serialize();
+        packetOut.setActionsLength(alen);
+        packetOut.setPacketData(lldp);
+        packetOut
+                .setLength((short) (OFPacketOut.MINIMUM_LENGTH + alen + lldp.length));
+        return packetOut;
+    }
+
+    /**
      * Send LLDPs to all switch-ports.
      */
     protected void discoverOnAllPorts() {
@@ -724,8 +694,8 @@
 
                     // If the switch port is not alreayd in the maintenance
                     // queue, add it.
-                    NodePortTuple npt = new NodePortTuple(sw, ofp.getPortNumber());
-                    addToMaintenanceQueue(npt);
+                    //NodePortTuple npt = new NodePortTuple(sw, ofp.getPortNumber());
+                    //addToMaintenanceQueue(npt);
                 }
             }
         }
@@ -812,18 +782,8 @@
             return Command.CONTINUE;
         }
 
-        long myId = ByteBuffer.wrap(controllerTLV.getValue()).getLong();
-        long otherId = 0;
-        boolean myLLDP = false;
-        Boolean isReverse = null;
-
-        ByteBuffer portBB = ByteBuffer.wrap(lldp.getPortId().getValue());
-        portBB.position(1);
-
-        Short remotePort = portBB.getShort();
-        IOFSwitch remoteSwitch = null;
-
         // Verify this LLDP packet matches what we're looking for
+        /*
         for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
             if (lldptlv.getType() == 127 && lldptlv.getLength() == 12 &&
                     lldptlv.getValue()[0] == 0x0 && lldptlv.getValue()[1] == 0x26 &&
@@ -850,66 +810,37 @@
                 }
             }
         }
+        */
 
-        if (!myLLDP) {
-            // This is not the LLDP sent by this controller.
-            // If the LLDP message has multicast bit set, then we need to broadcast
-            // the packet as a regular packet.
-            if (isStandard) {
-                if (log.isTraceEnabled()) {
-                    log.trace("Getting standard LLDP from a different controller and quelching it.");
-                }
-                return Command.STOP;
-            }
-            // XXX ONOS: Don't disregard any BDDP messages from other
-            // controllers because they're used for inter-instance link detection
-
-            /*else if (sw <= remoteSwitch.getId()) {
-                if (log.isTraceEnabled()) {
-                    log.trace("Getting BBDP from a different controller. myId {}: remoteId {}", myId, otherId);
-                    log.trace("and my controller id is smaller than the other, so quelching it. myPort {}: rPort {}",
-                    pi.getInPort(), remotePort);
-                }
-                //XXX ONOS: Fix the BDDP broadcast issue
-                //return Command.CONTINUE;
-                return Command.STOP;
-            }*/
-            /*
-            else if (myId < otherId)  {
-                if (log.isTraceEnabled()) {
-                    log.trace("Getting BDDP packets from a different controller" +
-                            "and letting it go through normal processing chain.");
-                }
-                //XXX ONOS: Fix the BDDP broadcast issue
-                //return Command.CONTINUE;
-                return Command.STOP;
-            }
-            */
-        }
-
-
-        if (remoteSwitch == null) {
-            // Ignore LLDPs not generated by Floodlight, or from a switch that has recently
-            // disconnected, or from a switch connected to another Floodlight instance
-            if (log.isTraceEnabled()) {
-                log.trace("Received LLDP from remote switch not connected to the controller");
-            }
+        byte[] packetData = pi.getPacketData();
+        if (!OnosLldp.isOnosLldp(packetData)) {
+            log.trace("Dropping LLDP that wasn't sent by ONOS");
             return Command.STOP;
         }
 
-        if (!remoteSwitch.portEnabled(remotePort)) {
-            if (log.isTraceEnabled()) {
-                log.trace("Ignoring link with disabled source port: switch {} port {}", remoteSwitch, remotePort);
+        SwitchPort switchPort = OnosLldp.extractSwitchPort(packetData);
+        long remoteDpid = switchPort.dpid().value();
+        short remotePort = switchPort.port().value();
+        IOFSwitch remoteSwitch = floodlightProvider.getSwitches().get(switchPort.dpid().value());
+
+
+        OFPhysicalPort physicalPort = null;
+        if (remoteSwitch != null) {
+            physicalPort = remoteSwitch.getPort(remotePort);
+            if (!remoteSwitch.portEnabled(remotePort)) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Ignoring link with disabled source port: switch {} port {}", remoteSwitch, remotePort);
+                }
+                return Command.STOP;
             }
-            return Command.STOP;
-        }
-        if (suppressLinkDiscovery.contains(new NodePortTuple(remoteSwitch.getId(),
-                remotePort))) {
-            if (log.isTraceEnabled()) {
-                log.trace("Ignoring link with suppressed src port: switch {} port {}",
-                        remoteSwitch, remotePort);
+            if (suppressLinkDiscovery.contains(new NodePortTuple(remoteSwitch.getId(),
+                    remotePort))) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Ignoring link with suppressed src port: switch {} port {}",
+                            remoteSwitch, remotePort);
+                }
+                return Command.STOP;
             }
-            return Command.STOP;
         }
         if (!iofSwitch.portEnabled(pi.getInPort())) {
             if (log.isTraceEnabled()) {
@@ -918,13 +849,12 @@
             return Command.STOP;
         }
 
-        OFPhysicalPort physicalPort = remoteSwitch.getPort(remotePort);
         int srcPortState = (physicalPort != null) ? physicalPort.getState() : 0;
         physicalPort = iofSwitch.getPort(pi.getInPort());
         int dstPortState = (physicalPort != null) ? physicalPort.getState() : 0;
 
         // Store the time of update to this link, and push it out to routingEngine
-        Link lt = new Link(remoteSwitch.getId(), remotePort, iofSwitch.getId(), pi.getInPort());
+        Link lt = new Link(remoteDpid, remotePort, iofSwitch.getId(), pi.getInPort());
 
 
         Long lastLldpTime = null;
@@ -949,6 +879,8 @@
         // first seen within a small interval, send probe on the
         // reverse link.
 
+        boolean isReverse = OnosLldp.isReverse(lldp);
+
         newLinkInfo = links.get(lt);
         if (newLinkInfo != null && isStandard && !isReverse) {
             Link reverseLink = new Link(lt.getDst(), lt.getDstPort(),
@@ -962,37 +894,6 @@
             }
         }
 
-        // XXX ONOS: Don't do this:
-        //   If the received packet is a BDDP packet, then create a reverse BDDP
-        //   link as well.
-        // We want to preserve our semantic of the instance that controls the
-        // destination switch is the one who adds the link to the database.
-        /*
-        if (!isStandard) {
-            Link reverseLink = new Link(lt.getDst(), lt.getDstPort(),
-                    lt.getSrc(), lt.getSrcPort());
-
-            // srcPortState and dstPort state are reversed.
-            LinkInfo reverseInfo =
-                    new LinkInfo(firstSeenTime, lastLldpTime, lastBddpTime,
-                            dstPortState, srcPortState);
-
-            addOrUpdateLink(reverseLink, reverseInfo);
-        }
-        */
-
-        // Remove the node ports from the quarantine and maintenance queues.
-        NodePortTuple nptSrc = new NodePortTuple(lt.getSrc(), lt.getSrcPort());
-        NodePortTuple nptDst = new NodePortTuple(lt.getDst(), lt.getDstPort());
-        removeFromQuarantineQueue(nptSrc);
-        removeFromQuarantineQueue(nptDst);
-
-        // XXX ONOS: Don't remove the port from the maintenance queue here
-        // because it sometimes prevents BDDPs from being sent and causes
-        // links to flap
-        // removeFromMaintenanceQueue(nptSrc);
-        // removeFromMaintenanceQueue(nptDst);
-
         // Consume this message
         return Command.STOP;
     }
@@ -1772,8 +1673,8 @@
 
         // Setup the BDDP task.  It is invoked whenever switch port tuples
         // are added to the quarantine list.
-        bddpTask = new SingletonTask(ses, new QuarantineWorker());
-        bddpTask.reschedule(BDDP_TASK_INTERVAL, TimeUnit.MILLISECONDS);
+        //bddpTask = new SingletonTask(ses, new QuarantineWorker());
+        //bddpTask.reschedule(BDDP_TASK_INTERVAL, TimeUnit.MILLISECONDS);
 
 
         // Register for the OpenFlow messages we want to receive
diff --git a/src/main/java/net/onrc/onos/core/packet/LLDPTLV.java b/src/main/java/net/onrc/onos/core/packet/LLDPTLV.java
index 262cb24..d5bb7fb 100644
--- a/src/main/java/net/onrc/onos/core/packet/LLDPTLV.java
+++ b/src/main/java/net/onrc/onos/core/packet/LLDPTLV.java
@@ -1,18 +1,33 @@
+/*******************************************************************************
+ * Copyright 2014 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.
+ ******************************************************************************/
 /**
- *    Copyright 2011, Big Switch Networks, Inc.
- *    Originally created by David Erickson, Stanford University
+ * Copyright 2011, Big Switch Networks, Inc.
+ * Originally created by David Erickson, Stanford University
  *
- *    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
+ * 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
+ * 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.
+ * 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 net.onrc.onos.core.packet;
@@ -20,8 +35,6 @@
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 
-import org.apache.commons.lang.ArrayUtils;
-
 // CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
 /**
  * @author David Erickson (daviderickson@cs.stanford.edu)
@@ -65,14 +78,14 @@
      * @return the value
      */
     public byte[] getValue() {
-        return ArrayUtils.clone(this.value);
+        return Arrays.copyOf(value, value.length);
     }
 
     /**
      * @param value the value to set
      */
     public LLDPTLV setValue(byte[] value) {
-        this.value = ArrayUtils.clone(value);
+        this.value = Arrays.copyOf(value, value.length);
         return this;
     }
 
@@ -107,7 +120,9 @@
         return this;
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see java.lang.Object#hashCode()
      */
     @Override
@@ -120,7 +135,9 @@
         return result;
     }
 
-    /* (non-Javadoc)
+    /*
+     * (non-Javadoc)
+     *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
diff --git a/src/main/java/net/onrc/onos/core/packet/OnosLldp.java b/src/main/java/net/onrc/onos/core/packet/OnosLldp.java
new file mode 100644
index 0000000..7a53f0b
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/packet/OnosLldp.java
@@ -0,0 +1,454 @@
+/*******************************************************************************
+ * Copyright 2014 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 net.onrc.onos.core.packet;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import net.onrc.onos.core.util.SwitchPort;
+
+import org.apache.commons.lang.ArrayUtils;
+
+import com.google.common.base.Charsets;
+
+/**
+ * LLDP packets ONOS uses for discovery of physical network topology.
+ * Refer to IEEE Std 802.1ABTM-2009 for more information.
+ *
+ */
+public class OnosLldp extends LLDP {
+
+    // ON.Lab OUI and ONOS name for organizationally specific TLVs
+    static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05};
+    public static final String ONOS_NAME = "ONOSVirteX";
+    static final byte[] LLDP_NICIRA = {0x01, 0x23, 0x20, 0x00, 0x00,
+            0x01};
+    static final byte[] LLDP_MULTICAST = {0x01, (byte) 0x80,
+            (byte) 0xc2, 0x00, 0x00, 0x0e};
+    static final byte[] BDDP_MULTICAST = {(byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+    public static final short ETHERTYPE_VLAN = (short) 0x8100;
+
+    // TLV constants: type, size and subtype
+    // Organizationally specific TLV also have packet offset and contents of TLV
+    // header
+    private static final byte CHASSIS_TLV_TYPE = 1;
+    private static final byte CHASSIS_TLV_SIZE = 7;
+    private static final byte CHASSIS_TLV_SUBTYPE = 4;
+
+    private static final byte PORT_TLV_TYPE = 2;
+    private static final byte PORT_TLV_SIZE = 3;
+    private static final byte PORT_TLV_SUBTYPE = 2;
+
+    private static final byte TTL_TLV_TYPE = 3;
+    private static final byte TTL_TLV_SIZE = 2;
+
+    private static final byte NAME_TLV_TYPE = 127;
+    // 4 = OUI (3) + subtype (1)
+    private static final byte NAME_TLV_SIZE = (byte) (4 + OnosLldp.ONOS_NAME.length());
+    private static final byte NAME_TLV_SUBTYPE = 1;
+    private static final short NAME_TLV_OFFSET = 32;
+    private static final short NAME_TLV_HEADER = (short) ((NAME_TLV_TYPE << 9) | (NAME_TLV_SIZE & 0xff));
+    // Contents of full name TLV
+    private static final byte[] NAME_TLV = ByteBuffer.allocate(NAME_TLV_SIZE + 2)
+            .putShort(NAME_TLV_HEADER).put(ONLAB_OUI).put(NAME_TLV_SUBTYPE)
+            .put(ONOS_NAME.getBytes(Charsets.UTF_8)).array();
+
+    private static final byte DPID_TLV_TYPE = 127;
+    private static final byte DPID_TLV_SIZE = (byte) (12); // 12 = OUI (3) + subtype
+                                                     // (1) + dpid (8)
+    private static final byte DPID_TLV_SUBTYPE = 2;
+    private static final short DPID_TLV_HEADER = (short) ((DPID_TLV_TYPE << 9) | DPID_TLV_SIZE);
+    // Contents of dpid TLV
+    // Note that this does *not* contain the actual dpid since we cannot match
+    // on it
+    private static final byte[] DPID_TLV = ByteBuffer.allocate(DPID_TLV_SIZE + 2 - 8)
+            .putShort(DPID_TLV_HEADER).put(ONLAB_OUI).put(DPID_TLV_SUBTYPE)
+            .array();
+
+    // Pre-built contents of both organizationally specific TLVs
+    private static final byte[] OUI_TLV = ArrayUtils.addAll(NAME_TLV, DPID_TLV);
+
+    // Default switch, port number and TTL
+    private static final byte[] DEFAULT_DPID = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00 };
+    private static final short DEFAULT_PORT = 0;
+    private static final short DEFAULT_TTL = 120; // in seconds
+
+    // Minimum and ONOS-generated LLDP packet sizes
+    private static final short MINIMUM_LLDP_SIZE = 61;
+    // Add 12 for 2-byte header of each TLV and a single EndOfLLDPTLV
+    private static final short ONOS_LLDP_SIZE = (short) (CHASSIS_TLV_SIZE
+            + PORT_TLV_SIZE + TTL_TLV_SIZE + NAME_TLV_SIZE + DPID_TLV_SIZE + 12);
+
+    // Direction TLVs are used to indicate if the LLDPs were sent
+    // periodically or in response to a received LLDP
+    private static final byte TLV_DIRECTION_TYPE = 0x73;
+    private static final short TLV_DIRECTION_LENGTH = 1;  // 1 byte
+    private static final byte[] TLV_DIRECTION_VALUE_FORWARD = {0x01};
+    private static final byte[] TLV_DIRECTION_VALUE_REVERSE = {0x02};
+    private static final LLDPTLV FORWARD_TLV
+            = new LLDPTLV().
+            setType(TLV_DIRECTION_TYPE).
+            setLength(TLV_DIRECTION_LENGTH).
+            setValue(TLV_DIRECTION_VALUE_FORWARD);
+
+    private static final LLDPTLV REVERSE_TLV
+            = new LLDPTLV().
+            setType(TLV_DIRECTION_TYPE).
+            setLength(TLV_DIRECTION_LENGTH).
+            setValue(TLV_DIRECTION_VALUE_REVERSE);
+
+    // Field offsets in ONOS-generated LLDP
+    private static final short ETHERTYPE_OFFSET = 12;
+    private static final short PORT_OFFSET = 26;
+    private static final short DPID_OFFSET = 54;
+
+    // Private member fields
+    // Byte arrays for TLV information string
+    private byte[] chassisId = new byte[CHASSIS_TLV_SIZE];
+    private byte[] portId = new byte[PORT_TLV_SIZE];
+    private byte[] ttl = new byte[TTL_TLV_SIZE];
+    private byte[] ouiName = new byte[NAME_TLV_SIZE];
+    private byte[] ouiDpid = new byte[DPID_TLV_SIZE];
+
+    // TLVs
+    private LLDPTLV chassisTLV;
+    private LLDPTLV portTLV;
+    private LLDPTLV ttlTLV;
+    private LLDPTLV ouiNameTLV;
+    private LLDPTLV ouiDpidTLV;
+    private List<LLDPTLV> optionalTLVList;
+
+    /**
+     * Instantiates a new ONOS LDDP message.
+     */
+    public OnosLldp() {
+        // Create TLVs
+        this.chassisTLV = new LLDPTLV();
+        this.portTLV = new LLDPTLV();
+        this.ttlTLV = new LLDPTLV();
+        this.ouiNameTLV = new LLDPTLV();
+        this.ouiDpidTLV = new LLDPTLV();
+        this.optionalTLVList = new LinkedList<LLDPTLV>();
+        this.optionalTLVList.add(this.ouiNameTLV);
+        this.optionalTLVList.add(this.ouiDpidTLV);
+
+        // Add TLVs to LLDP packet
+        this.setChassisId(this.chassisTLV);
+        this.setPortId(this.portTLV);
+        this.setTtl(this.ttlTLV);
+        this.setOptionalTLVList(this.optionalTLVList);
+
+        // Set TLVs to default values
+        this.setChassisTLV(DEFAULT_DPID);
+        this.setPortTLV(DEFAULT_PORT);
+        this.setTTLTLV(DEFAULT_TTL);
+        this.setOUIName(OnosLldp.ONOS_NAME);
+        this.setOUIDpid(DEFAULT_DPID);
+    }
+
+    /**
+     * Sets chassis TLV. Note that we can only put 6 bytes in the chassis ID, so
+     * we use another organizationally specific TLV to put the full dpid (see
+     * setOUIDpid()).
+     *
+     * @param dpid the switch DPID
+     */
+    private void setChassisTLV(final byte[] dpid) {
+        ByteBuffer bb = ByteBuffer.wrap(this.chassisId);
+        bb.put(CHASSIS_TLV_SUBTYPE);
+        for (int i = 2; i < 8; i++) {
+            bb.put(dpid[i]);
+        }
+
+        this.chassisTLV.setLength(CHASSIS_TLV_SIZE);
+        this.chassisTLV.setType(CHASSIS_TLV_TYPE);
+        this.chassisTLV.setValue(this.chassisId);
+    }
+
+    /**
+     * Sets port TLV.
+     *
+     * @param portNumber the port number
+     */
+    private void setPortTLV(final short portNumber) {
+        ByteBuffer bb = ByteBuffer.wrap(this.portId);
+        bb.put(PORT_TLV_SUBTYPE);
+        bb.putShort(portNumber);
+
+        this.portTLV.setLength(PORT_TLV_SIZE);
+        this.portTLV.setType(PORT_TLV_TYPE);
+        this.portTLV.setValue(this.portId);
+    }
+
+    /**
+     * Sets Time To Live TLV.
+     *
+     * @param time the time to live
+     */
+    private void setTTLTLV(final short time) {
+        ByteBuffer bb = ByteBuffer.wrap(this.ttl);
+        bb.putShort(time);
+
+        this.ttlTLV.setLength(TTL_TLV_SIZE);
+        this.ttlTLV.setType(TTL_TLV_TYPE);
+        this.ttlTLV.setValue(this.ttl);
+    }
+
+    /**
+     * Sets organizationally specific TLV for ONOS name (subtype 1).
+     *
+     * @param name the name
+     */
+    private void setOUIName(final String name) {
+        ByteBuffer bb = ByteBuffer.wrap(ouiName);
+        bb.put(OnosLldp.ONLAB_OUI);
+        bb.put(NAME_TLV_SUBTYPE);
+        bb.put(name.getBytes(Charsets.UTF_8));
+
+        this.ouiNameTLV.setLength(NAME_TLV_SIZE);
+        this.ouiNameTLV.setType(NAME_TLV_TYPE);
+        this.ouiNameTLV.setValue(ouiName);
+    }
+
+    /**
+     * Sets organizationally specific TLV for ONOS full dpid (subtype 2).
+     *
+     * @param dpid the switch DPID
+     */
+    private void setOUIDpid(final byte[] dpid) {
+        ByteBuffer bb = ByteBuffer.wrap(ouiDpid);
+        bb.put(OnosLldp.ONLAB_OUI);
+        bb.put(DPID_TLV_SUBTYPE);
+        bb.put(dpid);
+
+        this.ouiDpidTLV.setLength(DPID_TLV_SIZE);
+        this.ouiDpidTLV.setType(DPID_TLV_TYPE);
+        this.ouiDpidTLV.setValue(ouiDpid);
+    }
+
+    /**
+     * Sets switch DPID in LLDP packet.
+     *
+     * @param sw the switch dpid
+     */
+    public void setSwitch(Long dpid) {
+        final byte[] byteDpid = ByteBuffer.allocate(8).putLong(dpid)
+                .array();
+        this.setChassisTLV(byteDpid);
+        this.setOUIDpid(byteDpid);
+    }
+
+
+    /**
+     * Sets the port number in LLDP packet.
+     *
+     * @param port the port number
+     */
+    public void setPort(short portNumber) {
+        this.setPortTLV(portNumber);
+    }
+
+    /**
+     * Sets whether this is a forward or reverse LLDP.
+     *
+     * @param isReverse true if reverse, false if forward
+     */
+    public void setReverse(boolean isReverse) {
+        optionalTLVList.add((isReverse) ? REVERSE_TLV : FORWARD_TLV);
+    }
+
+    /**
+     * Serializes full LLDP packet to byte array.
+     *
+     * @return the serialized packet
+     */
+    public byte[] serialize() {
+        return super.serialize();
+    }
+
+    /**
+     * Checks if LLDP packet has correct size, LLDP multicast address, and
+     * ethertype. Packet assumed to have Ethernet header.
+     *
+     * @param packet full packet starting from the Ethernet header
+     * @return true if packet is LLDP, false otherwise
+     */
+    public static boolean isLLDP(final byte[] packet) {
+        // Does packet exist and does it have the mininum size?
+        if (packet == null || packet.length < MINIMUM_LLDP_SIZE) {
+            return false;
+        }
+
+        // Packet has LLDP multicast destination address?
+        final ByteBuffer bb = ByteBuffer.wrap(packet);
+        final byte[] dst = new byte[6];
+        bb.get(dst);
+
+        if (!(Arrays.equals(dst, OnosLldp.LLDP_NICIRA)
+                || Arrays.equals(dst, OnosLldp.LLDP_MULTICAST) || Arrays.equals(
+                dst, OnosLldp.BDDP_MULTICAST))) {
+
+            return false;
+        }
+
+        // Fetch ethertype, skip VLAN tag if it's there
+        short etherType = bb.getShort(ETHERTYPE_OFFSET);
+        if (etherType == ETHERTYPE_VLAN) {
+            etherType = bb.getShort(ETHERTYPE_OFFSET + 4);
+        }
+
+        // Check ethertype
+        if (etherType == Ethernet.TYPE_LLDP) {
+            return true;
+        }
+        if (etherType == Ethernet.TYPE_BSN) {
+            return true;
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Checks if packet has size of ONOS-generated LLDP, and correctness of two
+     * organizationally specific TLVs that use ON.Lab's OUI. Assumes packet is
+     * valid LLDP packet
+     *
+     * @param packet full packet starting from the Ethernet header
+     * @return true if this is an ONOS-generated LLDP, otherwise false
+     */
+    public static boolean isOnosLldp(byte[] packet) {
+        if (packet.length < ONOS_LLDP_SIZE) {
+            return false;
+        }
+
+        // Extra offset due to VLAN tag
+        final ByteBuffer bb = ByteBuffer.wrap(packet);
+        int offset = 0;
+        if (bb.getShort(ETHERTYPE_OFFSET) != Ethernet.TYPE_LLDP
+                && bb.getShort(ETHERTYPE_OFFSET) != Ethernet.TYPE_BSN) {
+            offset = 4;
+        }
+
+        // Compare packet's organizationally specific TLVs to the expected
+        // values
+        for (int i = 0; i < OUI_TLV.length; i++) {
+            if (packet[NAME_TLV_OFFSET + offset + i] != OUI_TLV[i]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Extracts dpid and port from ONOS-generated LLDP packet.
+     *
+     * @param packet full packet started at the Ethernet header
+     * @return switchport switch and port info from the DPID and Port TLVs
+     */
+    public static SwitchPort extractSwitchPort(final byte[] packet) {
+        final ByteBuffer bb = ByteBuffer.wrap(packet);
+
+        // Extra offset due to VLAN tag
+        int offset = 0;
+        if (bb.getShort(ETHERTYPE_OFFSET) != Ethernet.TYPE_LLDP
+                && bb.getShort(ETHERTYPE_OFFSET) != Ethernet.TYPE_BSN) {
+            offset = 4;
+        }
+
+        final short port = bb.getShort(PORT_OFFSET + offset);
+        final long dpid = bb.getLong(DPID_OFFSET + offset);
+
+        return new SwitchPort(dpid, port);
+    }
+
+    /**
+     * Checks if the LLDP is a reverse LLDP (i.e. sent in response to receiving
+     * an LLDP on the link). This information is stored in the Direction TLV.
+     *
+     * @param lldp parsed LLDP packet
+     * @return true if the LLDP is a reverse LLDP, otherwise false
+     */
+    public static boolean isReverse(final LLDP lldp) {
+        for (LLDPTLV lldpTlv : lldp.getOptionalTLVList()) {
+            if ((lldpTlv.getType() == TLV_DIRECTION_TYPE) &&
+                    Arrays.equals(lldpTlv.getValue(), TLV_DIRECTION_VALUE_REVERSE)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (!super.equals(other)) {
+            return false;
+        }
+        //
+        // NOTE: Subclasses are are considered as change of identity, hence
+        // equals() will return false if the class type doesn't match.
+        //
+        if (getClass() != other.getClass()) {
+            return false;
+        }
+
+        OnosLldp otherLldp = (OnosLldp) other;
+
+        if (!this.chassisTLV.equals(otherLldp.chassisTLV)) {
+            return false;
+        }
+
+        if (!this.portTLV.equals(otherLldp.portTLV)) {
+            return false;
+        }
+
+        if (!this.ttlTLV.equals(otherLldp.ttlTLV)) {
+            return false;
+        }
+
+        if (!this.ouiNameTLV.equals(otherLldp.ouiNameTLV)) {
+            return false;
+        }
+
+        if (!this.ouiDpidTLV.equals(otherLldp.ouiDpidTLV)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + chassisTLV.hashCode();
+        result = prime * result + portTLV.hashCode();
+        result = prime * result + ttlTLV.hashCode();
+        result = prime * result + ouiNameTLV.hashCode();
+        result = prime * result + ouiDpidTLV.hashCode();
+
+        return result;
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index cdcf010..4cebdaa 100644
--- a/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -395,6 +395,8 @@
      */
     @Test
     public void testSendDiscoveryMessage() throws IOException {
+        byte[] macAddress = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
+
         LinkDiscoveryManager topology = getTopology();
 
         // Mock up our expected behavior
@@ -404,6 +406,7 @@
         short portNum = 1;
         OFPhysicalPort ofpPort = new OFPhysicalPort();
         ofpPort.setPortNumber(portNum);
+        ofpPort.setHardwareAddress(macAddress);
 
         /* sendDiscoverMessage() should perform the following actions on
          * IOFSwitch object
