}
private Command handleLldp(LLDP lldp, long sw, short inPort,
boolean isStandard, FloodlightContext cntx) {
// If LLDP is suppressed on this port, ignore received packet as well
IOFSwitch iofSwitch = floodlightProvider.getSwitch(sw);
if (!isIncomingDiscoveryAllowed(sw, inPort, isStandard))
return Command.STOP;
// If this is a malformed LLDP exit
if (lldp.getPortId() == null || lldp.getPortId().getLength() != 3) {
return Command.STOP;
}
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
&& lldptlv.getValue()[2] == (byte) 0xe1
&& lldptlv.getValue()[3] == 0x0) {
ByteBuffer dpidBB = ByteBuffer.wrap(lldptlv.getValue());
remoteSwitch = floodlightProvider.getSwitch(dpidBB.getLong(4));
} else if (lldptlv.getType() == 12 && lldptlv.getLength() == 8) {
otherId = ByteBuffer.wrap(lldptlv.getValue()).getLong();
if (myId == otherId) myLLDP = true;
} else if (lldptlv.getType() == TLV_DIRECTION_TYPE
&& lldptlv.getLength() == TLV_DIRECTION_LENGTH) {
if (lldptlv.getValue()[0] == TLV_DIRECTION_VALUE_FORWARD[0])
isReverse = false;
else if (lldptlv.getValue()[0] == TLV_DIRECTION_VALUE_REVERSE[0])
isReverse = true;
}
}
if (myLLDP == false) {
// 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 (after checking IDs)
if (isStandard) {
if (log.isTraceEnabled()) {
log.trace("Got a standard LLDP=[{}] that was not sent by" +
" this controller. Not fowarding it.", lldp.toString());
}
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.");
}
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");
}
return Command.STOP;
}
if (!remoteSwitch.portEnabled(remotePort)) {
if (log.isTraceEnabled()) {
log.trace("Ignoring link with disabled source port: switch {} port {} {}",
new Object[] { remoteSwitch.getStringId(),
remotePort,
remoteSwitch.getPort(remotePort)});
}
return Command.STOP;
}
if (suppressLinkDiscovery.contains(new NodePortTuple(
remoteSwitch.getId(),
remotePort))) {
if (log.isTraceEnabled()) {
log.trace("Ignoring link with suppressed src port: switch {} port {} {}",
new Object[] { remoteSwitch.getStringId(),
remotePort,
remoteSwitch.getPort(remotePort)});
}
return Command.STOP;
}
if (!iofSwitch.portEnabled(inPort)) {
if (log.isTraceEnabled()) {
log.trace("Ignoring link with disabled dest port: switch {} port {} {}",
new Object[] { HexString.toHexString(sw),
inPort,
iofSwitch.getPort(inPort)});
}
return Command.STOP;
}
// Store the time of update to this link, and push it out to
// routingEngine
Link lt = new Link(remoteSwitch.getId(), remotePort,
iofSwitch.getId(), inPort);
if (!isLinkAllowed(lt.getSrc(), lt.getSrcPort(),
lt.getDst(), lt.getDstPort()))
return Command.STOP;