diff --git a/.gitignore b/.gitignore index 1205d8a1aee3d42aa13e0789222f04dca116f4cd..dcc106a8e1436ff767ad147545bdfe308800b665 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.class .classpath .project +.settings/ .pydevproject .settings .DS_Store diff --git a/build.xml b/build.xml index 3acd1ecf9e03b716194b449a40844da847343bdc..79d64b1f1c29c68f6cfd490e8e6a9942f1463856 100644 --- a/build.xml +++ b/build.xml @@ -67,6 +67,8 @@ <include name="jython-2.5.2.jar"/> <include name="libthrift-0.7.0.jar"/> <include name="guava-13.0.1.jar" /> + <include name="findbugs-annotations-2.0.1.jar" /> + <include name="findbugs-jsr305-2.0.1.jar" /> </patternset> <path id="classpath"> @@ -283,7 +285,8 @@ <mkdir dir="${findbugs.results}"/> <findbugs home="${findbugs.home}" output="xml" - outputFile="${findbugs.results}/results.xml" > + excludeFilter="${basedir}/findbugs-exclude.xml" + outputFile="${findbugs.results}/results.xml" reportLevel='high'> <sourcePath path="${source}" /> <sourcePath path="${thrift.out.dir}" /> <class location="${build}" /> @@ -298,6 +301,7 @@ <mkdir dir="${findbugs.results}"/> <findbugs home="${findbugs.home}" output="html" + excludeFilter="${basedir}/findbugs-exclude.xml" outputFile="${findbugs.results}/results.html" > <sourcePath path="${source}" /> <sourcePath path="${thrift.out.dir}" /> diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml new file mode 100644 index 0000000000000000000000000000000000000000..bb2e5f327c1d1c56d911e9c3f38351b233727cce --- /dev/null +++ b/findbugs-exclude.xml @@ -0,0 +1,23 @@ +<FindBugsFilter> + <!--- Checks disabled on generated code --> + <Match> + <!-- don't complain about switch statements / external representation exposed + by generated parser files --> + <Class name="~net\.bigdb\.(query|yang)\.parser\..*(Lexer|Parser)" /> + <Bug pattern="SF_SWITCH_NO_DEFAULT,EI_EXPOSE_REP" /> + </Match> + + <!-- checks disabled because of too many false positives --> + <Match> + <!-- BC_UNFIRMED_CAST complains about too many pseudo violations, where + we know an object is of a specific type (e.g., by checking the type field + of an openflow message --> + <Bug pattern="BC_UNCONFIRMED_CAST" /> + </Match> + + <!-- checks disabled because they are just not important --> + <Match> + <!-- RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE is not an important check --> + <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" /> + </Match> +</FindBugsFilter> diff --git a/lib/findbugs-annotations-2.0.1.jar b/lib/findbugs-annotations-2.0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..8a0204fc28d78a15a848f8d2d4af467e52bb43c8 Binary files /dev/null and b/lib/findbugs-annotations-2.0.1.jar differ diff --git a/lib/findbugs-jsr305-2.0.1.jar b/lib/findbugs-jsr305-2.0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..43807b02f35db48dc302b4ade0c72b2141d65cbb Binary files /dev/null and b/lib/findbugs-jsr305-2.0.1.jar differ diff --git a/setup-eclipse.sh b/setup-eclipse.sh index de92c3493d07eef70b89d8f721153bd134490fad..01a6a95ef0f34cee64e85d0707c3d5b29ca0d219 100755 --- a/setup-eclipse.sh +++ b/setup-eclipse.sh @@ -47,3 +47,10 @@ cat >>"$d/.classpath" <<EOF <classpathentry kind="output" path="target/bin"/> </classpath> EOF + +mkdir -p $d/.settings +cat >$d/.settings/edu.umd.cs.findbugs.core.prefs <<EOF +excludefilter0=findbugs-exclude.xml|true +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false|20 +filter_settings_neg=NOISE,I18N,EXPERIMENTAL| +EOF diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java index 391c0026d49ce6d4bbb8997815a49c8a4b447b58..fe6be954075533f069481576f8e561e900c0b2c0 100644 --- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java +++ b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java @@ -69,8 +69,8 @@ public class OFMessageFilterManager // The port and client reference for packet streaming protected int serverPort = 9090; protected final int MaxRetry = 1; - protected static TTransport transport = null; - protected static PacketStreamer.Client packetClient = null; + protected static volatile TTransport transport = null; + protected static volatile PacketStreamer.Client packetClient = null; protected IFloodlightProviderService floodlightProvider = null; protected IThreadPoolService threadPool = null; @@ -112,7 +112,7 @@ public class OFMessageFilterManager int i; if ((filterMap == null) || (filterTimeoutMap == null)) - return String.format("%d", FILTER_SETUP_FAILED); + return String.format("%s", FILTER_SETUP_FAILED); for (i=0; i<MAX_FILTERS; ++i) { Integer x = prime + i; @@ -287,15 +287,17 @@ public class OFMessageFilterManager while (numRetries++ < MaxRetry) { try { - transport = new TFramedTransport(new TSocket("localhost", - serverPort)); - transport.open(); + TFramedTransport t = + new TFramedTransport(new TSocket("localhost", + serverPort)); + t.open(); - TProtocol protocol = new TBinaryProtocol(transport); + TProtocol protocol = new TBinaryProtocol(t); packetClient = new PacketStreamer.Client(protocol); log.debug("Have a connection to packetstreamer server " + "localhost:{}", serverPort); + transport = t; break; } catch (TException x) { try { diff --git a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java index 17bbcf07e292b25b7ad2dae2c675a80389aa199e..98eb372404b3bbcf490d5dcde5bd43baaee43afc 100644 --- a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java +++ b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java @@ -30,14 +30,11 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProviderService; -import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IFloodlightProviderService.Role; -import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.annotations.LogMessageDoc; import net.floodlightcontroller.core.internal.Controller; import net.floodlightcontroller.core.internal.OFFeaturesReplyFuture; @@ -56,11 +53,11 @@ import org.openflow.protocol.OFFlowMod; import org.openflow.protocol.OFMatch; import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFPhysicalPort; -import org.openflow.protocol.OFPort; -import org.openflow.protocol.OFType; import org.openflow.protocol.OFPhysicalPort.OFPortConfig; import org.openflow.protocol.OFPhysicalPort.OFPortState; +import org.openflow.protocol.OFPort; import org.openflow.protocol.OFStatisticsRequest; +import org.openflow.protocol.OFType; import org.openflow.protocol.statistics.OFStatistics; import org.openflow.util.HexString; import org.openflow.util.U16; @@ -93,8 +90,8 @@ public abstract class OFSwitchBase implements IOFSwitch { * Members hidden from subclasses */ private Channel channel; - private AtomicInteger transactionIdSource; - // Lock to protect modification of the port maps. We only need to + private final AtomicInteger transactionIdSource; + // Lock to protect modification of the port maps. We only need to // synchronize on modifications. For read operations we are fine since // we rely on ConcurrentMaps which works for our use case. protected Object portLock; @@ -102,18 +99,18 @@ public abstract class OFSwitchBase implements IOFSwitch { protected ConcurrentHashMap<Short, OFPhysicalPort> portsByNumber; // Map port names to the appropriate OFPhyiscalPort // XXX: The OF spec doesn't specify if port names need to be unique but - // according it's always the case in practice. - private ConcurrentHashMap<String, OFPhysicalPort> portsByName; - private Map<Integer,OFStatisticsFuture> statsFutureMap; - private Map<Integer, IOFMessageListener> iofMsgListenersMap; - private Map<Integer,OFFeaturesReplyFuture> featuresFutureMap; + // according it's always the case in practice. + private final ConcurrentHashMap<String, OFPhysicalPort> portsByName; + private final Map<Integer,OFStatisticsFuture> statsFutureMap; + private final Map<Integer, IOFMessageListener> iofMsgListenersMap; + private final Map<Integer,OFFeaturesReplyFuture> featuresFutureMap; private volatile boolean connected; - private TimedCache<Long> timedCache; - private ReentrantReadWriteLock listenerLock; - private ConcurrentMap<Short, Long> portBroadcastCacheHitMap; - + private final TimedCache<Long> timedCache; + private final ReentrantReadWriteLock listenerLock; + private final ConcurrentMap<Short, AtomicLong> portBroadcastCacheHitMap; + - protected static ThreadLocal<Map<IOFSwitch,List<OFMessage>>> local_msg_buffer = + protected final static ThreadLocal<Map<IOFSwitch,List<OFMessage>>> local_msg_buffer = new ThreadLocal<Map<IOFSwitch,List<OFMessage>>>() { @Override protected Map<IOFSwitch,List<OFMessage>> initialValue() { @@ -139,8 +136,8 @@ public abstract class OFSwitchBase implements IOFSwitch { this.role = null; this.timedCache = new TimedCache<Long>(100, 5*1000 ); // 5 seconds interval this.listenerLock = new ReentrantReadWriteLock(); - this.portBroadcastCacheHitMap = new ConcurrentHashMap<Short, Long>(); - + this.portBroadcastCacheHitMap = new ConcurrentHashMap<Short, AtomicLong>(); + // Defaults properties for an ideal switch this.setAttribute(PROP_FASTWILDCARDS, OFMatch.OFPFW_ALL); this.setAttribute(PROP_SUPPORTS_OFPP_FLOOD, new Boolean(true)); @@ -524,10 +521,17 @@ public abstract class OFSwitchBase implements IOFSwitch { @Override public boolean updateBroadcastCache(Long entry, Short port) { if (timedCache.update(entry)) { - Long count = portBroadcastCacheHitMap.putIfAbsent(port, new Long(1)); - if (count != null) { - count++; + AtomicLong count = portBroadcastCacheHitMap.get(port); + if(count == null) { + AtomicLong newCount = new AtomicLong(0); + AtomicLong retrieved; + if((retrieved = portBroadcastCacheHitMap.putIfAbsent(port, newCount)) == null ) { + count = newCount; + } else { + count = retrieved; + } } + count.incrementAndGet(); return true; } else { return false; @@ -537,20 +541,36 @@ public abstract class OFSwitchBase implements IOFSwitch { @Override @JsonIgnore public Map<Short, Long> getPortBroadcastHits() { - return this.portBroadcastCacheHitMap; + Map<Short, Long> res = new HashMap<Short, Long>(); + for (Map.Entry<Short, AtomicLong> entry : portBroadcastCacheHitMap.entrySet()) { + res.put(entry.getKey(), entry.getValue().get()); + } + return res; } - @Override public void flush() { Map<IOFSwitch,List<OFMessage>> msg_buffer_map = local_msg_buffer.get(); List<OFMessage> msglist = msg_buffer_map.get(this); if ((msglist != null) && (msglist.size() > 0)) { + /* ============================ BIG CAVEAT =============================== + * This code currently works, but relies on undocumented behavior of + * netty. + * + * The method org.jboss.netty.channel.Channel.write(Object) + * (invoked from this.write(List<OFMessage> msg) is currently + * documented to be <emph>asynchronous</emph>. If the method /were/ truely + * asynchronous, this would break our code (because we are clearing the + * msglist right after calling write. + * + * For now, Netty actually invokes the conversion pipeline before doing + * anything asynchronous, so we are safe. But we should probably change + * that behavior. + */ try { this.write(msglist); } catch (IOException e) { - // TODO: log exception - e.printStackTrace(); + log.error("Error flushing local message buffer: "+e.getMessage(), e); } msglist.clear(); } diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index 73f3bed6632d2efa7a515b738588dd4892b3a233..1a41b9bb7a6c1b5a8850becf8629fd8a358aa278 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -1795,7 +1795,17 @@ public class Controller implements IFloodlightProviderService, this.roleChanger = new RoleChanger(this); initVendorMessages(); this.systemStartTime = System.currentTimeMillis(); - } + + String option = configParams.get("flushSwitchesOnReconnect"); + + if (option != null && option.equalsIgnoreCase("true")) { + this.setAlwaysClearFlowsOnSwAdd(true); + log.info("Flush switches on reconnect -- Enabled."); + } else { + this.setAlwaysClearFlowsOnSwAdd(false); + log.info("Flush switches on reconnect -- Disabled"); + } + } /** * Startup all of the controller's components @@ -1891,7 +1901,6 @@ public class Controller implements IFloodlightProviderService, /** * Handle changes to the controller nodes IPs and dispatch update. */ - @SuppressWarnings("unchecked") protected void handleControllerNodeIPChanges() { HashMap<String,String> curControllerNodeIPs = new HashMap<String,String>(); HashMap<String,String> addedControllerNodeIPs = new HashMap<String,String>(); @@ -1921,7 +1930,7 @@ public class Controller implements IFloodlightProviderService, // new controller node IP addedControllerNodeIPs.put(controllerID, discoveredIP); } - else if (curIP != discoveredIP) { + else if (!curIP.equals(discoveredIP)) { // IP changed removedControllerNodeIPs.put(controllerID, curIP); addedControllerNodeIPs.put(controllerID, discoveredIP); @@ -1936,7 +1945,8 @@ public class Controller implements IFloodlightProviderService, removedEntries.removeAll(curEntries); for (String removedControllerID : removedEntries) removedControllerNodeIPs.put(removedControllerID, controllerNodeIPsCache.get(removedControllerID)); - controllerNodeIPsCache = (HashMap<String, String>) curControllerNodeIPs.clone(); + controllerNodeIPsCache.clear(); + controllerNodeIPsCache.putAll(curControllerNodeIPs); HAControllerNodeIPUpdate update = new HAControllerNodeIPUpdate( curControllerNodeIPs, addedControllerNodeIPs, removedControllerNodeIPs); @@ -2014,5 +2024,4 @@ public class Controller implements IFloodlightProviderService, switchDescSortedList.add(description); } } - } diff --git a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java index c90db7a60341618c4d68a8cf62ae9cffa88ea6c1..9a8f95068e148b287ff672ab59efe2170e5758f6 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java +++ b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java @@ -306,7 +306,9 @@ public class RoleChanger { = pendingRequestMap.get(sw); if (pendingList == null) { pendingList = new LinkedList<PendingRoleRequestEntry>(); - pendingRequestMap.put(sw, pendingList); + LinkedList<PendingRoleRequestEntry> r = + pendingRequestMap.putIfAbsent(sw, pendingList); + if (r != null) pendingList = r; } int xid = sendHARoleRequest(sw, role, cookie); PendingRoleRequestEntry entry = diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java index d012fc8e4a5138c674cc1086452806461b83abe5..37e6c8402d8ed3ebf1b1caa6234fd4c6ef7f1513 100644 --- a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java @@ -24,8 +24,6 @@ import java.util.List; import java.util.Map; import net.floodlightcontroller.core.IFloodlightProviderService; -import net.floodlightcontroller.core.types.MacVlanPair; - import org.openflow.protocol.OFFeaturesReply; import org.openflow.protocol.statistics.OFStatistics; import org.openflow.protocol.statistics.OFStatisticsType; @@ -136,7 +134,6 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { private OFStatisticsType statType; private REQUESTTYPE requestType; private OFFeaturesReply featuresReply; - private Map<MacVlanPair, Short> switchTable; public GetConcurrentStatsThread(long switchId, REQUESTTYPE requestType, OFStatisticsType statType) { this.switchId = switchId; @@ -144,7 +141,6 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { this.statType = statType; this.switchReply = null; this.featuresReply = null; - this.switchTable = null; } public List<OFStatistics> getStatisticsReply() { @@ -155,10 +151,6 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { return featuresReply; } - public Map<MacVlanPair, Short> getSwitchTable() { - return switchTable; - } - public long getSwitchId() { return switchId; } diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java index 3c3d599f5443ac05db3325981145c2806e4c9abd..1221e66887666765574bc543cd57a049e839f616 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceListener.java @@ -17,13 +17,15 @@ package net.floodlightcontroller.devicemanager; +import net.floodlightcontroller.core.IListener; + /** * Implementors of this interface can receive updates from DeviceManager about * the state of devices under its control. * * @author David Erickson (daviderickson@cs.stanford.edu) */ -public interface IDeviceListener { +public interface IDeviceListener extends IListener<String> { /** * Called when a new Device is found * @param device the device that changed diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java index 1164163f522dee9f93bc617a7b84980b5e673297..69fac694665f14e6df08ada226d0a5496e2b9884 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java @@ -31,22 +31,6 @@ import net.floodlightcontroller.core.module.IFloodlightService; */ public interface IDeviceService extends IFloodlightService { - /** - * IDeviceListeners do one of two actions on devices in response to the device events: - * 1. Reclassify device - * 2. Reconcile flows for the device. - * - * We must make sure all device classification are done before flow reconciliation. - * So all listeners are grouped into two groups based on their types. - * Reclassification group is notified first, then the reconciliation group. - * - * When a module registers as a listener, it must specify the type. - */ - enum ListenerType { - DeviceClassifier, // Listener should only do device classification change. - DeviceReconciler, // Listener should do reconciliation only - } - /** * Fields used in devices for indexes and querying * @see IDeviceService#addIndex @@ -208,7 +192,7 @@ public interface IDeviceService extends IFloodlightService { * @param listener The listener that wants the notifications * @param type The type of the listener */ - public void addListener(IDeviceListener listener, ListenerType type); + public void addListener(IDeviceListener listener); /** * Specify points in the network where attachment points are not to diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index dff8cba7c1f5be868c3348c5d34cc337fd3a2f4e..5796830ba388189cb15ee339bf4891c2a8cb6ce6 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -47,6 +47,7 @@ import net.floodlightcontroller.core.IFloodlightProviderService.Role; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; +import net.floodlightcontroller.core.util.ListenerDispatcher; import net.floodlightcontroller.core.util.SingletonTask; import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.devicemanager.IDeviceService; @@ -200,8 +201,7 @@ IFlowReconcileListener, IInfoProvider, IHAListener { * reclassifyDeviceListeners are notified first before reconcileDeviceListeners. * This is to make sure devices are correctly reclassified before reconciliation. */ - protected Set<IDeviceListener> reclassifyDeviceListeners; - protected Set<IDeviceListener> reconcileDeviceListeners; + protected ListenerDispatcher<String,IDeviceListener> deviceListeners; /** * A device update event to be dispatched @@ -526,14 +526,21 @@ IFlowReconcileListener, IInfoProvider, IHAListener { } @Override - public void addListener(IDeviceListener listener, ListenerType type) { - switch (type) { - case DeviceClassifier: - reclassifyDeviceListeners.add(listener); - break; - case DeviceReconciler: - reconcileDeviceListeners.add(listener); - break; + public void addListener(IDeviceListener listener) { + deviceListeners.addListener("device", listener); + logListeners(); + } + + private void logListeners() { + List<IDeviceListener> listeners = deviceListeners.getOrderedListeners(); + if (listeners != null) { + StringBuffer sb = new StringBuffer(); + sb.append("DeviceListeners: "); + for (IDeviceListener l : listeners) { + sb.append(l.getName()); + sb.append(","); + } + logger.debug(sb.toString()); } } @@ -684,8 +691,7 @@ IFlowReconcileListener, IInfoProvider, IHAListener { new HashSet<EnumSet<DeviceField>>(); addIndex(true, EnumSet.of(DeviceField.IPV4)); - this.reclassifyDeviceListeners = new HashSet<IDeviceListener>(); - this.reconcileDeviceListeners = new HashSet<IDeviceListener>(); + this.deviceListeners = new ListenerDispatcher<String, IDeviceListener>(); this.suppressAPs = Collections.newSetFromMap( new ConcurrentHashMap<SwitchPort, Boolean>()); @@ -1323,12 +1329,15 @@ IFlowReconcileListener, IInfoProvider, IHAListener { if (logger.isTraceEnabled()) { logger.trace("Dispatching device update: {}", update); } - notifyListeners(reclassifyDeviceListeners, update); - notifyListeners(reconcileDeviceListeners, update); + List<IDeviceListener> listeners = deviceListeners.getOrderedListeners(); + notifyListeners(listeners, update); } } - protected void notifyListeners(Set<IDeviceListener> listeners, DeviceUpdate update) { + protected void notifyListeners(List<IDeviceListener> listeners, DeviceUpdate update) { + if (listeners == null) { + return; + } for (IDeviceListener listener : listeners) { switch (update.change) { case ADD: @@ -1729,11 +1738,11 @@ IFlowReconcileListener, IInfoProvider, IHAListener { * @param updates the updates to process. */ protected void sendDeviceMovedNotification(Device d) { - for (IDeviceListener listener : reclassifyDeviceListeners) { - listener.deviceMoved(d); - } - for (IDeviceListener listener : reconcileDeviceListeners) { - listener.deviceMoved(d); + List<IDeviceListener> listeners = deviceListeners.getOrderedListeners(); + if (listeners != null) { + for (IDeviceListener listener : listeners) { + listener.deviceMoved(d); + } } } diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java b/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java index 58e79e49432764453b57af4dd7d1d61145c1bcc2..7866b7914a57f0e7e91f6e2b2283a12c3df64d46 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/web/AbstractDeviceResource.java @@ -156,8 +156,9 @@ public abstract class AbstractDeviceResource extends ServerResource { if (ipv4StartsWith != null) { boolean match = false; for (Integer v : value.getIPv4Addresses()) { - String str = IPv4.fromIPv4Address(v); + String str; if (v != null && + (str = IPv4.fromIPv4Address(v)) != null && str.startsWith(ipv4StartsWith)) { match = true; break; @@ -168,9 +169,10 @@ public abstract class AbstractDeviceResource extends ServerResource { if (dpidStartsWith != null) { boolean match = false; for (SwitchPort v : value.getAttachmentPoints(true)) { - String str = - HexString.toHexString(v.getSwitchDPID(), 8); + String str; if (v != null && + (str = HexString.toHexString(v.getSwitchDPID(), + 8)) != null && str.startsWith(dpidStartsWith)) { match = true; break; @@ -181,8 +183,9 @@ public abstract class AbstractDeviceResource extends ServerResource { if (portStartsWith != null) { boolean match = false; for (SwitchPort v : value.getAttachmentPoints(true)) { - String str = Integer.toString(v.getPort()); + String str; if (v != null && + (str = Integer.toString(v.getPort())) != null && str.startsWith(portStartsWith)) { match = true; break; diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java index 4e4e07db9cd73899fef3e9b091d53ac19831b6ef..e946d7b8aa7674ad598ba022e75e556ca9780297 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java @@ -64,7 +64,10 @@ public class DeviceSerializer extends JsonSerializer<Device> { jGen.writeNumberField("lastSeen", device.getLastSeen().getTime()); - jGen.writeStringField("dhcpClientName", device.getDHCPClientName()); + String dhcpClientName = device.getDHCPClientName(); + if (dhcpClientName != null) { + jGen.writeStringField("dhcpClientName", dhcpClientName); + } jGen.writeEndObject(); } diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java index 6ec91da2e1c0958d18213feea5dbfa0644dd5d4a..c6a4fd763df1df46babb4b92fef411070365d7c8 100644 --- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java +++ b/src/main/java/net/floodlightcontroller/firewall/Firewall.java @@ -359,9 +359,7 @@ public class Firewall implements IFirewallService, IOFMessageListener, // storage, create table and read rules storageSource.createTable(TABLE_NAME, null); storageSource.setTablePrimaryKeyName(TABLE_NAME, COLUMN_RULEID); - synchronized (rules) { - this.rules = readRulesFromStorage(); - } + this.rules = readRulesFromStorage(); } @Override diff --git a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java index 8cad49b3148252197ba199e88ed1c2afa1d5cc03..4e48683cb2ff79322b083de8bbf4dc1c43461556 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java +++ b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java @@ -82,46 +82,58 @@ public class FCQueryObj { + evType + ", callerOpaqueObj=" + callerOpaqueObj + "]"; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((applInstName == null) ? 0 : applInstName.hashCode()); + result = prime * result + + ((callerName == null) ? 0 : callerName.hashCode()); + result = prime + * result + + ((callerOpaqueObj == null) ? 0 + : callerOpaqueObj.hashCode()); + result = prime * result + + ((dstDevice == null) ? 0 : dstDevice.hashCode()); + result = prime * result + ((evType == null) ? 0 : evType.hashCode()); + result = prime + * result + + ((fcQueryHandler == null) ? 0 : fcQueryHandler.hashCode()); + result = prime * result + + ((srcDevice == null) ? 0 : srcDevice.hashCode()); + result = prime * result + Arrays.hashCode(vlans); + return result; + } + @Override public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; FCQueryObj other = (FCQueryObj) obj; if (applInstName == null) { - if (other.applInstName != null) - return false; - } else if (!applInstName.equals(other.applInstName)) - return false; + if (other.applInstName != null) return false; + } else if (!applInstName.equals(other.applInstName)) return false; if (callerName == null) { - if (other.callerName != null) - return false; - } else if (!callerName.equals(other.callerName)) - return false; + if (other.callerName != null) return false; + } else if (!callerName.equals(other.callerName)) return false; if (callerOpaqueObj == null) { - if (other.callerOpaqueObj != null) - return false; + if (other.callerOpaqueObj != null) return false; } else if (!callerOpaqueObj.equals(other.callerOpaqueObj)) - return false; + return false; if (dstDevice == null) { - if (other.dstDevice != null) - return false; - } else if (!dstDevice.equals(other.dstDevice)) - return false; - if (evType != other.evType) - return false; - if (fcQueryHandler != other.fcQueryHandler) - return false; + if (other.dstDevice != null) return false; + } else if (!dstDevice.equals(other.dstDevice)) return false; + if (evType != other.evType) return false; + if (fcQueryHandler == null) { + if (other.fcQueryHandler != null) return false; + } else if (!fcQueryHandler.equals(other.fcQueryHandler)) + return false; if (srcDevice == null) { - if (other.srcDevice != null) - return false; - } else if (!srcDevice.equals(other.srcDevice)) - return false; - if (!Arrays.equals(vlans, other.vlans)) - return false; + if (other.srcDevice != null) return false; + } else if (!srcDevice.equals(other.srcDevice)) return false; + if (!Arrays.equals(vlans, other.vlans)) return false; return true; } diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java index 37de44e2626cc791fa42bcefe4d79e603b82fcc9..ba31a3adf9b680e0ad48d715c57dbf0d602b2021 100644 --- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java +++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java @@ -234,6 +234,9 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule { while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) { SwitchPort srcDap = srcDaps[iSrcDaps]; SwitchPort dstDap = dstDaps[iDstDaps]; + + // srcCluster and dstCluster here cannot be null as + // every switch will be at least in its own L2 domain. Long srcCluster = topology.getL2DomainId(srcDap.getSwitchDPID()); Long dstCluster = @@ -241,9 +244,7 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule { int srcVsDest = srcCluster.compareTo(dstCluster); if (srcVsDest == 0) { - if (!srcDap.equals(dstDap) && - (srcCluster != null) && - (dstCluster != null)) { + if (!srcDap.equals(dstDap)) { Route route = routingEngine.getRoute(srcDap.getSwitchDPID(), (short)srcDap.getPort(), diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java index 441347e20fb65ce802dd9ec6635bf1be06e22433..4e2ffb1dbe11c3ce4d89fa110adbc42287c611e7 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscoveryService.java @@ -104,4 +104,14 @@ public interface ILinkDiscoveryService extends IFloodlightService { */ public Map<NodePortTuple, Set<Link>> getPortLinks(); + /** + * Add a MAC address range to ignore list. All packet ins from this range + * will be dropped + * @param mac The base MAC address that is to be ignored + * @param ignoreBits The number of LSBs to ignore. A value of 0 will add + * only one MAC address 'mac' to ignore list. A value of 48 will add + * ALL MAC addresses to the ignore list. This will cause a drop of + * ALL packet ins. + */ + public void addMACToIgnoreList(long mac, int ignoreBits); } diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java index 107114b4daed6368c4c56c5ab86f6c6e13983bc6..f35a556f621a38fdad5d442c5ec7ca63a0268edd 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java @@ -187,7 +187,7 @@ public class LinkDiscoveryManager implements IOFMessageListener, * Flag to indicate if automatic port fast is enabled or not. Default is set * to false -- Initialized in the init method as well. */ - public final boolean AUTOPORTFAST_DEFAULT = false; + protected boolean AUTOPORTFAST_DEFAULT = false; protected boolean autoPortFastFeature = AUTOPORTFAST_DEFAULT; /** @@ -246,6 +246,12 @@ public class LinkDiscoveryManager implements IOFMessageListener, */ protected Map<NodePortTuple, Long> broadcastDomainPortTimeMap; + private class MACRange { + long baseMAC; + int ignoreBits; + } + protected Set<MACRange> ignoreMACSet; + /** * Get the LLDP sending period in seconds. * @@ -1098,6 +1104,10 @@ public class LinkDiscoveryManager implements IOFMessageListener, } } + if (ignorePacketInFromSource(eth.getSourceMAC().toLong())) { + return Command.STOP; + } + // If packet-in is from a quarantine port, stop processing. NodePortTuple npt = new NodePortTuple(sw, pi.getInPort()); if (quarantineQueue.contains(npt)) return Command.STOP; @@ -1477,6 +1487,8 @@ public class LinkDiscoveryManager implements IOFMessageListener, } IOFSwitch iofSwitch = floodlightProvider.getSwitches().get(sw); + if (iofSwitch == null) return; + if (autoPortFastFeature && iofSwitch.isFastPort(p)) { // Do nothing as the port is a fast port. return; @@ -1690,14 +1702,14 @@ public class LinkDiscoveryManager implements IOFMessageListener, srcNpt = new NodePortTuple(lt.getSrc(), lt.getSrcPort()); dstNpt = new NodePortTuple(lt.getDst(), lt.getDstPort()); - if (!portBroadcastDomainLinks.containsKey(lt.getSrc())) - portBroadcastDomainLinks.put(srcNpt, - new HashSet<Link>()); + if (!portBroadcastDomainLinks.containsKey(srcNpt)) + portBroadcastDomainLinks.put(srcNpt, + new HashSet<Link>()); portBroadcastDomainLinks.get(srcNpt).add(lt); - if (!portBroadcastDomainLinks.containsKey(lt.getDst())) - portBroadcastDomainLinks.put(dstNpt, - new HashSet<Link>()); + if (!portBroadcastDomainLinks.containsKey(dstNpt)) + portBroadcastDomainLinks.put(dstNpt, + new HashSet<Link>()); portBroadcastDomainLinks.get(dstNpt).add(lt); } @@ -2034,7 +2046,7 @@ public class LinkDiscoveryManager implements IOFMessageListener, log.debug("Event history size set to {}", EVENT_HISTORY_SIZE); // Set the autoportfast feature to false. - this.autoPortFastFeature = false; + this.autoPortFastFeature = AUTOPORTFAST_DEFAULT; // We create this here because there is no ordering guarantee this.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>(); @@ -2051,6 +2063,7 @@ public class LinkDiscoveryManager implements IOFMessageListener, this.evHistTopologySwitch = new EventHistory<EventHistoryTopologySwitch>(EVENT_HISTORY_SIZE); this.evHistTopologyLink = new EventHistory<EventHistoryTopologyLink>(EVENT_HISTORY_SIZE); this.evHistTopologyCluster = new EventHistory<EventHistoryTopologyCluster>(EVENT_HISTORY_SIZE); + this.ignoreMACSet = new HashSet<MACRange>(); } @Override @@ -2314,6 +2327,29 @@ public class LinkDiscoveryManager implements IOFMessageListener, this.autoPortFastFeature = autoPortFastFeature; } + @Override + public void addMACToIgnoreList(long mac, int ignoreBits) { + MACRange range = new MACRange(); + range.baseMAC = mac; + range.ignoreBits = ignoreBits; + ignoreMACSet.add(range); + } + + private boolean ignorePacketInFromSource(long srcMAC) { + Iterator<MACRange> it = ignoreMACSet.iterator(); + while (it.hasNext()) { + MACRange range = it.next(); + long mask = ~0; + if (range.ignoreBits >= 0 && range.ignoreBits <= 48) { + mask = mask << range.ignoreBits; + if ((range.baseMAC & mask) == (srcMAC & mask)) { + return true; + } + } + } + return false; + } + public void readTopologyConfigFromStorage() { IResultSet topologyResult = storageSource.executeQuery(TOPOLOGY_TABLE_NAME, null, null, diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java index e67a2fb2948cc547d3d644b39a5a0acb60c23cc6..83b9eaf573ea92e41603eb8bacd706bcf16e32eb 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java @@ -668,9 +668,8 @@ public class LoadBalancer implements IFloodlightModule, @Override public int removePool(String poolId) { LBPool pool; - pool = pools.get(poolId); - if(pools!=null){ + pool = pools.get(poolId); if (pool.vipId != null) vips.get(pool.vipId).pools.remove(poolId); pools.remove(poolId); diff --git a/src/main/java/net/floodlightcontroller/packet/BSNPROBE.java b/src/main/java/net/floodlightcontroller/packet/BSNPROBE.java index 720b45f1c5b0fda4df580cb5c2fe9a341b1872d1..1343f769b86f45399f33357ff3932092007c562c 100644 --- a/src/main/java/net/floodlightcontroller/packet/BSNPROBE.java +++ b/src/main/java/net/floodlightcontroller/packet/BSNPROBE.java @@ -143,43 +143,38 @@ public class BSNPROBE extends BasePacket { return this; } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ + @Override public int hashCode() { - final int prime = 883; + final int prime = 31; int result = super.hashCode(); - result = prime * result + srcMac.hashCode(); - result = prime * result + dstMac.hashCode(); - result = prime * result + (int) (srcSwDpid >> 32) + (int) srcSwDpid; + result = prime * result + + (int) (controllerId ^ (controllerId >>> 32)); + result = prime * result + Arrays.hashCode(dstMac); + result = prime * result + sequenceId; + result = prime * result + Arrays.hashCode(srcMac); result = prime * result + srcPortNo; + result = prime * result + (int) (srcSwDpid ^ (srcSwDpid >>> 32)); return result; } - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ + @Override public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (!(obj instanceof BSNPROBE)) - return false; + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; BSNPROBE other = (BSNPROBE) obj; - if (!Arrays.equals(srcMac, other.srcMac)) - return false; - if (!Arrays.equals(dstMac, other.dstMac)) - return false; - return (sequenceId == other.sequenceId && - srcSwDpid == other.srcSwDpid && - srcPortNo == other.srcPortNo - ); + if (controllerId != other.controllerId) return false; + if (!Arrays.equals(dstMac, other.dstMac)) return false; + if (sequenceId != other.sequenceId) return false; + if (!Arrays.equals(srcMac, other.srcMac)) return false; + if (srcPortNo != other.srcPortNo) return false; + if (srcSwDpid != other.srcSwDpid) return false; + return true; } - + + public String toString() { StringBuffer sb = new StringBuffer("\n"); sb.append("BSN Probe packet"); diff --git a/src/main/java/net/floodlightcontroller/packet/DHCPPacketType.java b/src/main/java/net/floodlightcontroller/packet/DHCPPacketType.java index 3417a18a200ed980c758c13e3361162a35570779..e90bb147ce1c411dae818140a3ed0bfa7167b28a 100644 --- a/src/main/java/net/floodlightcontroller/packet/DHCPPacketType.java +++ b/src/main/java/net/floodlightcontroller/packet/DHCPPacketType.java @@ -77,9 +77,9 @@ public enum DHCPPacketType { return "DHCPLEASEUNKNOWN"; case 13: return "DHCPLEASEACTIVE"; + default: + return "UNKNOWN"; } - - return null; } public static DHCPPacketType getType(int value) { switch (value) { diff --git a/src/main/java/net/floodlightcontroller/packet/Ethernet.java b/src/main/java/net/floodlightcontroller/packet/Ethernet.java index 6bd627b0ef419ed02b51acededa6c0efa012c3ff..44a908118d9e649ec0421f5620684a9d967f6519 100644 --- a/src/main/java/net/floodlightcontroller/packet/Ethernet.java +++ b/src/main/java/net/floodlightcontroller/packet/Ethernet.java @@ -425,28 +425,6 @@ public class Ethernet extends BasePacket { sb.append(p.getDiffServ()); sb.append("\nnw_proto: "); sb.append(p.getProtocol()); - - if (pkt instanceof TCP) { - sb.append("\ntp_src: "); - sb.append(((TCP) pkt).getSourcePort()); - sb.append("\ntp_dst: "); - sb.append(((TCP) pkt).getDestinationPort()); - - } else if (pkt instanceof UDP) { - sb.append("\ntp_src: "); - sb.append(((UDP) pkt).getSourcePort()); - sb.append("\ntp_dst: "); - sb.append(((UDP) pkt).getDestinationPort()); - } - - if (pkt instanceof ICMP) { - ICMP icmp = (ICMP) pkt; - sb.append("\nicmp_type: "); - sb.append(icmp.getIcmpType()); - sb.append("\nicmp_code: "); - sb.append(icmp.getIcmpCode()); - } - } else if (pkt instanceof DHCP) { sb.append("\ndhcp packet"); diff --git a/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java b/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java index a0930bd0fcf73c977ae778ed6dcaf53cbbe15c24..830dea6050f876484c7d6e422ef9073233e2a07f 100644 --- a/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java +++ b/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java @@ -139,43 +139,23 @@ public class LLDPOrganizationalTLV extends LLDPTLV { @Override public int hashCode() { - final int prime = 1423; - int result = 1; - result = prime * result + type; - result = prime * result + length; + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Arrays.hashCode(infoString); result = prime * result + Arrays.hashCode(oui); result = prime * result + subType; - result = prime * result + Arrays.hashCode(infoString); return result; } @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - - if (!(o instanceof LLDPOrganizationalTLV)) { - return false; - } - - LLDPOrganizationalTLV other = (LLDPOrganizationalTLV)o; - if (this.type != other.type) { - return false; - } - if (this.length != other.length) { - return false; - } - if (!Arrays.equals(this.oui, other.oui)) { - return false; - } - if (this.subType != other.subType) { - return false; - } - if (!Arrays.equals(this.infoString, other.infoString)) { - return false; - } - + public boolean equals(Object obj) { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + LLDPOrganizationalTLV other = (LLDPOrganizationalTLV) obj; + if (!Arrays.equals(infoString, other.infoString)) return false; + if (!Arrays.equals(oui, other.oui)) return false; + if (subType != other.subType) return false; return true; } } diff --git a/src/main/java/net/floodlightcontroller/packet/TCP.java b/src/main/java/net/floodlightcontroller/packet/TCP.java index 06359e4af10df78ce891dc56bbeea316488b97e2..c282c5d8a03e05c672333e9b9cb476f27067094f 100644 --- a/src/main/java/net/floodlightcontroller/packet/TCP.java +++ b/src/main/java/net/floodlightcontroller/packet/TCP.java @@ -18,6 +18,7 @@ package net.floodlightcontroller.packet; import java.nio.ByteBuffer; +import java.util.Arrays; /** * @@ -253,7 +254,7 @@ public class TCP extends BasePacket { (flags == other.flags) && (windowSize == other.windowSize) && (urgentPointer == other.urgentPointer) && - (dataOffset == 5 || options.equals(other.options)); + (dataOffset == 5 || Arrays.equals(options,other.options)); } @Override diff --git a/src/main/java/net/floodlightcontroller/storage/RowOrdering.java b/src/main/java/net/floodlightcontroller/storage/RowOrdering.java index f9e61ed1ce089ef72056b57e51de2300c734a573..d24e8b1eb7ed4cbfb73b3aec792a624a363a1fcc 100644 --- a/src/main/java/net/floodlightcontroller/storage/RowOrdering.java +++ b/src/main/java/net/floodlightcontroller/storage/RowOrdering.java @@ -43,6 +43,36 @@ public class RowOrdering { public Direction getDirection() { return direction; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + result = prime * result + + ((column == null) ? 0 : column.hashCode()); + result = prime * result + + ((direction == null) ? 0 : direction.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Item other = (Item) obj; + if (!getOuterType().equals(other.getOuterType())) return false; + if (column == null) { + if (other.column != null) return false; + } else if (!column.equals(other.column)) return false; + if (direction != other.direction) return false; + return true; + } + + private RowOrdering getOuterType() { + return RowOrdering.this; + } } private List<Item> itemList = new ArrayList<Item>(); @@ -96,24 +126,25 @@ public class RowOrdering { public List<Item> getItemList() { return itemList; } - - public boolean equals(RowOrdering rowOrdering) { - if (rowOrdering == null) - return false; - - int len1 = itemList.size(); - int len2 = rowOrdering.getItemList().size(); - if (len1 != len2) - return false; - - for (int i = 0; i < len1; i++) { - Item item1 = itemList.get(i); - Item item2 = rowOrdering.getItemList().get(i); - if (!item1.getColumn().equals(item2.getColumn()) || - item1.getDirection() != item2.getDirection()) - return false; - } - + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((itemList == null) ? 0 : itemList.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + RowOrdering other = (RowOrdering) obj; + if (itemList == null) { + if (other.itemList != null) return false; + } else if (!itemList.equals(other.itemList)) return false; return true; } } diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java index 06bb592584c40abc77d9d0d36831485640949150..7bc878614d124540d3165d42f7fa35088caf78e8 100644 --- a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java +++ b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java @@ -479,6 +479,12 @@ public class TopologyInstance { return true; } + @Override + public int hashCode() { + assert false : "hashCode not designed"; + return 42; + } + private TopologyInstance getOuterType() { return TopologyInstance.this; } diff --git a/src/main/java/net/floodlightcontroller/util/LoadMonitor.java b/src/main/java/net/floodlightcontroller/util/LoadMonitor.java index 72bb8a217610fc5c6576708bac16b6918aafb909..5b234cd5e01113cf4311a6eaf56d6cf48b4843a4 100644 --- a/src/main/java/net/floodlightcontroller/util/LoadMonitor.java +++ b/src/main/java/net/floodlightcontroller/util/LoadMonitor.java @@ -205,17 +205,23 @@ public class LoadMonitor implements Runnable { protected long readIdle() { long idle = 0; - + FileInputStream fs = null; + BufferedReader reader = null; try { - FileInputStream fs = new FileInputStream("/proc/stat"); - BufferedReader reader = - new BufferedReader(new InputStreamReader(fs)); - idle = Long.parseLong(reader.readLine().split("\\s+")[4]); - reader.close(); - fs.close(); - } - catch (IOException ex) { - ex.printStackTrace(); + try { + fs = new FileInputStream("/proc/stat"); + reader = new BufferedReader(new InputStreamReader(fs)); + String line = reader.readLine(); + if (line == null) throw new IOException("Empty file"); + idle = Long.parseLong(line.split("\\s+")[4]); + } finally { + if (reader != null) + reader.close(); + if (fs != null) + fs.close(); + } + } catch (IOException ex) { + log.error("Error reading idle time from /proc/stat", ex); } return idle; diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java index 87dfc4a3966230357858c404d763e60c1a87377a..3e227bde13f3853eb45f8586a04cb3369346bf6d 100644 --- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java +++ b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java @@ -73,7 +73,7 @@ import net.floodlightcontroller.util.MACAddress; * @author alexreimers */ public class VirtualNetworkFilter - implements IFloodlightModule, IVirtualNetworkService, IOFMessageListener, IDeviceListener { + implements IFloodlightModule, IVirtualNetworkService, IOFMessageListener { protected static Logger log = LoggerFactory.getLogger(VirtualNetworkFilter.class); private final short APP_ID = 20; @@ -82,7 +82,7 @@ public class VirtualNetworkFilter IFloodlightProviderService floodlightProvider; IRestApiService restApi; IDeviceService deviceService; - + // Our internal state protected Map<String, VirtualNetwork> vNetsByGuid; // List of all created virtual networks protected Map<String, String> nameToGuid; // Logical name -> Network ID @@ -91,6 +91,9 @@ public class VirtualNetworkFilter protected Map<MACAddress, Integer> macToGateway; // Gateway MAC -> Gateway IP protected Map<MACAddress, String> macToGuid; // Host MAC -> Network ID protected Map<String, MACAddress> portToMac; // Host MAC -> logical port name + + // Device Listener impl class + protected DeviceListenerImpl deviceListener; /** * Adds a gateway to a virtual network. @@ -99,10 +102,11 @@ public class VirtualNetworkFilter */ protected void addGateway(String guid, Integer ip) { if (ip.intValue() != 0) { - if (log.isDebugEnabled()) - log.debug("Adding {} as gateway for GUID {}", - IPv4.fromIPv4Address(ip), guid); - + if (log.isDebugEnabled()) { + log.debug("Adding {} as gateway for GUID {}", + IPv4.fromIPv4Address(ip), guid); + } + guidToGateway.put(guid, ip); if (vNetsByGuid.get(guid) != null) vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(ip)); @@ -306,13 +310,14 @@ public class VirtualNetworkFilter macToGuid = new ConcurrentHashMap<MACAddress, String>(); portToMac = new ConcurrentHashMap<String, MACAddress>(); macToGateway = new ConcurrentHashMap<MACAddress, Integer>(); + deviceListener = new DeviceListenerImpl(); } @Override public void startUp(FloodlightModuleContext context) { floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); restApi.addRestletRoutable(new VirtualNetworkWebRoutable()); - deviceService.addListener(this, IDeviceService.ListenerType.DeviceClassifier); + deviceService.addListener(this.deviceListener); } // IOFMessageListener @@ -326,7 +331,7 @@ public class VirtualNetworkFilter public boolean isCallbackOrderingPrereq(OFType type, String name) { // Link discovery should go before us so we don't block LLDPs return (type.equals(OFType.PACKET_IN) && - (name.equals("linkdiscovery") || (name.equals("devicemanager")))); + (name.equals("linkdiscovery") || (name.equals("devicemanager")))); } @Override @@ -341,7 +346,7 @@ public class VirtualNetworkFilter case PACKET_IN: return processPacketIn(sw, (OFPacketIn)msg, cntx); default: - break; + break; } log.warn("Received unexpected message {}", msg); return Command.CONTINUE; @@ -353,21 +358,21 @@ public class VirtualNetworkFilter * @return True if it is to/from a gateway, false otherwise. */ protected boolean isDefaultGateway(Ethernet frame) { - if (macToGateway.containsKey(frame.getSourceMAC())) - return true; - - Integer gwIp = macToGateway.get(frame.getDestinationMAC()); - if (gwIp != null) { - MACAddress host = frame.getSourceMAC(); - String srcNet = macToGuid.get(host); - if (srcNet != null) { - Integer gwIpSrcNet = guidToGateway.get(srcNet); - if ((gwIpSrcNet != null) && (gwIp.equals(gwIpSrcNet))) - return true; - } - } + if (macToGateway.containsKey(frame.getSourceMAC())) + return true; + + Integer gwIp = macToGateway.get(frame.getDestinationMAC()); + if (gwIp != null) { + MACAddress host = frame.getSourceMAC(); + String srcNet = macToGuid.get(host); + if (srcNet != null) { + Integer gwIpSrcNet = guidToGateway.get(srcNet); + if ((gwIpSrcNet != null) && (gwIp.equals(gwIpSrcNet))) + return true; + } + } - return false; + return false; } /** @@ -375,7 +380,7 @@ public class VirtualNetworkFilter * @param m1 The first MAC. * @param m2 The second MAC. * @return True if they are on the same virtual network, - * false otherwise. + * false otherwise. */ protected boolean oneSameNetwork(MACAddress m1, MACAddress m2) { String net1 = macToGuid.get(m1); @@ -416,7 +421,7 @@ public class VirtualNetworkFilter // If the host is on an unknown network we deny it. // We make exceptions for ARP and DHCP. if (eth.isBroadcast() || eth.isMulticast() || isDefaultGateway(eth) || isDhcpPacket(eth)) { - ret = Command.CONTINUE; + ret = Command.CONTINUE; } else if (srcNetwork == null) { log.trace("Blocking traffic from host {} because it is not attached to any network.", HexString.toHexString(eth.getSourceMACAddress())); @@ -427,14 +432,14 @@ public class VirtualNetworkFilter } if (log.isTraceEnabled()) - log.trace("Results for flow between {} and {} is {}", - new Object[] {eth.getSourceMAC(), eth.getDestinationMAC(), ret}); + log.trace("Results for flow between {} and {} is {}", + new Object[] {eth.getSourceMAC(), eth.getDestinationMAC(), ret}); /* * TODO - figure out how to still detect gateways while using * drop mods if (ret == Command.STOP) { if (!(eth.getPayload() instanceof ARP)) - doDropFlow(sw, msg, cntx); + doDropFlow(sw, msg, cntx); } */ return ret; @@ -485,54 +490,70 @@ public class VirtualNetworkFilter return; } - // IDeviceListener + @Override + public Collection <VirtualNetwork> listNetworks() { + return vNetsByGuid.values(); + } - @Override - public void deviceAdded(IDevice device) { - if (device.getIPv4Addresses() == null) return; - for (Integer i : device.getIPv4Addresses()) { - if (gatewayToGuid.containsKey(i)) { - MACAddress mac = MACAddress.valueOf(device.getMACAddress()); - if (log.isDebugEnabled()) - log.debug("Adding MAC {} with IP {} a a gateway", - HexString.toHexString(mac.toBytes()), - IPv4.fromIPv4Address(i)); - macToGateway.put(mac, i); - } - } - } + // IDeviceListener + class DeviceListenerImpl implements IDeviceListener{ + @Override + public void deviceAdded(IDevice device) { + if (device.getIPv4Addresses() == null) return; + for (Integer i : device.getIPv4Addresses()) { + if (gatewayToGuid.containsKey(i)) { + MACAddress mac = MACAddress.valueOf(device.getMACAddress()); + if (log.isDebugEnabled()) + log.debug("Adding MAC {} with IP {} a a gateway", + HexString.toHexString(mac.toBytes()), + IPv4.fromIPv4Address(i)); + macToGateway.put(mac, i); + } + } + } - @Override - public void deviceRemoved(IDevice device) { - // if device is a gateway remove - MACAddress mac = MACAddress.valueOf(device.getMACAddress()); - if (macToGateway.containsKey(mac)) { - if (log.isDebugEnabled()) - log.debug("Removing MAC {} as a gateway", - HexString.toHexString(mac.toBytes())); - macToGateway.remove(mac); - } - } + @Override + public void deviceRemoved(IDevice device) { + // if device is a gateway remove + MACAddress mac = MACAddress.valueOf(device.getMACAddress()); + if (macToGateway.containsKey(mac)) { + if (log.isDebugEnabled()) + log.debug("Removing MAC {} as a gateway", + HexString.toHexString(mac.toBytes())); + macToGateway.remove(mac); + } + } - @Override - public void deviceIPV4AddrChanged(IDevice device) { - // add or remove entry as gateway - deviceAdded(device); - } + @Override + public void deviceIPV4AddrChanged(IDevice device) { + // add or remove entry as gateway + deviceAdded(device); + } - @Override - public void deviceMoved(IDevice device) { - // ignore - } - - @Override - public void deviceVlanChanged(IDevice device) { - // ignore - } + @Override + public void deviceMoved(IDevice device) { + // ignore + } - @Override - public Collection <VirtualNetwork> listNetworks() { - return vNetsByGuid.values(); - + @Override + public void deviceVlanChanged(IDevice device) { + // ignore + } + + @Override + public String getName() { + return VirtualNetworkFilter.this.getName(); + } + + @Override + public boolean isCallbackOrderingPrereq(String type, String name) { + return false; + } + + @Override + public boolean isCallbackOrderingPostreq(String type, String name) { + // We need to go before forwarding + return false; + } } } diff --git a/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java index 87a2465eaef54df954157d05edf53ab5052c95eb..9a84aad1edfba2357480c27dcde53f68e45ef595 100644 --- a/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java +++ b/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java @@ -1,7 +1,7 @@ /** * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior * University -* +* * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at @@ -18,7 +18,10 @@ package org.openflow.protocol.statistics; +import net.floodlightcontroller.core.web.serializers.UShortSerializer; + import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.map.annotate.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; /** @@ -43,6 +46,7 @@ public class OFPortStatisticsReply implements OFStatistics { /** * @return the portNumber */ + @JsonSerialize(using=UShortSerializer.class) public short getPortNumber() { return portNumber; } diff --git a/src/main/java/org/openflow/protocol/vendor/OFBasicVendorId.java b/src/main/java/org/openflow/protocol/vendor/OFBasicVendorId.java index 09365d7c5e23e77d2293165aa50816e2c6cd64c9..5f789dc3f9a661c8dc84d74904b209e004bef215 100644 --- a/src/main/java/org/openflow/protocol/vendor/OFBasicVendorId.java +++ b/src/main/java/org/openflow/protocol/vendor/OFBasicVendorId.java @@ -87,7 +87,7 @@ public class OFBasicVendorId extends OFVendorId { * @return */ public OFVendorDataType lookupVendorDataType(int vendorDataType) { - return dataTypeMap.get(vendorDataType); + return dataTypeMap.get(Long.valueOf(vendorDataType)); } /** diff --git a/src/main/java/org/openflow/util/HexString.java b/src/main/java/org/openflow/util/HexString.java index 030823eed81e0426cd7638a3cf1d8955a10ac6c0..b5628242dadcbc7a12ccd8568f9c00b319439783 100644 --- a/src/main/java/org/openflow/util/HexString.java +++ b/src/main/java/org/openflow/util/HexString.java @@ -48,12 +48,12 @@ public class HexString { int i = 0; for (; i < (padTo * 2 - arr.length); i++) { ret += "0"; - if ((i % 2) == 1) + if ((i % 2) != 0) ret += ":"; } for (int j = 0; j < arr.length; j++) { ret += arr[j]; - if ((((i + j) % 2) == 1) && (j < (arr.length - 1))) + if ((((i + j) % 2) != 0) && (j < (arr.length - 1))) ret += ":"; } return ret; diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java index 4524e72aa3f1827afdc0e2d8c65dba0bd84d3440..0d6ceb51ab80232f06a245fd598eab0481ae4756 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java @@ -29,6 +29,7 @@ public class OFSwitchImplTest extends FloodlightTestCase { @Before public void setUp() throws Exception { + super.setUp(); sw = new OFSwitchImpl(); } diff --git a/src/test/java/net/floodlightcontroller/core/util/SingletonTaskTest.java b/src/test/java/net/floodlightcontroller/core/util/SingletonTaskTest.java index 010c651acad79264e2a911477bdf3045f3643520..8203161d91739b541e99e3202adab2147dcdfd87 100644 --- a/src/test/java/net/floodlightcontroller/core/util/SingletonTaskTest.java +++ b/src/test/java/net/floodlightcontroller/core/util/SingletonTaskTest.java @@ -33,7 +33,9 @@ public class SingletonTaskTest extends FloodlightTestCase { public long time = 0; @Before - public void setup() { + public void setUp() throws Exception { + super.setUp(); + ran = 0; finished = 0; time = 0; diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java index 5e3d764dfaefc4fd1d49057cabfa36da27d38aa1..671ef50609cd3022dfbb5b31f199f377cbb750c9 100644 --- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java +++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java @@ -19,10 +19,10 @@ package net.floodlightcontroller.devicemanager.internal; import static org.easymock.EasyMock.anyLong; +import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.anyShort; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; -import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; @@ -47,7 +47,6 @@ import java.util.concurrent.ConcurrentHashMap; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; -import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockThreadPoolService; import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.devicemanager.IDeviceListener; @@ -97,7 +96,6 @@ public class DeviceManagerImplTest extends FloodlightTestCase { protected IPacket testARPReqPacket_1, testARPReqPacket_2; protected byte[] testARPReplyPacket_1_Srld, testARPReplyPacket_2_Srld; private byte[] testARPReplyPacket_3_Serialized; - MockFloodlightProvider mockFloodlightProvider; DeviceManagerImpl deviceManager; MemoryStorageSource storageSource; FlowReconcileManager flowReconcileMgr; @@ -275,9 +273,17 @@ public class DeviceManagerImplTest extends FloodlightTestCase { @Test public void testEntityLearning() throws Exception { IDeviceListener mockListener = - createStrictMock(IDeviceListener.class); + createMock(IDeviceListener.class); + expect(mockListener.getName()).andReturn("mockListener").atLeastOnce(); + expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); - deviceManager.addListener(mockListener, IDeviceService.ListenerType.DeviceClassifier); + replay(mockListener); + deviceManager.addListener(mockListener); + verify(mockListener); + reset(mockListener); deviceManager.entityClassifier= new MockEntityClassifier(); deviceManager.startUp(null); @@ -481,9 +487,17 @@ public class DeviceManagerImplTest extends FloodlightTestCase { @Test public void testAttachmentPointLearning() throws Exception { IDeviceListener mockListener = - createStrictMock(IDeviceListener.class); + createMock(IDeviceListener.class); + expect(mockListener.getName()).andReturn("mockListener").atLeastOnce(); + expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); - deviceManager.addListener(mockListener, IDeviceService.ListenerType.DeviceClassifier); + replay(mockListener); + deviceManager.addListener(mockListener); + verify(mockListener); + reset(mockListener); ITopologyService mockTopology = createMock(ITopologyService.class); expect(mockTopology.getL2DomainId(1L)). @@ -591,7 +605,16 @@ public class DeviceManagerImplTest extends FloodlightTestCase { IDeviceListener mockListener = createMock(IDeviceListener.class); - deviceManager.addListener(mockListener, IDeviceService.ListenerType.DeviceClassifier); + expect(mockListener.getName()).andReturn("mockListener").anyTimes(); + expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + + replay(mockListener); + deviceManager.addListener(mockListener); + verify(mockListener); + reset(mockListener); ITopologyService mockTopology = createMock(ITopologyService.class); expect(mockTopology.getL2DomainId(1L)). @@ -706,7 +729,16 @@ public class DeviceManagerImplTest extends FloodlightTestCase { IDeviceListener mockListener = createMock(IDeviceListener.class); - deviceManager.addListener(mockListener, IDeviceService.ListenerType.DeviceClassifier); + expect(mockListener.getName()).andReturn("mockListener").anyTimes(); + expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + + replay(mockListener); + deviceManager.addListener(mockListener); + verify(mockListener); + reset(mockListener); ITopologyService mockTopology = createMock(ITopologyService.class); expect(mockTopology.getL2DomainId(1L)). @@ -1053,8 +1085,12 @@ public class DeviceManagerImplTest extends FloodlightTestCase { */ public void doTestEntityExpiration() throws Exception { IDeviceListener mockListener = - createStrictMock(IDeviceListener.class); - mockListener.deviceIPV4AddrChanged(isA(IDevice.class)); + createMock(IDeviceListener.class); + expect(mockListener.getName()).andReturn("mockListener").anyTimes(); + expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); ITopologyService mockTopology = createMock(ITopologyService.class); expect(mockTopology.isAttachmentPointPort(anyLong(), @@ -1096,8 +1132,12 @@ public class DeviceManagerImplTest extends FloodlightTestCase { assertTrue(diter.hasNext()); assertEquals(d.getDeviceKey(), diter.next().getDeviceKey()); + replay(mockListener); + deviceManager.addListener(mockListener); + verify(mockListener); + reset(mockListener); - deviceManager.addListener(mockListener, IDeviceService.ListenerType.DeviceClassifier); + mockListener.deviceIPV4AddrChanged(isA(IDevice.class)); replay(mockListener); deviceManager.entityCleanupTask.reschedule(0, null); @@ -1129,8 +1169,12 @@ public class DeviceManagerImplTest extends FloodlightTestCase { public void doTestDeviceExpiration() throws Exception { IDeviceListener mockListener = - createStrictMock(IDeviceListener.class); - mockListener.deviceRemoved(isA(IDevice.class)); + createMock(IDeviceListener.class); + expect(mockListener.getName()).andReturn("mockListener").anyTimes(); + expect(mockListener.isCallbackOrderingPostreq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); + expect(mockListener.isCallbackOrderingPrereq((String)anyObject(), (String)anyObject())) + .andReturn(false).atLeastOnce(); Calendar c = Calendar.getInstance(); c.add(Calendar.MILLISECOND, -DeviceManagerImpl.ENTITY_TIMEOUT-1); @@ -1160,7 +1204,12 @@ public class DeviceManagerImplTest extends FloodlightTestCase { d = deviceManager.learnDeviceByEntity(entity1); assertArrayEquals(new Integer[] { 1, 2 }, d.getIPv4Addresses()); - deviceManager.addListener(mockListener, IDeviceService.ListenerType.DeviceClassifier); + replay(mockListener); + deviceManager.addListener(mockListener); + verify(mockListener); + reset(mockListener); + + mockListener.deviceRemoved(isA(IDevice.class)); replay(mockListener); deviceManager.entityCleanupTask.reschedule(0, null); diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java index d05197019fb6377187be89c305a11bd3f081273c..5657cc515792d534179e5d66116f362a232c2098 100644 --- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java +++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDevice.java @@ -18,6 +18,7 @@ package net.floodlightcontroller.devicemanager.test; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.TreeSet; @@ -81,12 +82,11 @@ public class MockDevice extends Device { } return vals.toArray(new SwitchPort[vals.size()]); } - + @Override public String toString() { - String rv = "MockDevice[entities=+"; - rv += entities.toString(); - rv += "]"; - return rv; + return "MockDevice [getEntityClass()=" + getEntityClass() + + ", getEntities()=" + Arrays.toString(getEntities()) + "]"; } + } diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java index dd105bba873eb575be5dacee7952581a95338613..f543086b821567409936d6daeda9af09e0823339 100644 --- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java +++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java @@ -17,10 +17,8 @@ package net.floodlightcontroller.devicemanager.test; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Set; import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.devicemanager.IDeviceListener; @@ -63,11 +61,9 @@ public class MockDeviceManager extends DeviceManagerImpl { Integer ipv4Address, Long switchDPID, Integer switchPort, boolean processUpdates) { - Set<IDeviceListener> reclassifyListeners = reclassifyDeviceListeners; - Set<IDeviceListener> reconcileListeners = reconcileDeviceListeners; + List<IDeviceListener> listeners = deviceListeners.getOrderedListeners(); if (!processUpdates) { - reclassifyDeviceListeners = Collections.<IDeviceListener>emptySet(); - reconcileDeviceListeners = Collections.<IDeviceListener>emptySet(); + deviceListeners.clearListeners(); } if (vlan != null && vlan.shortValue() <= 0) @@ -77,8 +73,12 @@ public class MockDeviceManager extends DeviceManagerImpl { IDevice res = learnDeviceByEntity(new Entity(macAddress, vlan, ipv4Address, switchDPID, switchPort, new Date())); - reclassifyDeviceListeners = reclassifyListeners; - reconcileDeviceListeners = reconcileListeners; + // Restore listeners + if (listeners != null) { + for (IDeviceListener listener : listeners) { + deviceListeners.addListener("device", listener); + } + } return res; } diff --git a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java index 4e8e0f3ab5530a9536786f2bce7c1759de5fcea8..5de211420fb9c5dd2a810eed6e31d942404395ca 100644 --- a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java +++ b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java @@ -30,7 +30,6 @@ import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; -import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.packet.ARP; import net.floodlightcontroller.packet.Data; import net.floodlightcontroller.packet.Ethernet; @@ -60,7 +59,6 @@ import org.openflow.util.HexString; * @author Amer Tahir */ public class FirewallTest extends FloodlightTestCase { - protected MockFloodlightProvider mockFloodlightProvider; protected FloodlightContext cntx; protected OFPacketIn packetIn; protected IOFSwitch sw; diff --git a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java index 0d19e036f7d94c637c23b8b0a68c763d7ed6a40b..a66fac238c5448d92abc5108a7df193aafe4a085 100644 --- a/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java +++ b/src/test/java/net/floodlightcontroller/flowcache/FlowReconcileMgrTest.java @@ -24,7 +24,6 @@ import java.util.ListIterator; import net.floodlightcontroller.core.IListener.Command; import net.floodlightcontroller.core.module.FloodlightModuleContext; -import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockThreadPoolService; import net.floodlightcontroller.counter.ICounterStoreService; import net.floodlightcontroller.counter.SimpleCounter; @@ -43,7 +42,6 @@ import org.openflow.protocol.OFType; public class FlowReconcileMgrTest extends FloodlightTestCase { - protected MockFloodlightProvider mockFloodlightProvider; protected FlowReconcileManager flowReconcileMgr; protected MockThreadPoolService threadPool; protected ICounterStoreService counterStore; diff --git a/src/test/java/net/floodlightcontroller/flowcache/PortDownReconciliationTest.java b/src/test/java/net/floodlightcontroller/flowcache/PortDownReconciliationTest.java index ee4ee0a7e0ee0ebd7db11d0ce3515b02ef22f86f..8407ee3605e1ac650903c87a9c9e012adf29a027 100644 --- a/src/test/java/net/floodlightcontroller/flowcache/PortDownReconciliationTest.java +++ b/src/test/java/net/floodlightcontroller/flowcache/PortDownReconciliationTest.java @@ -56,7 +56,6 @@ import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; -import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockThreadPoolService; import net.floodlightcontroller.devicemanager.IEntityClassifierService; import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier; @@ -83,7 +82,6 @@ import net.floodlightcontroller.topology.ITopologyService; public class PortDownReconciliationTest extends FloodlightTestCase { - protected MockFloodlightProvider mockFloodlightProvider; protected FloodlightModuleContext fmc; protected ILinkDiscoveryService lds; protected FlowReconcileManager flowReconcileMgr; diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java index 2d491919a846caf9f47b1aaf9c216292f6f36110..78fb6112d0d08a927090f6d35cf924a328db8d69 100644 --- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java +++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java @@ -29,7 +29,6 @@ import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; -import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockThreadPoolService; import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier; import net.floodlightcontroller.devicemanager.test.MockDeviceManager; @@ -72,7 +71,6 @@ import org.openflow.protocol.action.OFActionOutput; import org.openflow.util.HexString; public class ForwardingTest extends FloodlightTestCase { - protected MockFloodlightProvider mockFloodlightProvider; protected FloodlightContext cntx; protected MockDeviceManager deviceManager; protected IRoutingService routingEngine; diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java index b4a215cd066a7772fc669683dba47aedeb8e7bca..22dfd855ffb94d0cbb0587b769ecb47eaefde552 100644 --- a/src/test/java/net/floodlightcontroller/hub/HubTest.java +++ b/src/test/java/net/floodlightcontroller/hub/HubTest.java @@ -126,7 +126,7 @@ public class HubTest extends FloodlightTestCase { assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); - assert(m.equals(po)); + assertEquals(po, m); } @Test @@ -162,6 +162,6 @@ public class HubTest extends FloodlightTestCase { assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); - assert(m.equals(po)); + assertEquals(po, m); } } diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java index 487e36ee774b9063e20c3bea107d9e33d6327ad6..b9397b603b2585af1adcb9bcf51ef9db38958f14 100644 --- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java +++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java @@ -33,7 +33,11 @@ import org.junit.Before; import org.junit.Test; import org.openflow.protocol.OFMessage; +import org.openflow.protocol.OFPacketIn; import org.openflow.protocol.OFPhysicalPort; +import org.openflow.protocol.OFType; +import org.openflow.protocol.OFPacketIn.OFPacketInReason; +import org.openflow.protocol.factory.BasicFactory; import org.openflow.util.HexString; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +45,7 @@ import org.slf4j.LoggerFactory; import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IFloodlightProviderService.Role; +import net.floodlightcontroller.core.IListener.Command; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.test.MockThreadPoolService; @@ -48,6 +53,11 @@ import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener; import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService; import net.floodlightcontroller.linkdiscovery.LinkInfo; import net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager; +import net.floodlightcontroller.packet.Data; +import net.floodlightcontroller.packet.Ethernet; +import net.floodlightcontroller.packet.IPacket; +import net.floodlightcontroller.packet.IPv4; +import net.floodlightcontroller.packet.UDP; import net.floodlightcontroller.restserver.IRestApiService; import net.floodlightcontroller.restserver.RestApiServer; import net.floodlightcontroller.routing.IRoutingService; @@ -495,4 +505,95 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase { List<OFMessage> msgList = wc.getValues(); assertTrue(msgList.size() == ports.size() * 2); } + + private OFPacketIn createPacketIn(String srcMAC, String dstMAC, + String srcIp, String dstIp, short vlan) { + IPacket testPacket = new Ethernet() + .setDestinationMACAddress(dstMAC) + .setSourceMACAddress(srcMAC) + .setVlanID(vlan) + .setEtherType(Ethernet.TYPE_IPv4) + .setPayload( + new IPv4() + .setTtl((byte) 128) + .setSourceAddress(srcIp) + .setDestinationAddress(dstIp) + .setPayload(new UDP() + .setSourcePort((short) 5000) + .setDestinationPort((short) 5001) + .setPayload(new Data(new byte[] {0x01})))); + byte[] testPacketSerialized = testPacket.serialize(); + OFPacketIn pi; + // build out input packet + pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN)) + .setBufferId(-1) + .setInPort((short) 1) + .setPacketData(testPacketSerialized) + .setReason(OFPacketInReason.NO_MATCH) + .setTotalLength((short) testPacketSerialized.length); + return pi; + } + + @Test + public void testIgnoreSrcMAC() throws Exception { + String mac1 = "00:11:22:33:44:55"; + String mac2 = "00:44:33:22:11:00"; + String mac3 = "00:44:33:22:11:02"; + String srcIp = "192.168.1.1"; + String dstIp = "192.168.1.2"; + short vlan = 42; + + IOFSwitch mockSwitch = createMock(IOFSwitch.class); + expect(mockSwitch.getId()).andReturn(1L).anyTimes(); + replay(mockSwitch); + + /* TEST1: See basic packet flow */ + OFPacketIn pi; + pi = createPacketIn(mac1, mac2, srcIp, dstIp, vlan); + FloodlightContext cntx = new FloodlightContext(); + Ethernet eth = new Ethernet(); + eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length); + IFloodlightProviderService.bcStore.put(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD, + eth); + Command ret; + ret = ldm.receive(mockSwitch, pi, cntx); + assertEquals(Command.CONTINUE, ret); + + /* TEST2: Add mac1 to the ignore MAC list and see that the packet is + * dropped + */ + ldm.addMACToIgnoreList(HexString.toLong(mac1), 0); + ret = ldm.receive(mockSwitch, pi, cntx); + assertEquals(Command.STOP, ret); + /* Verify that if we send a packet with another MAC it still works */ + pi = createPacketIn(mac2, mac3, srcIp, dstIp, vlan); + cntx = new FloodlightContext(); + eth = new Ethernet(); + eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length); + IFloodlightProviderService.bcStore.put(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD, + eth); + ret = ldm.receive(mockSwitch, pi, cntx); + assertEquals(Command.CONTINUE, ret); + + /* TEST3: Add a MAC range and see if that is ignored */ + ldm.addMACToIgnoreList(HexString.toLong(mac2), 8); + ret = ldm.receive(mockSwitch, pi, cntx); + assertEquals(Command.STOP, ret); + /* Send a packet with source MAC as mac3 and see that that is ignored + * as well. + */ + pi = createPacketIn(mac3, mac1, srcIp, dstIp, vlan); + cntx = new FloodlightContext(); + eth = new Ethernet(); + eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length); + IFloodlightProviderService.bcStore.put(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD, + eth); + ret = ldm.receive(mockSwitch, pi, cntx); + assertEquals(Command.STOP, ret); + + verify(mockSwitch); + } } \ No newline at end of file diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java index 95b21f77e29d9f1f0c24dd6efa70941be7cb012b..7311ac1aadd75dd13a19637f97a7edf7ff0e552b 100644 --- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java +++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java @@ -52,7 +52,6 @@ import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; -import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockThreadPoolService; import net.floodlightcontroller.counter.CounterStore; import net.floodlightcontroller.counter.ICounterStoreService; @@ -85,7 +84,6 @@ public class LoadBalancerTest extends FloodlightTestCase { protected FloodlightContext cntx; protected FloodlightModuleContext fmc; - protected MockFloodlightProvider mockFloodlightProvider; protected MockDeviceManager deviceManager; protected MockThreadPoolService tps; protected FlowReconcileManager frm; diff --git a/src/test/java/net/floodlightcontroller/packet/PacketTest.java b/src/test/java/net/floodlightcontroller/packet/PacketTest.java index 3e8aed8ba21b167aa8da5be5bc8a5853ff85cbed..b975166fafc0576306e0fdde88d740adb31d13de 100644 --- a/src/test/java/net/floodlightcontroller/packet/PacketTest.java +++ b/src/test/java/net/floodlightcontroller/packet/PacketTest.java @@ -17,6 +17,9 @@ package net.floodlightcontroller.packet; import static org.junit.Assert.*; + +import java.util.Arrays; + import org.junit.Before; import org.junit.Test; @@ -121,8 +124,8 @@ public class PacketTest { ARP arp = (ARP)pkt; ARP newArp = (ARP)newPkt; newArp.setSenderProtocolAddress(new byte[] {1,2,3,4}); - assertEquals(false, newArp.getSenderProtocolAddress() - .equals(arp.getSenderProtocolAddress())); + assertEquals(false, Arrays.equals(newArp.getSenderProtocolAddress(), + arp.getSenderProtocolAddress())); assertEquals(false, newPkt.equals(pkt)); } diff --git a/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java b/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java index 29cc15b706bbffef92e0388324596dbe8cb9b394..578cd9d1ae7fac34c1337529da23f9d5764e0301 100644 --- a/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java +++ b/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java @@ -173,7 +173,7 @@ public abstract class StorageTest extends FloodlightTestCase { else if (expectedObject instanceof Double) assertEquals(((Double)expectedObject).doubleValue(), resultSet.getDouble(columnName), 0.00001); else if (expectedObject instanceof byte[]) - assertEquals((byte[])expectedObject, resultSet.getByteArray(columnName)); + assertTrue(Arrays.equals((byte[])expectedObject, resultSet.getByteArray(columnName))); else if (expectedObject instanceof String) assertEquals((String)expectedObject, resultSet.getString(columnName)); else diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java index 822add1b653757eca52466e26a3fe97d97c18e5a..135e622054192c08f9c3bb1e07acb9a31ba92420 100644 --- a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java +++ b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java @@ -126,9 +126,9 @@ public class TopologyManagerTest extends FloodlightTestCase { public void testHARoleChange() throws Exception { testBasic2(); getMockFloodlightProvider().dispatchRoleChanged(null, Role.SLAVE); - assert(tm.switchPorts.isEmpty()); - assert(tm.switchPortLinks.isEmpty()); - assert(tm.portBroadcastDomainLinks.isEmpty()); - assert(tm.tunnelPorts.isEmpty()); + assertTrue(tm.switchPorts.isEmpty()); + assertTrue(tm.switchPortLinks.isEmpty()); + assertTrue(tm.portBroadcastDomainLinks.isEmpty()); + assertTrue(tm.tunnelPorts.isEmpty()); } }