Topology Manager to avoid redundant edge updates
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / internal / DiscoveryService.java
index 0895d9af27c85132965a98ea23cd166784a3e538..548bfb1f9fb26eb93ab4ca5bcd456d9bdc4082c3 100644 (file)
@@ -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,6 +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.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.
@@ -126,7 +125,7 @@ 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 {
@@ -218,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);
@@ -234,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 {
@@ -386,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());
+            }
         }
     }
 
@@ -407,7 +417,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
 
         List<LLDPTLV> 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;
         }
 
@@ -561,10 +571,11 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     private void addDiscovery(Node node) {
         Map<Long, ISwitch> switches = controller.getSwitches();
         ISwitch sw = switches.get(node.getID());
-        List<OFPhysicalPort> ports = sw.getEnabledPorts();
-        if (ports == null) {
+        if (sw == null) {
+            //switch could be removed by now, stop propagation
             return;
         }
+        List<OFPhysicalPort> ports = sw.getEnabledPorts();
         for (OFPhysicalPort port : ports) {
             NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
             if (!readyListHi.contains(nodeConnector)) {
@@ -825,8 +836,10 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             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);
     }
 
@@ -925,6 +938,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             return;
         }
 
+
         this.discoveryListener.notifyEdge(edge, type, props);
 
         NodeConnector src = edge.getTailNodeConnector(), dst = edge.getHeadNodeConnector();
@@ -1462,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());
@@ -1693,4 +1711,5 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         }
         return ports;
     }
+
 }