diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java index 3950c2c43938486359d38b6e3dd6d9d381647967..9f00f4a3d399e25cbe46f25e6d8673ca2b1fdac0 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java @@ -297,10 +297,10 @@ IFloodlightModule, IInfoProvider { OFPortDesc ofpPort = iofSwitch.getPort(port); - //if (log.isTraceEnabled()) { - log.warn("Sending LLDP packet out of swich: {}, port: {}, reverse: {}", + if (log.isTraceEnabled()) { + log.trace("Sending LLDP packet out of swich: {}, port: {}, reverse: {}", new Object[] {iofSwitch.getId().toString(), port.toString(), Boolean.toString(isReverse)}); - //} + } // using "nearest customer bridge" MAC address for broadest possible // propagation @@ -902,7 +902,7 @@ IFloodlightModule, IInfoProvider { updateList.add(updates.remove()); } - if (linkDiscoveryAware != null) { + if (linkDiscoveryAware != null && !updateList.isEmpty()) { if (log.isTraceEnabled()) { log.trace("Dispatching link discovery update {} {} {} {} {} {}ms for {}", new Object[] { @@ -1333,16 +1333,27 @@ IFloodlightModule, IInfoProvider { */ protected boolean updateLink(@Nonnull Link lk, @Nonnull LinkInfo existingInfo, @Nonnull LinkInfo newInfo) { boolean linkChanged = false; - + boolean ignoreBDDP_haveLLDPalready = false; + /* * Check if we are transitioning from one link type to another. * A transition is: * -- going from no LLDP time to an LLDP time (is OpenFlow link) - * -- going from an LLDP time to no LLDP time (is non-OpenFlow link) + * -- going from an LLDP time to a BDDP time (is non-OpenFlow link) + * + * Note: Going from LLDP to BDDP means our LLDP link must have timed + * out already (null in existing LinkInfo). Otherwise, we'll flap + * between mulitcast and unicast links. */ - if (existingInfo.getUnicastValidTime() != null && newInfo.getUnicastValidTime() == null) { - linkChanged = true; /* detected BDDP */ + if (existingInfo.getMulticastValidTime() == null && newInfo.getMulticastValidTime() != null) { + if (existingInfo.getUnicastValidTime() == null) { /* unicast must be null to go to multicast */ + log.warn("Link is BDDP. Changed."); + linkChanged = true; /* detected BDDP */ + } else { + ignoreBDDP_haveLLDPalready = true; + } } else if (existingInfo.getUnicastValidTime() == null && newInfo.getUnicastValidTime() != null) { + log.warn("Link is LLDP. Changed."); linkChanged = true; /* detected LLDP */ } @@ -1370,7 +1381,7 @@ IFloodlightModule, IInfoProvider { if (currentLatency == null) { /* no-op; already 'changed' as this is a new link */ - } else if (!latencyToUse.equals(currentLatency)) { + } else if (!latencyToUse.equals(currentLatency) && !ignoreBDDP_haveLLDPalready) { log.warn("Updating link {} latency to {}ms", lk.toKeyString(), latencyToUse.getValue()); lk.setLatency(latencyToUse); linkChanged = true; @@ -1400,7 +1411,7 @@ IFloodlightModule, IInfoProvider { } /* Update existing LinkInfo with most recent time stamp */ - if (existingInfo != null && existingInfo.getFirstSeenTime().getTime() >= newInfo.getFirstSeenTime().getTime()) { + if (existingInfo != null && existingInfo.getFirstSeenTime().before(newInfo.getFirstSeenTime())) { existingInfo.setFirstSeenTime(newInfo.getFirstSeenTime()); } @@ -1421,7 +1432,7 @@ IFloodlightModule, IInfoProvider { // Add all to event history LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { - log.info("Inter-switch link detected: {}", lt); + log.debug("Inter-switch link detected: {}", lt); eventCategory.newEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "direct-link-added::rcvd LLDP")); } diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java index 74434c328b58792fe047ae08ec9d07db568a18b9..c76f63f0cd34a0abf36a6ec0482a3de9a16a56b3 100644 --- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java +++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java @@ -304,8 +304,8 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo // ********************** // ILinkDiscoveryListener // ********************** - - + + @Override public void linkDiscoveryUpdate(List<LDUpdate> updateList) { if (log.isTraceEnabled()) { @@ -321,9 +321,9 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo } ldUpdates.add(update); } - - - + + + // **************** // ITopologyService // **************** @@ -331,46 +331,46 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo // // ITopologyService interface methods // - + @Override public Map<DatapathId, Set<Link>> getAllLinks(){ - + Map<DatapathId, Set<Link>> dpidLinks = new HashMap<DatapathId, Set<Link>>(); - TopologyInstance ti = getCurrentInstance(true); + TopologyInstance ti = getCurrentInstance(true); Set<DatapathId> switches = ti.getSwitches(); - + for(DatapathId s: switches) { - if (this.switchPorts.get(s) == null) continue; - for (OFPort p: switchPorts.get(s)) { - NodePortTuple np = new NodePortTuple(s, p); - if (this.switchPortLinks.get(np) == null) continue; - for(Link l: this.switchPortLinks.get(np)) { - if(dpidLinks.containsKey(s)) { - dpidLinks.get(s).add(l); - } - else { - dpidLinks.put(s,new HashSet<Link>(Arrays.asList(l))); - } - - } - } - } - + if (this.switchPorts.get(s) == null) continue; + for (OFPort p: switchPorts.get(s)) { + NodePortTuple np = new NodePortTuple(s, p); + if (this.switchPortLinks.get(np) == null) continue; + for(Link l: this.switchPortLinks.get(np)) { + if(dpidLinks.containsKey(s)) { + dpidLinks.get(s).add(l); + } + else { + dpidLinks.put(s,new HashSet<Link>(Arrays.asList(l))); + } + + } + } + } + return dpidLinks; } - + @Override - public boolean isEdge(DatapathId sw, OFPort p){ - TopologyInstance ti = getCurrentInstance(true); + public boolean isEdge(DatapathId sw, OFPort p){ + TopologyInstance ti = getCurrentInstance(true); return ti.isEdge(sw,p); - } + } @Override public Set<OFPort> getSwitchBroadcastPorts(DatapathId sw){ TopologyInstance ti = getCurrentInstance(true); return ti.swBroadcastPorts(sw); } - + @Override public Date getLastUpdateTime() { return lastUpdateTime; @@ -1068,7 +1068,7 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo switches.add(pinSwitch); } - for(DatapathId sid: switches) { + for (DatapathId sid : switches) { IOFSwitch sw = switchService.getSwitch(sid); if (sw == null) continue; Collection<OFPort> enabledPorts = sw.getEnabledPortNumbers(); @@ -1083,7 +1083,7 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo Set<OFPort> portsKnownToTopo = ti.getPortsWithLinks(sid); if (portsKnownToTopo != null) { - for(OFPort p: portsKnownToTopo) { + for (OFPort p : portsKnownToTopo) { NodePortTuple npt = new NodePortTuple(sid, p); if (ti.isBroadcastDomainPort(npt) == false) { @@ -1201,8 +1201,6 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo public boolean createNewInstance() { return createNewInstance("internal"); } - - /** * This function computes a new topology instance. @@ -1210,17 +1208,12 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo * and tunnel ports. The method returns if a new instance of * topology was created or not. */ - - - - - protected boolean createNewInstance(String reason) { Set<NodePortTuple> blockedPorts = new HashSet<NodePortTuple>(); - + if (!linksUpdated) return false; - - Map<NodePortTuple, Set<Link>> openflowLinks; + + Map<NodePortTuple, Set<Link>> openflowLinks; openflowLinks = new HashMap<NodePortTuple, Set<Link>>(); Set<NodePortTuple> nptList = switchPortLinks.keySet(); @@ -1240,17 +1233,17 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo identifyBroadcastDomainPorts(); // Remove all links incident on broadcast domain ports. - for(NodePortTuple npt: broadcastDomainPorts) { + for (NodePortTuple npt : broadcastDomainPorts) { if (switchPortLinks.get(npt) == null) continue; - for(Link link: switchPortLinks.get(npt)) { + for (Link link : switchPortLinks.get(npt)) { removeLinkFromStructure(openflowLinks, link); } } // Remove all tunnel links. - for(NodePortTuple npt: tunnelPorts) { + for (NodePortTuple npt: tunnelPorts) { if (switchPortLinks.get(npt) == null) continue; - for(Link link: switchPortLinks.get(npt)) { + for (Link link : switchPortLinks.get(npt)) { removeLinkFromStructure(openflowLinks, link); } } @@ -1259,28 +1252,26 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo for (DatapathId sw : switchPorts.keySet()){ allPorts.put(sw, this.getPorts(sw)); } - + TopologyInstance nt = new TopologyInstance(switchPorts, blockedPorts, openflowLinks, broadcastDomainPorts, tunnelPorts,switchPortLinks,allPorts); - - log.info("-----------creating Topology instance-------------"); + nt.compute(); - + // We set the instances with and without tunnels to be identical. // If needed, we may compute them differently. currentInstance = nt; currentInstanceWithoutTunnels = nt; - TopologyEventInfo topologyInfo = new TopologyEventInfo(0, nt.getClusters().size(), new HashMap<DatapathId, List<NodePortTuple>>(), 0); eventCategory.newEventWithFlush(new TopologyEvent(reason, topologyInfo)); - + return true; } @@ -1301,18 +1292,18 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo // Copy switchPortLinks Map<NodePortTuple, Set<Link>> spLinks = new HashMap<NodePortTuple, Set<Link>>(); - for(NodePortTuple npt: switchPortLinks.keySet()) { + for (NodePortTuple npt : switchPortLinks.keySet()) { spLinks.put(npt, new HashSet<Link>(switchPortLinks.get(npt))); } - for(NodePortTuple npt: spLinks.keySet()) { + for (NodePortTuple npt : spLinks.keySet()) { Set<Link> links = spLinks.get(npt); boolean bdPort = false; ArrayList<Link> linkArray = new ArrayList<Link>(); if (links.size() > 2) { bdPort = true; } else if (links.size() == 2) { - for(Link l: links) { + for (Link l : links) { linkArray.add(l); } // now, there should be two links in [0] and [1].