X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FDiscoveryService.java;h=1a59a325adf6f6b71e03d4e68077921657f6813e;hp=bb303e3651de7e3a95659641cf001da4b0153bb4;hb=c7551f594c34504fffa0055d3360132577938b38;hpb=d4b6addab23cf24f20cd7969a7f1d800fda2bac1 diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java index bb303e3651..1a59a325ad 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java @@ -33,17 +33,11 @@ import org.opendaylight.controller.protocol_plugin.openflow.IInventoryProvider; import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener; import org.opendaylight.controller.protocol_plugin.openflow.core.IController; import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; -import org.openflow.protocol.OFPhysicalPort; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.opendaylight.controller.sal.connection.IPluginOutConnectionService; import org.opendaylight.controller.sal.core.Config; import org.opendaylight.controller.sal.core.ConstructionException; -import org.opendaylight.controller.sal.core.Edge; import org.opendaylight.controller.sal.core.ContainerFlow; +import org.opendaylight.controller.sal.core.Edge; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -61,8 +55,11 @@ import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.NetUtils; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; import org.opendaylight.controller.sal.utils.NodeCreator; -import org.opendaylight.controller.sal.utils.Status; -import org.opendaylight.controller.sal.utils.StatusCode; +import org.openflow.protocol.OFPhysicalPort; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The class describes neighbor discovery service for an OpenFlow network. @@ -128,11 +125,12 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa private Boolean throttling = false; // if true, no more batching. private volatile Boolean shuttingDown = false; - private LLDPTLV chassisIdTlv, portIdTlv, ttlTlv, customTlv; + private LLDPTLV chassisIdTlv, systemNameTlv, portIdTlv, ttlTlv, customTlv; private IPluginOutConnectionService connectionOutService; class DiscoveryTransmit implements Runnable { private final BlockingQueue transmitQ; + private int count = 0; DiscoveryTransmit(BlockingQueue transmitQ) { this.transmitQ = transmitQ; @@ -146,8 +144,11 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa RawPacket outPkt = createDiscoveryPacket(nodeConnector); sendDiscoveryPacket(nodeConnector, outPkt); nodeConnector = null; + if ((++count & 0x7f) == 0) { + Thread.sleep(10); + } } catch (InterruptedException e1) { - logger.warn("DiscoveryTransmit interupted", e1.getMessage()); + logger.trace("DiscoveryTransmit interupted", e1.getMessage()); if (shuttingDown) { return; } @@ -216,6 +217,11 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa chassisIdTlv.setType(LLDPTLV.TLVType.ChassisID.getValue()).setLength((short) cidValue.length) .setValue(cidValue); + // Create LLDP SystemName TLV + byte[] snValue = LLDPTLV.createSystemNameTLVValue(nodeConnector.getNode().toString()); + systemNameTlv.setType(LLDPTLV.TLVType.SystemName.getValue()).setLength((short) snValue.length) + .setValue(snValue); + // Create LLDP PortID TLV String portId = nodeConnector.getNodeConnectorIDString(); byte[] pidValue = LLDPTLV.createPortIDTLVValue(portId); @@ -232,7 +238,8 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa // Create discovery pkt LLDP discoveryPkt = new LLDP(); - discoveryPkt.setChassisId(chassisIdTlv).setPortId(portIdTlv).setTtl(ttlTlv).setOptionalTLVList(customList); + discoveryPkt.setChassisId(chassisIdTlv).setPortId(portIdTlv).setTtl(ttlTlv).setSystemNameId(systemNameTlv) + .setOptionalTLVList(customList); RawPacket rawPkt = null; try { @@ -384,7 +391,12 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa updateProdEdge(edge, props); } catch (Exception e) { - logger.warn("Caught exception ", e); + if (logger.isDebugEnabled()) { + logger.debug( + "Caught exception while attempting to snoop non controller generated or malformed LLDP frame sent by {} and received on {}: {}", + HexEncode.bytesToHexStringFormat(ethPkt.getSourceMACAddress()), dstNodeConnector, + e.getMessage()); + } } } @@ -405,7 +417,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa List optionalTLVList = lldp.getOptionalTLVList(); if (optionalTLVList == null) { - logger.info("The discovery packet with null custom option from {}", dstNodeConnector); + logger.warn("The discovery packet with null custom option from {}", dstNodeConnector); return false; } @@ -559,10 +571,11 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa private void addDiscovery(Node node) { Map switches = controller.getSwitches(); ISwitch sw = switches.get(node.getID()); - List ports = sw.getEnabledPorts(); - if (ports == null) { + if (sw == null) { + //switch could be removed by now, stop propagation return; } + List ports = sw.getEnabledPorts(); for (OFPhysicalPort port : ports) { NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node); if (!readyListHi.contains(nodeConnector)) { @@ -579,6 +592,14 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa readyListHi.add(nodeConnector); } + private void removeNodeConnector(NodeConnector nodeConnector) { + readyListLo.remove(nodeConnector); + readyListHi.remove(nodeConnector); + stagingList.remove(nodeConnector); + holdTime.remove(nodeConnector); + elapsedTime.remove(nodeConnector); + } + private Set getRemoveSet(Collection c, Node node) { Set removeSet = new HashSet(); if (c == null) { @@ -586,16 +607,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa } for (NodeConnector nodeConnector : c) { if (node.equals(nodeConnector.getNode())) { - Edge edge1 = edgeMap.get(nodeConnector); - if (edge1 != null) { - removeSet.add(nodeConnector); - - // check reverse direction - Edge edge2 = edgeMap.get(edge1.getTailNodeConnector()); - if ((edge2 != null) && node.equals(edge2.getTailNodeConnector().getNode())) { - removeSet.add(edge2.getHeadNodeConnector()); - } - } + removeSet.add(nodeConnector); } } return removeSet; @@ -604,6 +616,29 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa private void removeDiscovery(Node node) { Set removeSet; + removeSet = getRemoveSet(edgeMap.keySet(), node); + NodeConnector peerConnector; + Edge edge1, edge2; + for (NodeConnector nodeConnector : removeSet) { + // get the peer for fast removal of the edge in reverse direction + peerConnector = null; + edge1 = edgeMap.get(nodeConnector); + if (edge1 != null) { + edge2 = edgeMap.get(edge1.getTailNodeConnector()); + if ((edge2 != null) && node.equals(edge2.getTailNodeConnector().getNode())) { + peerConnector = edge2.getHeadNodeConnector(); + } + } + + removeEdge(nodeConnector, false); + removeEdge(peerConnector, isEnabled(peerConnector)); + } + + removeSet = getRemoveSet(prodMap.keySet(), node); + for (NodeConnector nodeConnector : removeSet) { + removeProdEdge(nodeConnector); + } + removeSet = getRemoveSet(readyListHi, node); readyListHi.removeAll(removeSet); @@ -618,22 +653,14 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa holdTime.remove(nodeConnector); } - removeSet = getRemoveSet(edgeMap.keySet(), node); + removeSet = getRemoveSet(elapsedTime.keySet(), node); for (NodeConnector nodeConnector : removeSet) { - removeEdge(nodeConnector, false); - } - - removeSet = getRemoveSet(prodMap.keySet(), node); - for (NodeConnector nodeConnector : removeSet) { - removeProdEdge(nodeConnector); + elapsedTime.remove(nodeConnector); } } private void removeDiscovery(NodeConnector nodeConnector) { - readyListHi.remove(nodeConnector); - readyListLo.remove(nodeConnector); - stagingList.remove(nodeConnector); - holdTime.remove(nodeConnector); + removeNodeConnector(nodeConnector); removeEdge(nodeConnector, false); removeProdEdge(nodeConnector); } @@ -672,7 +699,6 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa for (NodeConnector nodeConnector : retrySet) { // Allow one more retry - readyListLo.add(nodeConnector); elapsedTime.remove(nodeConnector); if (connectionOutService.isLocal(nodeConnector.getNode())) { transmitQ.add(nodeConnector); @@ -805,8 +831,15 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa } elapsedTime.remove(src); + // fast discovery of the edge in reverse direction + if (!edgeMap.containsKey(dst) && !readyListHi.contains(dst) && !elapsedTime.keySet().contains(dst)) { + moveToReadyListHi(dst); + } + + //checking only OF map, since production edge discovery always overwrites any existing edge + UpdateType ut = edgeMap.containsKey(dst) ? UpdateType.CHANGED : UpdateType.ADDED; // notify - updateEdge(edge, UpdateType.ADDED, props); + updateEdge(edge, ut, props); logger.trace("Add edge {}", edge); } @@ -871,18 +904,15 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa * Remove OpenFlow edge */ private void removeEdge(NodeConnector nodeConnector, boolean stillEnabled) { - holdTime.remove(nodeConnector); - readyListLo.remove(nodeConnector); - readyListHi.remove(nodeConnector); + if (nodeConnector == null) { + return; + } + + removeNodeConnector(nodeConnector); if (stillEnabled) { // keep discovering - if (!stagingList.contains(nodeConnector)) { - stagingList.add(nodeConnector); - } - } else { - // stop it - stagingList.remove(nodeConnector); + stagingList.add(nodeConnector); } Edge edge = null; @@ -908,13 +938,14 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa return; } + this.discoveryListener.notifyEdge(edge, type, props); NodeConnector src = edge.getTailNodeConnector(), dst = edge.getHeadNodeConnector(); if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) { if (type == UpdateType.ADDED) { edgeMap.put(dst, edge); - } else { + } else if (type == UpdateType.REMOVED) { edgeMap.remove(dst); } } else { @@ -923,7 +954,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa */ if (type == UpdateType.ADDED) { prodMap.put(dst, edge); - } else { + } else if (type == UpdateType.REMOVED) { prodMap.remove(dst); } } @@ -1240,7 +1271,15 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa if (val != null) { try { - int ticks = Integer.parseInt(val); + int ticks; + Set monitorSet = holdTime.keySet(); + if (monitorSet != null) { + for (NodeConnector nodeConnector : monitorSet) { + holdTime.put(nodeConnector, 0); + } + } + + ticks = Integer.parseInt(val); DiscoveryPeriod.INTERVAL.setTick(ticks); discoveryBatchRestartTicks = getDiscoveryInterval(); discoveryBatchPauseTicks = getDiscoveryPauseInterval(); @@ -1437,6 +1476,10 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa chassisIdTlv = new LLDPTLV(); chassisIdTlv.setType(LLDPTLV.TLVType.ChassisID.getValue()); + // Create LLDP SystemName TLV + systemNameTlv = new LLDPTLV(); + systemNameTlv.setType(LLDPTLV.TLVType.SystemName.getValue()); + // Create LLDP PortID TLV portIdTlv = new LLDPTLV(); portIdTlv.setType(LLDPTLV.TLVType.PortID.getValue()); @@ -1658,7 +1701,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa */ private int getDiscoveryBatchMaxPorts() { String val = System.getProperty("of.discoveryBatchMaxPorts"); - int ports = 1024; + int ports = 512; if (val != null) { try { @@ -1668,4 +1711,5 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa } return ports; } + }