@Override
public OFPacketOut generateLLDPMessage(long sw, short port,
boolean isStandard, boolean isReverse) {
IOFSwitch iofSwitch = floodlightProvider.getSwitch(sw);
ImmutablePort ofpPort = iofSwitch.getPort(port);
if (log.isTraceEnabled()) {
log.trace("Sending LLDP packet out of swich: {}, port: {}",
HexString.toHexString(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 };
LLDPTLV dpidTLV = new LLDPTLV().setType((byte) 127)
.setLength((short) dpidTLVValue.length)
.setValue(dpidTLVValue);
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 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);
// TODO: Consider remove this block of code.
// It's evil to overwrite port object. The the old code always
// overwrote mac address, we now only overwrite zero macs and
// log a warning, mostly for paranoia.
byte[] srcMac = ofpPort.getHardwareAddress();
byte[] zeroMac = { 0, 0, 0, 0, 0, 0 };
if (Arrays.equals(srcMac, zeroMac)) {
log.warn("Port {}/{} has zero hareware address"
+ "overwrite with lower 6 bytes of dpid",
HexString.toHexString(dpid), ofpPort.getPortNumber());
System.arraycopy(dpidArray, 2, srcMac, 0, 6);
}
// 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(reverseTLV);
} else {
lldp.getOptionalTLVList().add(forwardTLV);
}
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);
}