diff --git a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java index ec5974fcdec74433d98530a57e3b8b305d55f0c4..87ae4a2d3927506a162cc93235ea0303749dcd3e 100644 --- a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java +++ b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java @@ -123,8 +123,8 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, * Map from link to the most recent time it was verified functioning */ protected Map<LinkTuple, LinkInfo> links; - protected Long lldpFrequency = 15L * 1000; // sending frequency - protected Long lldpTimeout = 35L * 1000; // timeout + protected int lldpFrequency = 15 * 1000; // sending frequency + protected int lldpTimeout = 35 * 1000; // timeout protected ReentrantReadWriteLock lock; /** @@ -149,11 +149,11 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, public static enum UpdateOperation {ADD, UPDATE, REMOVE, SWITCH_UPDATED, CLUSTER_MERGED}; - public Long getLldpFrequency() { + public int getLldpFrequency() { return lldpFrequency; } - public Long getLldpTimeout() { + public int getLldpTimeout() { return lldpTimeout; } @@ -296,6 +296,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, Runnable timeoutLinksTimer = new Runnable() { @Override public void run() { + log.trace("Running timeoutLinksTimer"); try { timeoutLinks(); if (!shuttingDown) { @@ -308,7 +309,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, "terminating process", e); floodlightProvider.terminate(); } catch (Exception e) { - log.error("Exception in link timer", e); + log.error("Exception in timeoutLinksTimer", e); } } }; @@ -711,8 +712,8 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } /** - * - * @param links + * Removes links from memory and storage. + * @param links The List of @LinkTuple to delete. */ protected void deleteLinks(List<LinkTuple> links) { lock.writeLock().lock(); @@ -747,7 +748,14 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, lock.writeLock().unlock(); } } - + + /** + * Handles an OFPortStatus message from a switch. We will add or + * delete LinkTupes as well re-compute the topology if needed. + * @param sw The IOFSwitch that sent the port status message + * @param ps The OFPortStatus message + * @return The Command to continue or stop after we process this message + */ protected Command handlePortStatus(IOFSwitch sw, OFPortStatus ps) { if (log.isDebugEnabled()) { log.debug("handlePortStatus: Switch {} port #{} reason {}; " + @@ -844,11 +852,21 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, return Command.CONTINUE; } + /** + * We send out LLDP messages when a switch is added to discover the topology + * @param sw The IOFSwitch that connected to the controller + */ @Override public void addedSwitch(IOFSwitch sw) { + // TODO - Send LLDPs only from the switch that was added sendLLDPs(); } + /** + * When a switch disconnects we remove any links from our map and re-compute + * the topology. + * @param sw The IOFSwitch that disconnected from the controller + */ @Override public void removedSwitch(IOFSwitch sw) { List<LinkTuple> eraseList = new ArrayList<LinkTuple>(); @@ -865,6 +883,11 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } } + /** + * Iterates though @SwitchCluster links and then deletes ones + * that have timed out. The timeout is set by lldpTimeout. + * If links are deleted updateClusters() is then called. + */ protected void timeoutLinks() { List<LinkTuple> eraseList = new ArrayList<LinkTuple>(); Long curTime = System.currentTimeMillis(); @@ -881,8 +904,11 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, eraseList.add(entry.getKey()); } } - - deleteLinks(eraseList); + + if (eraseList.size() > 0) { + deleteLinks(eraseList); + updateClusters(); + } } finally { lock.writeLock().unlock(); } @@ -902,12 +928,20 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } /** + * Sets the IFloodlightProvider for this TopologyImpl. * @param floodlightProvider the floodlightProvider to set */ public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { this.floodlightProvider = floodlightProvider; } + /** + * Checks to see if a SwitchPortTuple is internal. A SwitchPortTuple is + * defined as internal if the switch is a core switch if only switches that + * are in the same SwitchCluster are connected to it. + * @param idPort The SwitchPortTuple to check + * @return True if it is internal, false otherwise + */ @Override public boolean isInternal(SwitchPortTuple idPort) { lock.readLock().lock(); @@ -943,8 +977,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, return result; } - - @Override public LinkInfo getLinkInfo(SwitchPortTuple idPort, boolean isSrcPort) { Set<LinkTuple> links = this.portLinks.get(idPort); @@ -997,7 +1029,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } /** -<<<<<<< HEAD * @author Srinivasan Ramasubramanian * * This function divides the network into clusters. Every cluster is @@ -1126,8 +1157,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, return currIndex; } - - public Set<IOFSwitch> getSwitchesInCluster(IOFSwitch sw) { SwitchCluster cluster = switchClusterMap.get(sw); if (cluster == null){ @@ -1136,10 +1165,19 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, return cluster.getSwitches(); } + /** + * Returns the SwitchCluster that contains the switch. + * @param sw The IOFSwitch to get + * @return The SwitchCluster that it is part of + */ public SwitchCluster getSwitchCluster(IOFSwitch sw) { return switchClusterMap.get(sw); } + /** + * Checks if two IOFSwitches are in the same SwitchCluster + * @return True if they are in the same cluster, false otherwise + */ public boolean inSameCluster(IOFSwitch switch1, IOFSwitch switch2) { if (switchClusterMap != null) { lock.readLock().lock(); @@ -1156,11 +1194,18 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } // STORAGE METHODS - + /** + * Deletes all links from storage + */ void clearAllLinks() { storageSource.deleteRowsAsync(LINK_TABLE_NAME, null); } + /** + * Gets the storage key for a LinkTuple + * @param lt The LinkTuple to get + * @return The storage key as a String + */ private String getLinkId(LinkTuple lt) { String srcDpid = lt.getSrc().getSw().getStringId(); String dstDpid = lt.getDst().getSw().getStringId(); @@ -1168,6 +1213,11 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, dstDpid + "-" + lt.getDst().getPort(); } + /** + * Writes a LinkTuple and corresponding LinkInfo to storage + * @param lt The LinkTuple to write + * @param linkInfo The LinkInfo to write + */ void writeLink(LinkTuple lt, LinkInfo linkInfo) { Map<String, Object> rowValues = new HashMap<String, Object>(); @@ -1278,6 +1328,10 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, storageSource.updateRowAsync(LINK_TABLE_NAME, id, rowValues); } + /** + * Removes a link from storage using an asynchronous call. + * @param lt The LinkTuple to delete. + */ void removeLink(LinkTuple lt) { String id = getLinkId(lt); storageSource.deleteRowAsync(LINK_TABLE_NAME, id); @@ -1292,7 +1346,8 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } /** - * @param storageSource the storage source to use for persisting link info + * Sets the IStorageSource to use for ITology + * @param storageSource the storage source to use */ public void setStorageSource(IStorageSource storageSource) { this.storageSource = storageSource; @@ -1300,6 +1355,10 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID); } + /** + * Gets the storage source for this ITopology + * @return The IStorageSource ITopology is writing to + */ public IStorageSource getStorageSource() { return storageSource; } @@ -1325,7 +1384,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, @Override public void rowsModified(String tableName, Set<Object> rowKeys) { - Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches(); ArrayList<IOFSwitch> updated_switches = new ArrayList<IOFSwitch>(); for(Object key: rowKeys) { @@ -1379,5 +1437,4 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, public void rowsDeleted(String tableName, Set<Object> rowKeys) { // Ignore delete events, the switch delete will do the right thing on it's own } - } diff --git a/src/main/java/org/openflow/protocol/OFPhysicalPort.java b/src/main/java/org/openflow/protocol/OFPhysicalPort.java index a231511e737b87ef57ef03c9d16c885e779f650c..39a9878dc52a8cfac928f5674852237dfdcb3607 100644 --- a/src/main/java/org/openflow/protocol/OFPhysicalPort.java +++ b/src/main/java/org/openflow/protocol/OFPhysicalPort.java @@ -32,13 +32,41 @@ public class OFPhysicalPort { public static int OFP_ETH_ALEN = 6; public enum OFPortConfig { - OFPPC_PORT_DOWN (1 << 0), - OFPPC_NO_STP (1 << 1), - OFPPC_NO_RECV (1 << 2), - OFPPC_NO_RECV_STP (1 << 3), - OFPPC_NO_FLOOD (1 << 4), - OFPPC_NO_FWD (1 << 5), - OFPPC_NO_PACKET_IN (1 << 6); + OFPPC_PORT_DOWN (1 << 0) { + public String toString() { + return "port-down (0x1)"; + } + }, + OFPPC_NO_STP (1 << 1) { + public String toString() { + return "no-stp (0x2)"; + } + }, + OFPPC_NO_RECV (1 << 2) { + public String toString() { + return "no-recv (0x4)"; + } + }, + OFPPC_NO_RECV_STP (1 << 3) { + public String toString() { + return "no-recv-stp (0x8)"; + } + }, + OFPPC_NO_FLOOD (1 << 4) { + public String toString() { + return "no-flood (0x10)"; + } + }, + OFPPC_NO_FWD (1 << 5) { + public String toString() { + return "no-fwd (0x20)"; + } + }, + OFPPC_NO_PACKET_IN (1 << 6) { + public String toString() { + return "no-pkt-in (0x40)"; + } + }; protected int value; @@ -55,12 +83,36 @@ public class OFPhysicalPort { } public enum OFPortState { - OFPPS_LINK_DOWN (1 << 0), - OFPPS_STP_LISTEN (0 << 8), - OFPPS_STP_LEARN (1 << 8), - OFPPS_STP_FORWARD (2 << 8), - OFPPS_STP_BLOCK (3 << 8), - OFPPS_STP_MASK (3 << 8); + OFPPS_LINK_DOWN (1 << 0) { + public String toString() { + return "link-down (0x1)"; + } + }, + OFPPS_STP_LISTEN (0 << 8) { + public String toString() { + return "listen (0x0)"; + } + }, + OFPPS_STP_LEARN (1 << 8) { + public String toString() { + return "learn-no-relay (0x100)"; + } + }, + OFPPS_STP_FORWARD (2 << 8) { + public String toString() { + return "forward (0x200)"; + } + }, + OFPPS_STP_BLOCK (3 << 8) { + public String toString() { + return "block-broadcast (0x300)"; + } + }, + OFPPS_STP_MASK (3 << 8) { + public String toString() { + return "block-broadcast (0x300)"; + } + }; protected int value; @@ -77,18 +129,66 @@ public class OFPhysicalPort { } public enum OFPortFeatures { - OFPPF_10MB_HD (1 << 0), - OFPPF_10MB_FD (1 << 1), - OFPPF_100MB_HD (1 << 2), - OFPPF_100MB_FD (1 << 3), - OFPPF_1GB_HD (1 << 4), - OFPPF_1GB_FD (1 << 5), - OFPPF_10GB_FD (1 << 6), - OFPPF_COPPER (1 << 7), - OFPPF_FIBER (1 << 8), - OFPPF_AUTONEG (1 << 9), - OFPPF_PAUSE (1 << 10), - OFPPF_PAUSE_ASYM (1 << 11); + OFPPF_10MB_HD (1 << 0) { + public String toString() { + return "10mb-hd (0x1)"; + } + }, + OFPPF_10MB_FD (1 << 1) { + public String toString() { + return "10mb-fd (0x2)"; + } + }, + OFPPF_100MB_HD (1 << 2) { + public String toString() { + return "100mb-hd (0x4)"; + } + }, + OFPPF_100MB_FD (1 << 3) { + public String toString() { + return "100mb-fd (0x8)"; + } + }, + OFPPF_1GB_HD (1 << 4) { + public String toString() { + return "1gb-hd (0x10)"; + } + }, + OFPPF_1GB_FD (1 << 5) { + public String toString() { + return "1gb-fd (0x20)"; + } + }, + OFPPF_10GB_FD (1 << 6) { + public String toString() { + return "10gb-fd (0x40)"; + } + }, + OFPPF_COPPER (1 << 7) { + public String toString() { + return "copper (0x80)"; + } + }, + OFPPF_FIBER (1 << 8) { + public String toString() { + return "fiber (0x100)"; + } + }, + OFPPF_AUTONEG (1 << 9) { + public String toString() { + return "autoneg (0x200)"; + } + }, + OFPPF_PAUSE (1 << 10) { + public String toString() { + return "pause (0x400)"; + } + }, + OFPPF_PAUSE_ASYM (1 << 11) { + public String toString() { + return "pause-asym (0x800)"; + } + }; protected int value;